首页 > 编程语言 >一门多范式的编程语言Scala学习的第二天-函数的使用

一门多范式的编程语言Scala学习的第二天-函数的使用

时间:2024-08-21 16:38:08浏览次数:11  
标签:范式 编程语言 val Scala Int 函数 List println String

2.12 scala中的函数式编程

* scala中的函数式编程
*
* 面向对象编程:将对象当作参数一样传来传去
* 1、对象可以当作方法参数传递
* 2、对象也可以当作方法的返回值返回
* 当看到类,抽象类,接口的时候,今后无论是参数类型还是返回值类型,都需要提供对应的实现类对象
*
* 面向函数式编程:将函数当作参数一样传来传去
* 1、函数A当作函数B的参数进行传递
* 2、函数A当作函数B的返回值返回
*
* 在scala中,将函数也当作一个对象,对象就有类型
* 函数在scala也有类型的说法
* 参数类型=>返回值类型
object Demo10fun {
  def main(args: Array[String]): Unit = {

    //是一个参数是字符串类型,返回值是整数类型的函数
    def fun1(a1:String):Int={
      a1.toInt
    }

    val res1: Int = fun1("1000")
    println(res1)

    //定义变量的方式,定义一个函数
    //将函数当作对象,赋值给类型是函数类型的变量,将来可以直接通过变量调用函数
    val fun2:String=>Int=fun1
    val res2: Int = fun2("2000")
    println(res2)

    /**
     * 函数A作为函数B的参数定义
     *
     * 本质上是将函数A的处理逻辑主体传给了函数B,在函数B中使用这个处理逻辑
     */
    //f:String=>Int  相当于函数A
    //fun3相当于函数B
    def fun3(f:String=>Int):Int={
      val a1:Int=f("100")
      a1+100
    }

    def show1(a1:String):Int=a1.toInt

    val res4: Int = fun3(show1)
    println(res4)

    def show2(a1: String): Int = a1.toInt+100

    val res5: Int = fun3(show2)
    println(res5)

    //定义一个函数fun1, 函数的参数列表中,既有正常的类型参数,也有函数类型的参数
    def fun4(s:String,f:String=>Int): Int = {
      val b1:Int=f(s)
      b1+111
    }

    def show3(a1: String): Int = a1.toInt + 100

    val res6: Int = fun4("1000",show3)
    println(res6)


    //使用lambda表达式改写函数作为参数传递的调用形式
    fun4("100",(s:String)=>s.toInt)
    fun4("100",(s:String)=>s.toInt+100)

    //在Scala中数据类型可以自动推断
    val res7: Int = fun4("1000", s => s.toInt + 100)
    println(res7)
    ////如果当作参数的函数的参数只在函数主体使用了一次,那么可以使用_代替
    fun4("100",_.toInt+100)
  }

}

1、函数当作参数传递的应用

object Demo11fun {
  def main(args: Array[String]): Unit = {
    val arr1: Array[Int] = Array(11, 22, 33, 44, 55)

    def fun1(i:Int): Unit = {
      println(i*2)

    }
    //def foreach[U](f: A => U): Unit
    //foreach函数需要一个参数和数组元素一样类型的类型,返回值是Unit的函数
    //foreach函数的主要作用是将调用该方法的序列中的元素,依次取出传递给后面的函数进行处理
    arr1.foreach(fun1)

    // scala自带的一个函数
    // def println(x: Any) = Console.println(x)
    // Any可以接收任意的数据类型元素
    arr1.foreach(println)
  }
}

2、函数当作返回值返回

