Scala - 快速学习09 - 函数式编程:一些操作
1- 集合类(collection)
![](/assets/blank.gif)
可变集合(Mutable)
![](/assets/blank.gif)
不可变集合(Immutable)
- 对不可变集合的操作(修改,添加,删除某个集合元素),都是返回一个新的集合,原来的集合不会发生改变。
- 由于“永远不会被改变”的特性,可以说不可变集合是线程安全的。
- Scala在默认情况下采用的是不可变集合。在使用上,优先使用不可变集合。
- 不可变集合适用于大多数情况。
![](/assets/blank.gif)
2- 列表(List)
List[T]
val a = List(1, 2, 3, 4) //> a : List[Int] = List(1, 2, 3, 4)val b = 0 :: a //> b : List[Int] = List(0, 1, 2, 3, 4)val c = "x" :: "y" :: "z" :: Nil //> c : List[String] = List(x, y, z)val r0 = "z" :: Nil //> r0 : List[String] = List(z)val r1 = "y" :: r0 //> r1 : List[String] = List(y, z)val r2 = "x" :: r1 //> r2 : List[String] = List(x, y, z)val d = a ::: c //> d : List[Any] = List(1, 2, 3, 4, x, y, z)d.head //> res0: Any = 1d.tail //> res1: List[Any] = List(2, 3, 4, x, y, z)d.isEmpty //> res2: Boolean = falseNil.isEmpty //> res3: Boolean = truedef test(tlist: List[Int]): String = {if (tlist.isEmpty) ""else tlist.head.toString + " " + test(tlist.tail)} //> test: (tlist: List[Int])Stringtest(a) //> res4: String = "1 2 3 4 "
val test = List(1, 2, 3, 4, 5) //> test : List[Int] = List(1, 2, 3, 4, 5)test.filter(x => x % 2 == 1) //> res0: List[Int] = List(1, 3, 5)"Double in 2018!".toList //> res1: List[Char] = List(D, o, u, b, l, e, , i, n, , 2, 0, 1, 8, !)"Double in 2018!".toList.filter(x => Character.isDigit(x))//> res2: List[Char] = List(2, 0, 1, 8)"Double in 2018!".toList.takeWhile(x => x != 'i')//> res3: List[Char] = List(D, o, u, b, l, e, )
列表的遍历
val list = List(1, 2, 3) //> list : List[Int] = List(1, 2, 3)for (elem <- list) println(elem) //> 1//| 2//| 3list.foreach(elem => print(elem)) //> 123list.foreach(print) //> 123
3- 映射(Map)
键值对的集合
val test = Map(1 -> "Anliven", 9 -> "Angel") //> test : scala.collection.immutable.Map[Int,String] = Map(1 -> Anliven, 9 -> //| Angel)test(1) //> res0: String = Anliventest(9) //> res1: String = Angeltest.contains(1) //> res2: Boolean = truetest.contains(2) //> res3: Boolean = falsetest.keys //> res4: Iterable[Int] = Set(1, 9)test.values //> res5: Iterable[String] = MapLike.DefaultValuesIterable(Anliven, Angel)test + (8 -> "888") //> res6: scala.collection.immutable.Map[Int,String] = Map(1 -> Anliven, 9 -> An//| gel, 8 -> 888)test - 1 //> res7: scala.collection.immutable.Map[Int,String] = Map(9 -> Angel)test ++ List(2 -> "222", 3 -> "333") //> res8: scala.collection.immutable.Map[Int,String] = Map(1 -> Anliven, 9 -> An//| gel, 2 -> 222, 3 -> 333)test ++ List(2 -> "222", 3 -> "333") -- List(1, 9)//> res9: scala.collection.immutable.Map[Int,String] = Map(2 -> 222, 3 -> 333)
映射的遍历
val test3 = Map("1" -> "AAA", "2" -> "BBB", "3" -> "CCC")//> test3 : scala.collection.immutable.Map[String,String] = Map(1 -> AAA, 2 -> B//| BB, 3 -> CCC)for ((k, v) <- test3) printf("Key is : %s and Value is: %s\n", k, v)//> Key is : 1 and Value is: AAA//| Key is : 2 and Value is: BBB//| Key is : 3 and Value is: CCCfor (k <- test3.keys) println(k) //> 1//| 2//| 3for (v <- test3.values) println(v) //> AAA//| BBB//| CCCfor (x <- test3) println(x) //> (1,AAA)//| (2,BBB)//| (3,CCC)
4- Range与Stream
- range 整数序列
- stream 惰性求值列表
1 to 10 //> res0: scala.collection.immutable.Range.Inclusive = Range 1 to 101 to 10 by 2 //> res1: scala.collection.immutable.Range = inexact Range 1 to 10 by 2(1 to 10).toList //> res2: List[Int] = List(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)1 until 10 //> res3: scala.collection.immutable.Range = Range 1 until 101 until 10 by 2 //> res4: scala.collection.immutable.Range = inexact Range 1 until 10 by 21 #:: 2 #:: 3 #:: Stream.empty //> res5: scala.collection.immutable.Stream[Int] = Stream(1, ?)val stream = (1 to 123456789).toStream //> stream : scala.collection.immutable.Stream[Int] = Stream(1, ?)stream.head //> res6: Int = 1stream.tail //> res7: scala.collection.immutable.Stream[Int] = Stream(2, ?)
5- Tuple
(1, 2) //> res0: (Int, Int) = (1,2)1 -> 2 //> res1: (Int, Int) = (1,2)(1, "Alice", "Math", 95.5) //> res2: (Int, String, String, Double) = (1,Alice,Math,95.5)val test = (1, "Alice", "Math", 95.5) //> test : (Int, String, String, Double) = (1,Alice,Math,95.5)test._1 //> res3: Int = 1test._2 //> res4: String = Alicetest._3 //> res5: String = Mathtest._4 //> res6: Double = 95.5val test2 = List(1, 2, 3, 4, 5) //> test2 : List[Int] = List(1, 2, 3, 4, 5)def sumSq(in: List[Int]): (Int, Int, Int) =in.foldLeft((0, 0, 0))((t, v) => (t._1 + 1, t._2 + v, t._3 + v * v))//> sumSq: (in: List[Int])(Int, Int, Int)sumSq(test2) //> res7: (Int, Int, Int) = (5,15,55)
6- 集合操作
Map操作与flatMap操作
val test = List[String]("x", "y", "z") //> test : List[String] = List(x, y, z)test.map(x => x.toUpperCase) //> res0: List[String] = List(X, Y, Z)test.map(_.toUpperCase) //> res1: List[String] = List(X, Y, Z)val test2 = List(1, 2, 3, 4, 5) //> test2 : List[Int] = List(1, 2, 3, 4, 5)test2.filter(x => x % 2 == 1) //> res2: List[Int] = List(1, 3, 5)test2.filter(_ % 2 == 1) //> res3: List[Int] = List(1, 3, 5)test2.filter(_ % 2 == 1).map(_ + 10) //> res4: List[Int] = List(11, 13, 15)val test3 = List(test2, List(6, 7, 8, 9, 0)) //> test3 : List[List[Int]] = List(List(1, 2, 3, 4, 5), List(6, 7, 8, 9, 0))test3.map(x => x.filter(_ % 2 == 0)) //> res5: List[List[Int]] = List(List(2, 4), List(6, 8, 0))test3.map(_.filter(_ % 2 == 0)) //> res6: List[List[Int]] = List(List(2, 4), List(6, 8, 0))test3.flatMap(_.filter(_ % 2 == 0)) //> res7: List[Int] = List(2, 4, 6, 8, 0)
val myStr = List("AAA", "BBB", "CCC") //> myStr : List[String] = List(AAA, BBB, CCC)myStr flatMap (s => s.toList) //> res0: List[Char] = List(A, A, A, B, B, B, C, C, C)myStr.flatMap(s => s.toList) //> res1: List[Char] = List(A, A, A, B, B, B, C, C, C)
示例说明:对于列表myStr中的每个元素,都执行Lamda表达式定义的匿名函数“s => s.toList”,myStr中的每个元素都调用toList,生成一个字符集合List[Char],最后,flatMap把这些集合中的元素“拍扁”得到一个集合List。
filter操作
val testMap = Map(11 -> "ABC", 22 -> "BCD", 33 -> "CDE")//> testMap : scala.collection.immutable.Map[Int,String] = Map(11 -> ABC, 22 ->//| BCD, 33 -> CDE)val testFilter = testMap filter { kv => kv._2 contains "BC" }//> testFilter : scala.collection.immutable.Map[Int,String] = Map(11 -> ABC, 22//| -> BCD)testFilter foreach { kv => println(kv._1 + ":" + kv._2) }//> 11:ABC//| 22:BCDval testMap2 = Map(1 -> "ab", 2 -> "ac", 3 -> "bc")//> testMap2 : scala.collection.immutable.Map[Int,String] = Map(1 -> ab, 2 -> a//| c, 3 -> bc)val testFilter2 = testMap2 filter { kv => kv._2 startsWith "a" }//> testFilter2 : scala.collection.immutable.Map[Int,String] = Map(1 -> ab, 2 -//| > ac)testFilter2 foreach { kv => println(kv._1 + ":" + kv._2) }//> 1:ab//| 2:ac
reduce操作(归约)与fold操作(折叠)
- 使用reduce可以对集合中的元素进行归约,包含reduceLeft和reduceRight两种操作。
- reduceLeft从集合的头部开始操作,reduceRight从集合的尾部开始操作。
- reduce默认采用的是reduceLeft,其原型:reduceLeft(op: (T, T) => T)
val test = List(1, 2, 3, 4, 5) //> test : List[Int] = List(1, 2, 3, 4, 5)test.reduceLeft((x, y) => x + y) //> res0: Int = 15test.reduceLeft(_ + _) //> res1: Int = 15test.reduceRight(_ + _) //> res2: Int = 15test.reduceLeft(_ - _) //> res3: Int = -13test.reduceRight(_ - _) //> res4: Int = 3test.reduce(_ - _) //> res5: Int = -13
- reduceLeft(_ - _)表示从列表头部开始,对两两元素进行求和操作
- reduceRight(_ - _)表示从列表尾部开始,对两两元素进行求和操作
- 下划线是占位符表示当前获取的两个元素,两个下划线之间的是操作符,表示对两个元素进行的操作
- 直接使用reduce,等同于reduceLeft
- foldLeft(),第一个参数为累计值,从集合的头部开始操作。
- foldRight(),第二个参数为累计值,从集合的尾部开始操作。
val test = List(1, 2, 3, 4, 5) //> test : List[Int] = List(1, 2, 3, 4, 5)test.foldLeft(0)(_ + _) //> res0: Int = 15test.foldRight(0)(_ + _) //> res1: Int = 15test.foldLeft(0)(_ - _) //> res2: Int = -15test.foldRight(0)(_ - _) //> res3: Int = 3test.fold(0)(_ - _) //> res4: Int = -15test.fold(10)(_ * _) //> res5: Int = 1200
7- 实例WordCount
this is a test !
1,2,3
4,5,6,7,8,9
word2.txt
1,2,3
4,5,6,7,8,9
4,5,6,7,8,9
this is a test !
2 - 编辑并运行如下代码:
package testscala import java.io.File import scala.io.Sourceobject TestScala {def main(args: Array[String]): Unit = {val dirfile = new File("D:\\Anliven-Running\\Zen\\ScalaProjets\\temptest")val files = dirfile.listFiles //得到数组filesfor (file <- files) println(file) //遍历数组val aFilesList = files.toList //Array类的toList方法将连续存放的数组转换为递归存放的列表val wordsMap = scala.collection.mutable.Map[String, Int]() //定义一个Map变量,key是单词,value是单词数量aFilesList.foreach(file => Source.fromFile(file).getLines().foreach(line => line.split(" ").foreach(word => {if (wordsMap.contains(word)) {wordsMap(word) += 1} else {wordsMap += (word -> 1)}})))println(wordsMap) //打印内容for ((key, value) <- wordsMap) println(key + ": " + value) //遍历内容}}
代码说明:
- 如果是在Linux系统下运行,目录格式应为“/d/Anliven-Running/Zen/ScalaProjets/temptest”
- aFilesList.foreach()对列表aFilesList中的每个元素进行遍历操作,按照括号中定义的逻辑进行处理
- file => Source.fromFile(file).getLines().foreach()遍历获取列表aFilesList的元素值(文件路径名)并赋值给file,然后调用getLines()方法获取该文件的所有行,并执行foreach()方法遍历所有行
- line=>line.split(" ").foreach()对一行内容进行切分得到一个集合,然后调用foreach()方法圆括号中定义的处理逻辑遍历集合
- foreach()方法中处理逻辑的功能是,对于当前遍历到的某个单词,如果这个单词以前已经统计过,就把映射中以该单词为key的映射条目的value增加1。如果以前没有被统计过,则为这个单词新创建一个映射条目。
3 - 运行结果:
D:\Anliven-Running\Zen\ScalaProjets\temptest\word1.txt
D:\Anliven-Running\Zen\ScalaProjets\temptest\word2.txt
Map(is -> 2, 1,2,3 -> 2, a -> 2, 4,5,6,7,8,9 -> 3, ! -> 2, this -> 2, test -> 2)
is: 2
1,2,3: 2
a: 2
4,5,6,7,8,9: 3
!: 2
this: 2
test: 2
转载于:https://www.cnblogs.com/anliven/p/10041915.html
Scala - 快速学习09 - 函数式编程:一些操作相关推荐
- Scala - 快速学习08 - 函数式编程:高阶函数
函数式编程的崛起 函数式编程中的"值不可变性"避免了对公共的可变状态进行同步访问控制的复杂问题,能够较好满足分布式并行编程的需求,适应大数据时代的到来. 函数是第一等公民 可以作为 ...
- Scala深入学习之函数式编程
目录 一.函数式编程 二.高阶函数 三.闭包和柯里化 一.函数式编程 示例代码: package matchDemo.function/*** @author : 蔡政洁* @email :caizh ...
- 大数据学习,Scala快速学习的方法
大数据学习过程中,都会学习Scala,众所周知,Spark支持4门语言,分别为R.Python.Java与Scala,但真正的底层实现语言则是Scala.在我以往的实践分享中,除了Python,我还会 ...
- Java基础学习之函数式编程Comsumer接口(JDK8)
前言 从毕业到现在正好三年,高难度的项目做了不少,但是基础这个东西一段时间不接触就会忘得一干二净.话不多说,开始今天的学习! 1. Consumer接口 接触过"消费者",&quo ...
- 大数据技术之_16_Scala学习_09_函数式编程-高级
大数据技术之_16_Scala学习_09 第十三章 函数式编程-高级 13.1 偏函数(partial function) 13.1.1 提出一个需求,引出思考 13.1.2 解决方式-filter ...
- Supplier JAVA_Java基础学习之函数式编程Supplier接口(JDK8)
前言 今天带大家领略一下Supplier接口大道至简的魅力. 1.源码 @FunctionalInterface public interface Supplier { /*** Gets a res ...
- 2021年大数据常用语言Scala(二十七):函数式编程 聚合操作
目录 聚合操作 聚合 reduce 定义 案例 折叠 fold 定义 案例 聚合操作 聚合操作,可以将一个列表中的数据合并为一个.这种操作经常用来统计分析中 聚合 reduce reduce表示 ...
- 学习 Java8 函数式编程 (二)
和 Lambda 表达式 Say Hello 如果用一大段枯燥的文字去解释一个我们并不熟悉的概念,我觉得和看天书并无区别.我之所以选择学编程,就是因为没有什么是写段代码不能搞定的.那么废话少说,大家先 ...
- 廖雪峰python学习笔记——函数式编程
一个简单粗暴的内置函数: reduce()和map()的区别: map()是将函数依次作用到每个参数上,而reduce()相当于是迭代,而且每次都必须是两个参数. 用reduce()和map完成str ...
- Python快速学习07:文本文件的操作
作者:Jeff Lee 出处:http://www.cnblogs.com/Alandre/ 欢迎转载,也请保留这段声明.谢谢! 系列文章:[传送门] Python具有基本的文本文件读写功能.Pyth ...
最新文章
- win10环境下 运行debug程序
- CVPR2019 日程安排
- 以太坊创始人V 神:普通人看见现在,天才看见未来
- docker mysql开发环境_Docker 构建PHP+Apache+MySQL 开发环境
- 定域性和实在性之矛盾的世界
- Python:错误FileNotFoundError: [Errno 2] No such file or directory: 'objects/epsilon.pkl
- JAVA并发编程学习笔记之CAS操作
- win7系统去除图标箭头的方法
- div内容横排 html_css如何让文字横向滑入?
- 设计灵感|如何在海报设计中正确使用双色调风格?
- 感性精品高清PSD美手分层海报,一键替换,奢华品、首饰、护肤品推荐临摹应用
- AX 2009 父窗体参数记录传递
- xml property标签注入一个类变量_java开发两年,连Spring的依赖注入的方式都搞不清楚,你工作可能有点悬!...
- SDIO接口WiFi驱动浅析
- 酷狗音乐、QQ音乐、网易云音乐API
- linux 如何添加用户,Linux 怎么添加用户(adduser)
- 在线培训考核系统源码
- 小博的软件测试学习笔记(V1.0)
- 金大侠的亲属与剑桥大学最厉害的三个学院
- 电子计算机厂房火灾危险性,三氯化磷储罐的火灾危险性分类?