Scala编程基础——集合&高阶函数

集合

Scala中集合分为可变集合不可变集合

可变集合:可以修改、添加、移除一个集合的元素。

不可变集合:安全的并发访问。

不可变集合,相比之下,永远不会改变。不过,你仍然可以模拟添加,移除或更新操作。但是这些操作将在每一种情况下都返回一个新的集合,同时使原来的集合不发生改变。

// 不可变集合scala.collection.immutable (Scala默认采用不可变集合)
// 可变集合scala.collection.mutable
数组
定长数组Array

创建数组

//创建数组,长度为10,int数据类型
var arr1 = new Array[Int](10)
//数组创建存在默认值,与泛型有关
println(arr1)//不可变数组无法直接打印数组中的值,打印数组名得到地址

另一种创建数组方式,不使用new关键字【触发apply】

var arr2 = Array(1,2,3)
//指定数据类型的泛型,即指定数组中存储的数据类型
val arr3 = Array[String](xs = "HDFS","Zookeeper")
变长数组arrayBuffer
 /*定义可变数组Scala中默认使用是不可变的集合操作,如果需要使用可变集合需要导入可变集合包 scala.collection.mutable.ArrayBuffer*///定义一个可变Int类型数组val nums = ArrayBuffer[Int]();//向集合中添加数据【集合的末尾】
//    nums(0) = 1;
//    println(nums)//上面方式对于变量数组赋值是不允许的nums += 1println(nums)//在末尾添加多个元素nums += (2,3,4,5)//使用++=在尾端添加任何集合nums ++= Array(6,7,8)println(nums)//这些运算操作符也有相应的 -=,--=可以作为数组的删减//使用append方法向数组中追加一个或多个数据nums.append(1);nums.append(2,3)println(nums)//有数据的前提下,在指定下标位置之前插入数据(一个或多个数据)nums.insert(2,20);nums.insert(2,30,30)println(nums)//移除(删除)最后2个元素nums.trimEnd(2)println(nums)//移除最开始的一个或多个元素nums.trimStart(1)println(nums)//删除数组中数据-->删除指定数据(下标位置)nums.remove(2)println(nums)//删除数组中数据-->删除指定数组(下标位置)开始删除多少个nums.remove(2,2)println(nums)/*可以使用Scala中增强for循环进行数组的遍历for(变量 <- 数组名){操作变量就相当于获取到数中对应数据}*/for(ele <- nums){println(ele)}//使用下标的方式遍历(要求数中要有数据)for(i <- 0 until nums.length){println(nums(i))}
定长数组与变长数组的转换
定长数组名.toBuffer  //转为变长
变长数组名.toArray    //转为定长
//将定长数组转换为变长数组
println(arr1.toBuffer)
//将变长数组转换为定长数组
println(arr2.toArray)
遍历数组

Scala与Java拥有同一概念–>下标,通过下标值,可以获取数组中的元素

val ints:Array[Int] = new Array[Int](10)//for循环遍历数组for(i <- ints){println(i)}for(i<- 0 until ints.length){println(ints(i))}
数组元素处理
 val ints:Array[Int] = new Array[Int](10)//修改数组中的值ints(0) = 10000;println(ints.toBuffer)//扩容ints(10)=111println(ints.toBuffer)//使用可变集合必须导入包import scala.collection.mutable.ArrayBufferval buffer = ArrayBuffer[Int]()//可以使用下标 推荐使用 += 运算符buffer += 1println(buffer)//添加多个数据buffer += (2,3,4,5,6)println(buffer)//++= 在集合的尾部添加任何集合存储的数据到当前集合buffer ++= Array(7,8,9)println(buffer)//使用append进行数据添加buffer.append(1)//insert在指定下标位置进行数据插入buffer.insert(2,101,102)//下标为2println(buffer)//删除数组中的数据【删除最后几个数据-->几个根据参数决定】buffer.trimEnd(2)//删除最后两个元素buffer.trimStart(2)//删除最开始两个元素buffer.remove(2)//删除下标为2的元素buffer.remove(2,3)//从第一个参数位置开始删除后续多个数据//遍历for(i<- buffer){println(i)}