object Demo12fun {
  def main(args: Array[String]): Unit = {
    /**
     * fun1: 参数是String类型,返回值是一个函数(参数是String类型,返回值是Int)
     */
    //定义返回值是函数的函数方式1:
    def fun1(s1:String):String=>Int={
      def fun2(s2:String):Int={
        s2.toInt+s1.toInt
    }
      fun2
    }
    //调用函数的返回值是函数的方式1
    val res1: String => Int = fun1("100")
    val res2: Int = res1("100")
    println(res2)

    //定义方式2(是方式1的简化写法):
    def fun2(s1:String)(s2:String):Int={
      s1.toInt+s2.toInt
    }

    val res3: Int = fun2("1")("100")
    println(res3)
    //一般这么用方式二
    val resfun: String => Int = fun2("10")
    val res4: Int = resfun("11")
    println(res4)
    val res5: Int = resfun("22")
    println(res5)
    val res6: Int = resfun("33")
    println(res6)

    //另一种写法
    def fun3(s1:String,s2:String):Int={
      s1.toInt+s2.toInt
    }

    val res7: Int = fun3("100", "10")
    println(res7)

    /**
     * 使用下划线进行占位,那么Scala会自动根据参数类型和返回值类型,创建一个新的相符合的函数
     * 偏函数
     */
    val funn3: String => Int = fun3("100", _)
    val res8: Int = funn3("100")
    println(res8)
    val res9: Int = funn3("1000")
    println(res9)

  }
}

2.13数组

//数组:在内存中一块连续固定大小的空间,有索引可以检索数据,查询快,但是增删速度较慢
//创建一个数组
val arr1: Array[Int] = Array(11, 22, 33, 44, 55)
println(arr1(0))
println(arr1(1))
println(arr1(2))
println(arr1(3))
println(arr1(4))

3、Scala中的”_"的用法总结

在Scala中的大部分情况下,表示所有或者默认值或者占位符的时候,都使用下划线

1、导包时

  • 多引用的方法,和Java中的*类似,相当于该类下面的任意子类
import scala.collection.mutable._

2、在访问元组

  • 和值在一起使用则表示第几个元素
val/var 元组名 = (元素1, 元素2, 元素3....)
//获取第一个元素
元组名._1
//获取第二个元素
元组名._2

3、根据定义的变量的类型的初始值进行的占位符

var gender:String = _

4、使用下划线来简化函数的定义

  • 当函数的参数在函数体中只出现一次,而且函数体没有嵌套调用时,可以使用下划线来简化函数的定义

def main(args: Array[String]): Unit = {
    val a = List(1,2,3,4,5)
//    a.foreach(x=>println(x))
    a.foreach(println(_))
}

5、用于元素匹配,匹配每一个元素

List(1,2,3,4,5,6,7,8,9).filter(_ % 2 == 0)

6、用于替换函数中的参数

  • 函数参数在函数中只出现一次,则可以使用下划线代替

    /**
     * 偏函数
     */
    val f1: String => Int = function1("1", _)
    val res1: Int = f1("1000")
    val res2: Int = f1("2000")
    val res3: Int = f1("3000")
    println(s"res1:$res1,res2:$res2,res3:$res3")

7、用于模式匹配中的默认匹配项

case表达式中的无需使用到的匹配到的变量,可以用下划线代替

变量 match {
  case "常量1" => 表达式1
  case "常量2" => 表达式2
  case "常量3" => 表达式3
  case _ => 表达式4 // 默认匹配项
}


str match {
   case "hadoop" => println("大数据分布式存储和计算框架")
   case "zookeeper" => println("大数据分布式协调服务框架")
   case "spark" => println("大数据分布式内存计算框架")
   case _ => println("未匹配")
  }

在case校验时,变量没有被使用,也可以用下划线替代

  • 下面是Scala中处理异常的时间的使用

      /**
       * 也可以手动的抛出异常
       */
      val sc = new Scanner(System.in)
      print("输入除数:")
      val cs: Int = sc.nextInt()
      if(cs!=0){
        println(10/cs)
      }else{
        throw new ArithmeticException("您输入的除数是0")
      }
    }catch{
      //类似于sql语句中case when
      case e:ArithmeticException=>
//        println("除0异常")
          e.printStackTrace()
      case e:ArrayIndexOutOfBoundsException=>
        println("数组越界异常")
      case _ =>
        println("出现异常")
    }finally {
      //今后finally中的处理大部分情况下都与释放资源有关
      println("这是finally代码块")
    }

8、在定义变量时

  • 在定义变量时,使用下划线占位,就表示将来会赋予该变量默认值
  /**
   * 定义成员变量
   */
  val _name: String = name
  val _age: Int = age
  var _gender: String = _ // 这个下划线,就表示将来会赋予默认值

4、Scala中的集合

List: 元素有序,且可以发生重复,长度是固定的

Set:元素无序,且唯一,长度固定的

Map:元素是以键值对的形式,键是唯一的

Tuple:元组,长度是固定的,每一个元素的数据类型可以是不一样的

4.1ArrayList

object Demo13ArrayList {
  def main(args: Array[String]): Unit = {
    val list1: util.ArrayList[Int] = new util.ArrayList[Int]

    list1.add(11)
    list1.add(123)
    list1.add(22)
    list1.add(31)
    list1.add(17)

    println(list1)

    var i=0
    while (i<list1.size()){
      val res1: Int = list1.get(i)
      println(res1)
      i+=1
    }
  }
}

4.2 List

  • List中的基础用法,和Java中的集合用法一致
//创建一个scala中的List集合
//创建了一个空集合
//    val list1: List[Nothing] = List()
val list2: List[Int] = List(34, 11, 22, 11, 33, 44, 55, 22, 75, 987, 1, 12, 34, 66, 77)

println(list2)
//获取List集合的长度
println(list2.size)
println(list2.length)
println("=" * 50)
//可以直接通过索引下标获取元素
println(list2(0))
println(list2(1))
println(list2(2))
println("=" * 50)
//scala推荐获取第一个元素的方式是调用head函数
println(list2.head)
println(list2.last)
//根据指定的分隔符拼接元素
println(list2.mkString("|"))
println("=" * 50)
val resList1: List[Int] = list2.reverse //返回一个新的集合
println(s"list2:$list2")
println(s"resList1:$resList1")
println("=" * 50)
//对集合中元素进行去重
val resList2: List[Int] = list2.distinct //返回一个新的集合
println(s"list2:$list2")
println(s"resList2:$resList2")
println("=" * 50)
val resList3: List[Int] = list2.tail // 除去第一个,其余的元素返回一个新的集合
println(s"list2:$list2")
println(s"resList3:$resList3")
println("=" * 50)
val resList4: List[Int] = list2.take(5) // 从左向右取元素,取若干个
println(s"list2:$list2")
println(s"resList4:$resList4")
println("=" * 50)
val resList5: List[Int] = list2.takeRight(5) //取右边的几个,组成新的集合
println(s"list2:$list2")
println(s"resList5:$resList5")
println("=" * 50)
//从第一个判断取数据,直到不符合条件停止
val resList10: List[Int] = list2.takeWhile((e: Int) => e % 2 == 0)
println(s"list2:$list2")
println(s"resList10:$resList10")
println("***********************************" * 50)
val res1: Int = list2.sum // 元素必须是数值
println(s"集合中的元素和为:$res1")
println("=" * 50)
val res2: Int = list2.max
println(s"集合中的元素最大值为:$res2")
println("=" * 50)
//集合的遍历
for (e <- list2) {
    println(e)
}
println("=" * 50)
  • Scala中的List高阶函数用法
/**
     * 高阶函数:
     * foreach: 将集合中的元素依次取出传入到后面的函数中
     * 注意:没有返回值的,要么就输出,要么就其他方式处理掉了
     */
//def foreach[U](f: A => U)
//    list2.foreach((e: Int) => println(e))
//    list2.foreach(println)
//需求1:使用foreach求出集合中偶数的和
var ouSum = 0
var jiSum = 0
list2.foreach((e: Int) => {
    if (e % 2 == 0) {
        ouSum += e
    } else {
        jiSum += e
    }
})
println(s"集合中偶数之和为:$ouSum")
println(s"集合中奇数之和为:$jiSum")
println("=" * 50)
/**
     * 高阶函数:
     * map: 依次处理每一个元素,得到一个新的结果,返回到一个新的集合中
     */