数组的常用方法

数组中提供了比较常见处理数据的操作

val arr =Array(1,2,3,4,5,6,7,8,9)
println(arr1.sum)//求数组中数据之和
println(arr1.max)//求数组中最大的元素
println(arr1.min)//求数组中最小的元素
println(arr1.sorted.toBuffer)//数组排序(默认升序),返回一个新的数组/*可以根据自定义规则规则进行排序操作sortWith_>_ 升序   _<_ 降序*/println(arr1.sortWith(_<_).toBuffer);
val arr =Array(1,2,3,4,5,6,7,8,9)for(i <- arr){print(i*2)}for(i <- arr){if(i%2 == 0){println(i*2)}}val res = for(ele <- arr)yield ele*2val res2=for(ele <- arr if(ele%2==0))yield ele*2//利用封装好的方法进行处理/*记忆:map方法:遍历 集合中的每一个元素,并在参数的位置 提供一个可以处理集合元素函数操作*/val ints:Array[Int] = arr.map(x => x * 2)//filter 遍历集合中的每一个元素,并在参数位置提供一个判断的逻辑 对数据进行操作val ints1:Array[Int] = arr.filter(x => x % 2 == 0).map(y => y * 2)//至简原则 //_ 属于简化写法 等价于变相定义了 x 这个变量 _ 获取集合中每一个元素arr.map(_*2)arr.filter(_%2==0).map(_*2)val arr1=Array(1,23,4,5,4,7)arr1.sortWith((x,y)=>x>y)

元组(Tuple)

表示固定元素的组合,元素可以装着多个不同类型的值,是不同类型的值的聚集。

特点:

  • 最多支持22个元素组合,分别对应类型Tuple1~Tuple22
  • 元组可以容纳不同类型的元素
  • 元组不可变

特别地:二元组(v1,v2)可以表示Map中的一个元素(key,value),Map是K/V对偶的集合,对偶是元组的最简单形式。

创建访问元组

创建元组:使用小括号()将多个元素括起来,元素之间用逗号分隔,元素的类型和个数不超过22

访问组元:使用_1_2_3等形式访问组元,注意下标从1开始。

第二种方式定义的元组也可以通过abc 去访问组元。

//定义元组
/*
t 就是元组名称 代表整个元组
()数据*/
val t = ("hadoop","yarn","spark","zookeeper")
println(t)
//获取元组中某一个值,元组中数据是存在的,整个位置从1开始 递增+1
//表示形式_数字 获取对应位置
println(t._1)
//abc对应元组数据,访问变量名获取数据
val t2,(a,b,c)=("hadoop",1,123)
println(c)
//标准元组创建方式
val t3 =new Tuple4("hadoop","yarn","spark","zookeeper")
//元组中提供的方法productElement这个方法的参数是元组数据位置【参考下标形态】
//开始值从0开始
println(t3.productElement(0))
//元组的遍历 元组本身不是集合的成员 不能直接在for中使用
//需要将元组转换为元组迭代器对象才可以进行操作
for(i<- t.productIterator){println(i)//获取元组中每一个元素
}
//必须记住的地方 foreach 遍历集合中每一个元素用于打印操作
t.productIterator.foreach(x=> println(x))
t.productIterator.foreach(println(_))
元组访问
 //Scala中已经定义好的元祖对象,根据数字决定元祖中存储数据个数val tuple3 = new Tuple3(1,3.14,"true");/*注意访问元祖中数据可以使用【_数字】 的形式访问数字是从1开始 根据元祖中存数据个数递增+1*/println(tuple3._3)/*元祖中也提供一个方法productElement这个方法参数值是 元祖中存数据的下标,第一个数据下标是从0开始的*/println(tuple3.productElement(0))
元组遍历

因为元组本身不是集合成员,所以元组不能作为for生成器的表达式。但元组实现了productIterator()方法,该方法可以生成元组的迭代器Iterator(继承自TraversableOnce),迭代器提供了遍历集合的方法。这也是通常我们将Tuple视为集合的原因。

方式一:

 //第一种遍历元祖的方式for(ele <- tuple3.productIterator){println(ele)}

方式二:

// foreach 遍历集合中每一个元素用于打印操作/*第二种遍历元祖的方式利用productIterator中foreach方法进行数据打印foreach属于高阶函数*/tuple3.productIterator.foreach(i => println(i))//简化版本 使用 【_】 替代参数的定义tuple3.productIterator.foreach(println(_))}
zip拉链操作
 //拉链操作(将两个集合中的内容合并到一个集合)//ps:两个集合中元素个数相等时val num1 = Seq(1,2,3,4)val num2 = Seq(5,6,7,8)val num3 = num1 zip num2//将形成新集合,存储数据形式类似于Map集合中kv键值对//集合中元素个数不一致时,以最短集合长度作为合并依据,多余的数据会被删除val num4 = Seq(1,2,3)val num5 = Seq(1,2,3,4)val num6 = num4 zip num5println(num6)//zipAll函数与zip函数是相似的,也是进行数据的拉链操作。如果有较少数据拉链操作会进行默认值填充操作val num7 = List(1,2,3,4)val name = List("hadoop","Scala","Spark")//此时使用zip 让num7 zip name 因为name 长度短,会以它为基准,多余数据会被删除//为了减少数据丢失,可以以zipAll的形式来操作数据//num7中存储的是整数,数据类型是Int,所以提供的整数默认值是 0val defaultNum = 0//name中存储的是字符串,数据类型是String,提供字符串的默认值“_”val defaultStr = "_"val list = num7.zipAll(name,defaultNum,defaultStr)println(list)//zipWithIndex函数将元素与其对应所在位置索引值形成对偶(pair)元组val name2 = List("hadoop","Scala","Spark","linux")val list2 = name2.zipWithIndexprintln(list2)//zip操作参数版本,如果需要从指定参数索引值开始指定拉链操作数据val list3 = name2.zip(Stream from 1)println(list3)//unzip将已经执行zip操作之后的数据分成原有数据val num8 = Seq(1,2,3,4)val num9 = Seq(5,6,7,8)val num1_1 = num8 zip num9println(num1_1)//拆分zip操作结果集val unzip = num1_1.unzipval value = unzip._1

映射(Map)

 //scala中提供的集合默认都是不可以变的val score =Map("kg"->50,"bb"->18,"bz"->60)val score1 =Map(("kg",50),("kb",18),("uz",67))//提供可变集合存储数据形式是一样的val score2 =scala.collection.mutable.Map(("kg",50),("db",18),("fz",67))//获取集合中的数据/*方式一:map集合名字+key名字 就可以得到value值--》map集合名字(key名)如果key值存在 则返回数据,不存在则抛出异常*/val age = score("kg")print(age)/*val age2 = score("kfg")print(age2)*//*方式二:可以利用map集合中提供的 contains 方法判断是否存在key 如果存在则获取 不存在则返回默认值*/val age2 = if(score.contains("bb")) score("bb") else 0/*方式三:使用map集合中的get方法获取对应的key的valueget方法的返回值是option类型【含有some(有值)和none(没值)】如果存在some值需要再次使用get方法进行获取才可以获取真正操作数据,否则无法操作 None如果执行get方法会出现异常*/val age3 = score.get("bg")//val value = age3.getval i = age3.getOrElse(0)//最终版本:就是直接利用map集合中提供getOrElse 进行操作// 如果key存在则获取value值 如果key不存在 则获取方法默认值val age4 = score2.getOrElse("kg",0)

Map集合的基础操作

 //创建一个可变Map集合import scala.collection.mutable.Mapval score = Map("kg" -> 50, "bb" -> 18, "bz" -> 60)//更新某个key的valuescore.update("kg", 100)//向map集合中添加数据score("sz") = 120//利用 += 一次性向map集合中添加一个或多个数据score += ("ds" -> 1000)score += ("ds" -> 1000, "fs" -> 89)//添加另外一个集合中数据到map中 ++=val score2 = Map("kg" -> 50, "db" -> 18, "gz" -> 60)score ++= score2//'-=' 删除kv键值对(一个或多个)'--=' 集合提供key的形式删除kv键值对(多个)score -= "db"score -= ("kg", "gz")score --= List("kg", "gz", "db")println(score)
遍历map
     //遍历Map集合操作//1.获取所有的key值,返回值是一个迭代器对象就可以获取数据val keys: Iterable[String] = score.keysfor (key <- keys) {println(key)}//2.获取所有value值,返回值是一个迭代器遍历迭代器对象就可以获取数据val values: Iterable[Int] = score.valuesfor (value <- values) {println(value)}//3.直接遍历map集合获取到数据是完整kv键值对(二元组)for (ele <- score) {println(ele)//4、遍历的时候单独的获取k和vfor ((k, v) <- score) {println("key值:" + k + "value值:" + v)}//5、foreach的遍历方式score.foreach((k) => println(k._1 + k._2)) //使用foreach遍历map之后将map集合中数据看做了((key , value) , ( key, value))

列表(List)

元素类型必须相同 有序 列表是不可变的,内容及长度都不可变。

 //构建list集合//创建一个空集合val empty = Nil//代表空集合val empty2 = List()//存储数据list集合val names  = List("kaige","bb","bz")//List集合中存储其他集合的对象val moreList = List(List(1,2,3),List(4,5,6))//如果访问集合中数据--》 存在下标的 可以访问下标的形式来访问集合中的数据print(names(0))//List集合的遍历for(ele <- names){println(ele)}//foreach高阶函数的处理names.foreach(name=>println(name))names.foreach(println(_))names.foreach(println)//操作集合中数据使用map方法操作集合中数据并返回一个处理之后的新的集合val ints = names.map(str => str.length)val ints1 = names.map(_.length)//向list集合中添加数据val list = List(1,2,3)//中缀符操作val list2 = 0 :: list//向集合中第一个位置添加 0 数据val list3 = list.:: (0)val list4 = 0 +: list//还可以list.+:(0)//追加集合的末尾val ints2 = list :+ 4//追加其他集合数据val list1 = List(4,5,6)val ints3 = list ++ list1//++:  .::://List常用方法和基本操作val list5 = List(1,233,3)val list6 = List(4,33,5)//获取列表中第一个元素val head:Int = list5.head//返回除第一个元素之外剩余List集合中元素————》返回的是一个集合val tail = list5.tail//判断集合是否为空 true-空 false-不空val empty1 = list5.isEmpty//拼接两个集合并生成一个新集合val ints4=List.concat(list5,list6)//将集合中数据进行反转(配合sorted进行降序操作)val reverse = list5.reverse//获取集合中长度val length = list5.length//获取集合中最后一个元素val last = list5.last//比较重要的方法 将来可以用作TopN//获取列表中前N个元素val ints5 = list5.take(2)//***//丢弃列表的前N个元素获取剩余的元素val ints6 = list5.drop(2)//list集合支持拉链操作val tuples = list5 zip list6