val list3: List[Int] = List(1, 2, 3, 4, 5, 6, 7, 8, 9)
//需求2:将集合中的每一个元素*2
val resList6: List[Int] = list3.map((e: Int) => e * 2)
println(s"list3:$list3")
println(s"resList6:$resList6")

/**
     * 高阶函数:
     * filter: 保留符合条件的元素
     */
println("=" * 50)
val list4: List[Int] = List(4, 7, 9, 10, 12, 11, 14, 9, 7)
val resList7: List[Int] = list4.filter((e: Int) => e % 2 == 0)
println(s"list4:$list4")
println(s"resList7:$resList7")

/**
     * 高阶函数:
     * sortBy: 排序
     * sortWith: 两个数之间的关系排序
     */
println("=" * 50)
val resList8: List[Int] = list4.sortBy((e: Int) => -e)
println(s"list4:$list4")
println(s"resList8:$resList8")
val resList9: List[Int] = list4.sortWith((x: Int, y: Int) => x > y)
println(s"list4:$list4")
println(s"resList9:$resList9")

/**
     * 高阶函数:
     * flatMap: 扁平化
     */
println("=" * 50)
val list5: List[String] = List("hello|world|java", "hello|hadoop|flink", "scala|spark|hadoop")
val resTmp1: List[String] = list5.flatMap((e: String) => e.split("\\|"))
resTmp1.foreach(println)

/**
     * 高阶函数:
     * groupBy: 分组
     */
val list6: List[String] = List("hello", "world", "java", "hadoop", "flink", "java", "hadoop", "flink", "flink", "java", "hadoop", "flink", "java", "hadoop", "hello", "world", "java", "hadoop", "hello", "world", "java", "hadoop")
val map: Map[String, List[String]] = list6.groupBy((e: String) => e)
for (e <- map) {
    println(e)
}

/**
     * 基本函数
     *
     * 高阶函数:
     *  foreach: 依次取出元素,进行后面函数逻辑,没有返回值
     *  map: 依次取出元素,进行后面函数逻辑,有返回值,返回新的集合
     *  filter: 所有数据中取出符合条件的元素
     *  sortBy/sortWith: 排序
     *  flatMap: 扁平化
     *  groupBy: 分组,结果是一个map集合
     */

4.3Set

set集合:
	scala中的Set集合也是不可变的,除了排序相关的函数以外,List集合有的高阶函数,Set集合也有
val set1: Set[Int] = Set(1, 4, 3, 6, 5)
val set2: Set[Int] = Set(3, 6, 5, 7, 8)
println(s"$set1")
println(s"$set2")

//    val res1: Set[Int] = set1.&(set2)
//求交集
val res2: Set[Int] = set1 & set2
println(s"$res2")
//求并集
val res3: Set[Int] = set1.|(set2)
println(s"$res3")
//求差集
val res4: Set[Int] = set1.&~(set2)
println(s"$res4")

/**
     * list集合和set集合可以相互转换
     */
val list1: List[Int] = List(11, 22, 33, 44, 55, 11, 22, 44, 88, 33, 44, 99, 11, 22, 55)
val set3: Set[Int] = list1.toSet
println(s"$set3")
val list2: List[Int] = set3.toList.sortBy((e: Int) => e)
println(s"$list2")

标签:范式,编程语言,val,Scala,Int,函数,List,println,String
From: https://www.cnblogs.com/shmil/p/18371944