List的高阶方法***
 //***(开发中常用)存在一定的通用性val list1 =List(1,2,3,4)/*map函数:可以将集合中的每一个元素获取出来并提供逻辑进行计算返回一个处理之后的结果集//将list集合中数据都乘以2返回计算之后的结果*///根据map函数中参数提供 函数类型进行函数的定义val num = (x:Int) => x*2//将定义好的函数传递到map函数的参数中提供使用以完成数据操作val ints : List[Int] = list1.map(num)//Scala“简洁”进行开发利用ScaLa中提供高级函数中概念【匿名函数】的方式针对map方法参数进行函数赋值val ints1: List[Int] = list1.map((x: Int) => x * 2)//"简洁" 进行匿名函数实现 根据Scala自动推断已经得到 参数数据类型 所以无需定义直接提供参数即可val ints2: List[Int] = list1.map(x => x * 2)//“简洁”Scala在提供函数是现实如果遇到相同的类型的复数定义 可以省略参数名使用【_】进行简化操作val ints3: List[Int] = list1.map(_ * 2)/*flatMap方法:扁平化处理,将集合中存储集合数据扁平化处理成一个List集合Ps: flatMap这个方法时有两个方法简化而来flatten和 mapflatten这个方法就是扁平化处理可以将结合中数据处理完成为一个新的集合*/val list2:List[List[Int]] = List(List(1,2,3,4),List(5,6,7,8));/*将存储在List2集合中数据进行获取组合成一个新的集合,集合中存储不在是集合对象,而是具体数据值这个过程称之为扁平化处理”---》List(List(1,2,3,4),List(5,6,7,8))转换为---》List(1,2,3,4,5,6,7,8)*/val flatten = list2.flattenprintln(flatten)val line = List("hello tom hello jerry" , "hello xiaobai hello");/*需要将List集合中存储字符串进行处理获取字符串中每一个单词形成一个List集合--》List( "helLo" , "tom" , "helLo" , "jerry" , . ..)*///数据处理第一步:将字符串拆分为单词val stringses: List[Array[String]] = line.map(_.split(" "))//当前的数据形成--》list((Array("helLo" , "tom" ,...),Array( "helLo" , "jerry" , . ..)//第二步:将存储在集合中数据进行扁平化处理val flatten1: List[String] = stringses.flatten//Scala为了方便我们操作就将flatten和map进行了结合 flatmap 遍历数据同时进行扁平化处理// 上面操作直接简化为val line2 = List("hello tom hello jerry" , "hello xiaobai hello" )val strings: List[String] = line2.flatMap(_.split(" "))/*foreach方法:提供一个函数获取集合中每一个数据并执行打印操作foreach与map方法的区别在于foreach没有返回值(只适用于打印)map有返回值(适合处理集合中数据并返回结果)*/list1.foreach(println)/*filter方法:提供一个函数获取集合中每一个数据 并在函数中提供数据的判断操作(提供booLean表达式判断),如果返回值为true,则该元素返回一个存储数据结果的List集合*///获取list1中所有的偶数val ints4 = list1.filter(x => x % 2 == 0)//简化:list1.filter(_%2==0)/*partition方法:提供一个函数获取集合中每一个数据 参与到参数中提供boolean表达式进行判断,返回true值放置到一组 返回false值的放置到一组*///需求:将List1中数据按照奇偶数据进行分组val tuple: (List[Int],List[Int]) = list1.partition(_ % 2 == 0)/*find方法:提供一个函数获取集合中每一个元素 参与到参数中提供boolean表达式进行判断获取到满足条件的【第一个元素】(第一个结果为true值直接返回,后续不在判断)如果判断结果为false则返回NonePS: find方法的返回值是Option类型 所以找到数据以some(数据)返回,如果找不到以None返回*/val maybeInt = list1.find(_ % 2 == 0)//保证安全val i = maybeInt.getOrElse(0)print(i)/*takewhile方法:提供一个函数获取集合中每一个元素 参与到参数中提供boolean表达式进行判断一旦有一个元素不满足判断条件(即结果为false),后续的元素就不在判断了直接返回存储结果的集合PS:takewhile也可以过滤数据但是和filter是有很大区别*/val list3 = List(1,23,3,5,6,7)val ints5 = list3.takeWhile(_ < 3)println(ints5)/*droplwhile方法:提供一个函数获取集合中每一个元素 参与到参数中提供boolean表达式进行判断一旦有一个元素不满足判断条件(即结果为false),后续元素就不在判断之前判断结果为true的数据将被删除,为false这个数据开始剩余数据保留返回为集合*/val list4 = List(1,23,3,5,6,7)val ints6 = list4.dropWhile(_ < 3)println(ints6)/*span方法:提供一个函数获取集合中每一个元素 参与到参数中提供boolean表达式进行判断判断条件为true的放置到一组,判断条件为false放置到一组与partition是不同,span等同于是在做(c takewhile p, c dropwhile p)但是它效率更高*/val tuple1 = list1.span(_ < 3)/*exists方法:提供一个函数获取集合中每一个元素 参与到参数中提供boolean表达式进行判断判断的是否满足条件返回是true满足条件﹐false是不满足条件判断集合中是否存在执行的元素值ps:这个方法已经被contains替换了,参数不在需要提供boolean类型表达式直接提供判断是否存在数据即可*/val bool = list1.contains(1)/*forall方法提供一个函数获取集合中每一个元素 参与到参数中提供booLean表达式进行判断这个方法判断集合中所有的数据是否满足条件,只有所有数据都满足条件才会返回true 只要任何一个不满足直接返回false*/val list5 = List(1,2,334,6,6,4,7)list5.forall(_ > 0)/*sortwith方法:这个一个排序方法可以提供排序数据方式(函数)进行升序不是降序排序 类似于Javacomparator与Comparable接口的实现来执行排序方式第一个参数>第二个参数 降序第一个参数<第二个参数 升序返回排序好之后的集合*/val list6 = List(1,3,5,7,3,3,3,2,62,6,9)val ints7 = list6.sortWith(_ < _)
可变列表ListBuffer

ListBuffer与List的区别在于:修改ListBuffer改变的是本身。

//使用ListBuffer需要导入可变包import scala.collection.mutable.ListBuffer//创建一个可变ListBuffer并初始化3个数据val list1 = ListBuffer[Int](1,2,3);//创建一个可变ListBuffer空的集合val list2 = new ListBuffer[Int]//向list2中追加数据  ps:没有生成新的集合list2 += 4;list1.append(4)//append方法时一个可变参数可以追加一个或多个//list1和list2两个集合,合并乘一个新ListBuffer集合 ps:生成了一个新的集合val list3 = list2 ++ list1;//将元素追加到list1的后面生成一个新的集合val listBuffer = list1 :+ 5//将可变与不可变集合之间进行转换操作val buffer = ListBuffer(1,2,3,4)val list = List(5,6,7,8);//将可变集合转变为不可变集合val list4 = buffer.toList//将不可变集转变为可变集合val buffer1 = list.toBuffer

Set

set中的元素不可重复,无序

 //set集合的基础操作val set1 = Set(5,2,7,6,8,7,3,1,9,2,7)val set2 = Set(5,2,7,6,8,7,3,1,9,2,7)//判断集合中是否存在指定元素val bool = set1.contains(5)//set集合提供了 交集 差集 并集的计算//交集val ints = set1 & set2val ints1 = set1.intersect(set2)//差集val ints2 = set1 &~ set2val ints3 = set1.diff(set2)//并集val ints4 = set1.union(set2)/*size 获取集合中存储元素个数splitAt:将集合拆分成两个容器,第一个容器由前n(方法参数)个元素组成第二个容器由剩余元素组成take 返回前N(方法参数)个元素toXXX方法可以转换其他集合存储数据*/

集合的重要函数

高阶函数
 //聚合函数//sum//reduce,对集合中的数据进行计算操作val list = List(1,2,4,5,6,7,89,90)println(list.sum)//reduce求和计算/*执行流程:对两个变量获取集合中第一个和第二个元素执行x+y 得出结果触发计算逻辑x不在获取集合中的元素,而是得到上一次x+y的结果值y继续获取集合中数据 参与x+y计算 直到y无法获取集合中数据时,整个reduce计算结束*/val sum = list.reduce((x: Int, y: Int) => x + y)//val sum = list.reduce(_ + _)println(sum)//reduce方法有两个变种:reduceleft和reduceright 在没有开起并行化的前提下,他们的计算逻辑方式都是一样//如果开启并行化reduceleft reduceright 会强制要求计算操作 要求是从左往右 从右往左//fold函数进行求和计算/*fold 是典型的柯里化,需要两个参数第一个参数:第一个小括号 提供默认值 会参与就算第二个参数:第二个小括号 提供计算逻辑执行流程:x获取到0这个值,y获取到集合中第一个元素执行x+y的逻辑 得到第一次计算结果 x获取x+y y依旧获取集合中每一个元素参与计算*/list.fold(0)((x:Int,y:Int)=>x+y)//fold方法有两个变种:foldleft和foldright 在没有开起并行化的前提下,他们的计算逻辑方式都是一样//如果开启并行化foldleft和foldright 会强制要求计算操作 要求是从左往右 从右往左
 //将每个元素*2def method(x:Int):Int = {x*2}def main(args: Array[String]): Unit = {val list =List(1,2,3,4,5,6)//将集合中的每一个元素*2返回最终结果 将方法转换为函数//手动 方法名 _ 方法传递到一个函数的参数位进行赋值,自动将方法转换为函数val list1 = list.map(method)println(list1)}
 //将函数作为方法的返回值存在,通过调用方法的得到另外一个函数操作def main(args: Array[String]): Unit = {def urlBuilder(ssl:Boolean,domainName:String):(String,String)=>String = {val schema = if(ssl)"https//" else "http://"(endPoint:String,query:String)=>s"$schema$domainName/$endPoint?$query"}val domainName ="www.qfedu.com"val function = urlBuilder(ssl = true, domainName)val url = function("user","id=1")println(url)/*java角度理解class Person{}class Demo{public static Person showPerson(){return new Person()}psvmPerson p = showPerson()sout(p)p.getAge()}*/}
 /*高阶函数:允许函数提供参数类型是【函数类型】 允许函数的返回值类型是【函数类型】*/def func(x:Int):(Int)=>Int={(y:Int)=>x+y}val func_1:(Int)=>Int = func(1)val sum = func_1(2)//简化操作提供的概念def func2(x:Int)(y:Int):Int ={x+y}//触发柯里化方法时-->第二个参数(2)等价与触发第一个函数执行 (y:Int)=>x+yval sum2 = func2(1)(2)