相关文章

  • 一门多范式的编程语言Scala学习的第一天-简介
    Scala1、Scala简介1.1Scala的介绍scala是一门多范式的编程语言Scala是把函数式编程思想和面向对象编程思想结合的一种编程语言大数据计算引擎spark是由Scala编写的1.2Scala的特性1.2.1多范式1.2.1.1面向对象特性Scala是一种高度表达性的编程语言,它结合了面向对象编程......
  • Swift操作符重载:编程语言的瑞士军刀
    标题:Swift操作符重载:编程语言的瑞士军刀在Swift编程语言中,操作符重载是一种强大的特性,它允许开发者为自定义类型提供已有操作符的新实现。这不仅提升了代码的可读性,还增加了Swift语言的表达力。本文将深入探讨Swift中操作符重load的机制,并展示如何通过代码示例来实现它。......
  • Paper Reading: SAFE: Scalable Automatic Feature Engineering Framework for Indust
    目录研究动机文章贡献本文方法整体框架特征生成特征组合关系排序特征组合生成特征特征选择去除无信息特征去除冗余特征复杂度分析实验结果数据集和实验设置对比实验特征重要性比较运行时间特征稳定性不同迭代次数的性能大规模数据集实验优点和创新点PaperReading是从个人角度进......
  • 编程语言的核心:类型系统(Type System)
    编程语言的核心是其类型系统,只要掌握了其类型系统,对整门编程语言的掌握便事半功倍。为啥这么说呢?首先,在设计一门编程语言的时候,会针对该编程语言所作用的问题域(ProblemDomain)和解决域(SolutionDomain),进行设计。由此,对于问题域和解决域的抽象,就行形成该编程语言的抽......
  • 数据库三范式
    数据库的范式是一套减少数据冗余和改善数据完整性的规则。第一范式(1NF)要求每列的原子性,即属性值不能再分解示例:一个包含学生信息的表,其中包含以下字段:学生ID(StudentID)学生姓名(StudentName)选修课程(Courses)如果Courses字段是这样的:学生A:数学,英语学生B:物理,化学,生......
  • 晋商银行携手云和恩墨MogDB重塑数据安全与业务创新新范式
    在信息技术飞速发展的今天,金融机构面临如何在保障数据安全与业务连续性的基础上推进技术创新与应用的重大挑战。晋商银行积极响应国家战略,通过实际行动给出了自己的答案……谋定而后动,晋商银行携手MogDB创新启程经过对国内数据库厂商及其产品进行严格筛选和审慎评估,晋商银行最终选......
  • 仓颉编程语言:整数类型(基础数据类型)
    整数类型分为有符号(signed)整数类型和无符号(unsigned)整数类型。有符号整数类型包括Int8、Int16、Int32、Int64和IntNative,分别用于表示编码长度为8-bit、16-bit、32-bit、64-bit和平台相关大小的有符号整数值的类型。无符号整数类型包括UInt8、UInt16、UInt32、UInt64......
  • 仓颉编程语言:布尔类型(基础数据类型)
    布尔类型使用Bool表示,用来表示逻辑中的真和假。布尔类型字面量布尔类型只有两个字面量:true和false。下面的例子展示了布尔字面量的使用:leta:Bool=trueletb:Bool=false布尔类型支持的操作布尔类型支持的操作符包括:逻辑操作符(逻辑非!,逻辑与&&,逻辑或||)、部......
  • 仓颉编程语言:字符串类型(基础数据类型)
    字符串类型使用String表示,用于表达文本数据,由一串Unicode字符组合而成。字符串字面量字符串字面量分为三类:单行字符串字面量,多行字符串字面量,多行原始字符串字面量。单行字符串字面量的内容定义在一对单引号或一对双引号之内,引号中的内容可以是任意数量的(除了非转义的双......
  • groovy 编程语言简单介绍
    值提取系列值提取系列字符串值提取工具-01-概览字符串值提取工具-02-java调用js字符串值提取工具-03-java调用groovy字符串值提取工具-04-java调用java?Janino编译工具字符串值提取工具-05-java调用shell字符串值提取工具-06-java调用python字符串值提取工具-......