柯里化

Curring函数,指的是,将原来接收两个参数的一个函数,转换为两个函数,第一个函数接收原先的第一个参数,然后返回接收原先第二个参数的第二个函数。

在函数调用的过程中,就变为了两个函数连续调用的形式

即柯里化(Currying)是指将原先接受多个参数的函数多个一个参数的多参数列表的过程。

 /*使用柯里化目的在于让传递匿名函数作为参数的语法更加简洁柯里化可以更加简便的进行 函数作为返回值操作如果将一个方法的返回值 定义为一个函数调用方法时是获取获取到这个函数,只有再次代用这个函数才可以得到具体的结果需要调用两次才可以,但是利用柯里化可以简化这个调用直接得到结果值*///简化函数作为返回值时的调用执行过程def func(x: Int): (Int) => Int = {(y: Int) => x + y;}//第一次调用这个方法时,得到结果不是一个具体数据,而是一个函数即(y:Int) => x+yval func_1: Int => Int = func(1)//第二次func_1才可以得到最终的计算结果val sum = func_1(1);println(sum)//利用柯里化简化这个操作,直接得到计算结果def func2(x:Int)(y:Int)={x+y;}val sum2 = func2(1)(1);//第二个(1)等价在触发 (y: Int) => x + y;//使用柯里化让传递匿名函数作为参数的语法更为简洁//需求:编写一个泛型方法,用来完成两个值类型的计算(具体的计算封装到函数中)//没有使用柯里化方式定义方法def curringMethod1[A <: AnyVal](x:A,y:A,f:(A,A)=>A)={f(x,y)}//使用了柯里化定义方法def curringMethod2[A <: AnyVal](x:A,y:A)(f:(A,A)=>A)={f(x,y)}//没有提供柯里化方法在传递匿名函数是不可以使用 简化操作必须完整定义出函数curringMethod1(1,2,(x:Int,y:Int)=>x+y);/*不能提供简化操作 因为方法中使用泛型,需要提供数据类型才可以进行泛型赋值操作如果使用简化的匿名函数进行推断是无法正确推断出数据类型*///curringMethod1(1,2,_+_);//使用了提供柯里化操作的方法就可以利用简化操作/*第一个(1,2)已经推断出了泛型是Int类型,然后在调用第二(_+_)这个函数操作此时根据第一个推断出结果是Int类型,所以简化操作也推断出是Int类型*/curringMethod2(1,2)(_+_);

Scala编程基础——集合高阶函数相关推荐

  1. 【Scala之旅】高阶函数

    本节翻译自 Type Inference Higher-order Functions Nested Methods Multiple Parameter Lists (Currying) 综述:Sc ...

  2. Kotlin 编程核心基石—高阶函数

    前言 1. 高阶函数有多重要? 高阶函数,在 Kotlin 里有着举足轻重的地位.它是 Kotlin 函数式编程的基石,它是各种框架的关键元素,比如:协程,Jetpack Compose,Gradle ...

  3. Python学习札记(二十) 函数式编程1 介绍 高阶函数介绍

    参考: 函数式编程 高阶函数 Note A.函数式编程(Functional Programming)介绍 1.函数是Python内建支持的一种封装,我们通过一层一层的函数调用把复杂任务分解成简单的任 ...

  4. Kotlin基础 9 - 高阶函数

    高阶函数的基本概念 1.传入或者返回函数的函数 2.函数引用 ::println 3.带有Receiver的引用 pdfPrinter:println fun main(args: Array< ...

  5. Python基础-09 高阶函数

    高阶函数 一个函数作为另一个的返回值 def demo():print('我是test函数')return 'hello'def demo():print('我是demo函数')return test ...

  6. Scala高阶函数详解

    概述 高阶函数主要有两种:一种是将一个函数当做另外一个函数的参数(即函数参数):另外一种是返回值是函数的函数. 用函数作为形参或返回值的函数,称为高阶函数. (1)使用函数作为参数 //函数参数,即传 ...

  7. Scala入门到精通——第十三节 高阶函数

    本节主要内容 高阶函数简介 Scala中的常用高阶函数 SAM转换 函数柯里化 部分应用函数 1. 高阶函数简介 高阶函数主要有两种:一种是将一个函数当做另外一个函数的参数(即函数参数):另外一种是返 ...

  8. kotlin修炼指南8—集合中的高阶函数

    点击上方蓝字关注我,知识会给你力量 Kotlin对集合操作类新增了很多快捷的高阶函数操作,各种操作符让很多开发者傻傻分不清,特别是看一些Kotlin的源码或者是协程的源码,各种眼花缭乱的操作符,让代码 ...

  9. 【Kotlin】Kotlin 语言集合中的高阶函数详解 ( 数据类 data class | maxBy | minBy | filter | map | any | count | find )

    文章目录 I . List 集合高阶函数引入 II . Kotlin 数据类 ( data class ) III . Java 代码 与 Kotlin 代码实现对比 ( 查询年龄最大的 ) IV . ...

最新文章

  1. 重点 (七) : 开发技巧/方法
  2. Mysql memory表引擎
  3. 20145321 《Java程序设计》第7周学习总结
  4. [转载] 杜拉拉升职记——15 1001个笑话
  5. 【SPOJ】Power Modulo Inverted(拓展BSGS)
  6. 数据分析与挖掘建模实战002:数据获取
  7. Java只用一个循环语句输出九九乘法表
  8. python functools
  9. gtk_widget_modify_bg的用法
  10. 整合Servlet到Spring容器
  11. flowable实现多实例节点的自由跳转
  12. 【网络覆盖优化】基于matlab的网络覆盖遗传优化问题仿真
  13. 基于JAVA的KTV交易_Java写的KTV管理系统(Swing界面,含源码)
  14. python中idle环境的退出命令的快捷键_IDLE环境的退出命令是( )。_学小易找答案...
  15. java世界杯hashmap,Java练习题_Map 利用Map,完成下面的功能: 从命令行读入一个字符串,表示一个年份,输出该年的世界杯冠军是哪支球队。...
  16. 北大MBA夫妇不满现有教育系统 携女隐居终南山
  17. Python爬取链家租房信息
  18. C#在一个form中改变另一个form中控件的内容、C#做登录界面并且密码显示为*
  19. 给真的想【卷】的你们
  20. nodejs之pathinfo/pathname的使用

热门文章

  1. 【二〇二一·芒种】读书笔记
  2. Matlab/Simulink电力系统——同步发电机突然三相短路暂态过程
  3. 学习-Python字典之手机号归属运营商判断
  4. pymol 知道多少?pymol技巧汇总
  5. 0基础、其他行业转行,适合学Python吗?
  6. 七云mc服务器下载地址_我的世界1.7.10云晨之都
  7. 2021届 海康威视人力面试 嵌入式软件
  8. 拓扑学笔记:定义域的性质之紧性暂记(紧集“有界闭集”的性质)
  9. 微信小程序中配置云开发
  10. android虚线边框_Android通过代码实现虚线或者虚线框shape