Scala中可以通过map映射操作来解决问题,将集合中的每一个元素通过指定功能(函数)映射(转换)成为一个新的结果集合,这里其实就是所谓的将函数作为参数传递给另一个函数,这就是函数式编程的特

以HashSet为例说明

1
2
3
4
5
def map[B](file:///F:/(A)%E2%86%92B): HashSet[B]
// 这个就是map映射函数集合类型都有
// [B]是泛型
// map是一个高阶函数(就是可以接收一个函数作为参数的函数),可以接收函数f:(A)=>B后面详解(先简单介绍下.)
// HashSet[B]就是返回的新的集合

集合操作(将 list(3,5,7) 集合中的内容都 * 2返回新的集合),我们使用高阶函数来进行处理

下面代码 list.map高阶函数解析(我们平时处理的都是单个参数,但是传入的List集合时如何进行处理的呢)

list.map[Int](elementProduct)说明 做了什么

  1. 将list集合的这个元素依次遍历出来
  2. 将各个元素 传递给elementProduct 函数 ⇒ 新Int
  3. 将得到的新Int包装到新的集合中,并返回
1
2
3
4
5
6
7
8
9
10
11
12
13
14
object exercise01 {
def main(args: Array[String]): Unit = {
// 将 list(3,5,7) 集合中的内容都 * 2返回新的集合

val list = List[Int](3, 5, 7)
val value = list.map[Int](elementProduct)
println("处理过后的集合" + value)
println("处理过后集合的类型" + value(0).isInstanceOf[String])
}

def elementProduct(num: Int): Int = {
num * 2
}
}

模拟Map映射的底层机制

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
object exercise01 {
def main(args: Array[String]): Unit = {
// 将 list(3,5,7) 集合中的内容都 * 2返回新的集合

// val list = List[Int](3, 5, 7)
// val value = list.map[Int](elementProduct)
// println("处理过后的集合" + value)
val list = MyList()
val value = list.map(elementProduct)
println(value)
}

def elementProduct(num: Int): Int = {
println("调用的次数")
num * 2
}
}

class MyList {
val myList = List[Int](3, 5, 7, 100)
var newMyList = List[Int]()

def map(f: Int => Int): List[Int] = {
for (item <- this.myList) {
newMyList = newMyList :+ f(item)
}
newMyList
}
}

object MyList {
def apply(): MyList = new MyList()
}

FlatMap映射

flat即压扁、压平、扁平化映射,效果就是将集合中的每个元素的子素映射到某个函数并返回新的集合

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
package com.sky.scala.exercise15.map.dataProcess

object exercise02 {
def main(args: Array[String]): Unit = {
val list = List("alice", "andelu", "jaCK")
val list2 = StringToUpperCase(list).stringToUpperCase2(stringToUpperCase)
println(list2)
}
def stringToUpperCase(str: String): String = {
str.toUpperCase()
}
}
class StringToUpperCase(inStrList: List[String]) {
val strList = inStrList
var strList2 = List[String]()

def stringToUpperCase2(f: String => String): List[String] = {
for (item <- strList) {
strList2 = strList2 :+ f(item)
}
strList2
}
}
object StringToUpperCase {
def apply(inStrList: List[String]): StringToUpperCase = new StringToUpperCase(inStrList)
}

集合元素的过滤(将符合要求的数据,筛选放置到新的集合中)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
package com.sky.scala.exercise15.map.dataProcess

//数据过滤
object FilterExercise03 {
def main(args: Array[String]): Unit = {
val list = List("Alice", "andelu", "AjaCK")
val list2 = strFilter(list).strFilter2(s)
println(list2)
}

def s(str: String): String = {
str
}

}

class strFilter(inStrList: List[String]) {
val strList = inStrList
var strList2 = List[String]()

def strFilter2(f: String => String): List[String] = {
for (item <- strList) {
if (item.indexOf("A") == 0) {
strList2 = strList2 :+ f(item)
}
}
strList2
}
}

object strFilter {
def apply(inStrList: List[String]): strFilter = new strFilter(inStrList)
}

// 方法二

def main(args: Array[String]): Unit = {
val list = List("Alice", "andelu", "AjaCK")
// val list2 = strFilter(list).strFilter2(s)
// println(list2)

val value = list.filter(isAStart)
println(value)
}

def isAStart(str: String): Boolean = {
str.startsWith("A")
}

化简

需求,我们如何计算一个list中多个 int类型的和

化简:将二元函数引用于集合中的函数

  1. 我们可以使用reduceLeft(f) 函数来进行解决
  2. reduceLeft() 函数的运行规则为从左边开始执行,将得到的结果返回给第一个参数,然后继续和下一个元素运行,再将得到的结果返回给第一个参数,如此运行
1
2
3
4
5
6
7
8
9
10
11
12
13
package com.sky.scala.exercise15.map.dataProcess

object exercise04 {
def main(args: Array[String]): Unit = {
val list = List[Int](1, 3, 4, 5, 6)
val i = list.reduceLeft(sum)
println(i)
}

def sum(n1: Int, n2: Int): Int = {
return n1 + n2
}
}

示例代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
package com.sky.scala.exercise15.map.dataProcess

object exercise04 {
def main(args: Array[String]): Unit = {
val list = List[Int](1, 3, 4, 5, 6)
// 相加
val i = list.reduceLeft(sum)
println(i)
val i_2 = list.reduceRight(sum)
println(i_2)
// 相减
val i2 = list.reduceRight(subtract)
println(i2)
val i2_2 = list.reduceLeft(subtract)
println(i2_2)

// 求最大值或者最小值

// 求最大值
println(list.reduce(subtract))
// 求最小值
println(list.reduce(max))
}

// 相加
def sum(n1: Int, n2: Int): Int = {
return n1 + n2
}

// 相减
def subtract(n1: Int, n2: Int): Int = {
n1 - n2
}

// 求最大值或者最小值

// 求最大值
def mini(n1: Int, n2: Int): Int = {
if (n1 > n2) {
n1
} else {
n2
}
}

// 求最小值
def max(n1: Int, n2: Int): Int = {
if (n1 > n2) {
n2
} else {
n1
}
}
}

折叠

foldLeft和foldRight缩写方法分别是: /:和:\

统计分析练习

1.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
package com.sky.scala.exercise15.map.dataProcess

object exercise04 {
def main(args: Array[String]): Unit = {
val list = List[Int](1, 3, 4, 5, 6)
// 相加
val i = list.reduceLeft(sum)
println(i)
val i_2 = list.reduceRight(sum)
println(i_2)
// 相减
val i2 = list.reduceRight(subtract)
println(i2)
val i2_2 = list.reduceLeft(subtract)
println(i2_2)

// 求最大值或者最小值

// 求最大值
println(list.reduce(subtract))
// 求最小值
println(list.reduce(max))
}

// 相加
def sum(n1: Int, n2: Int): Int = {
return n1 + n2
}

// 相减
def subtract(n1: Int, n2: Int): Int = {
n1 - n2
}

// 求最大值或者最小值

// 求最大值
def mini(n1: Int, n2: Int): Int = {
if (n1 > n2) {
n1
} else {
n2
}
}

// 求最小值
def max(n1: Int, n2: Int): Int = {
if (n1 > n2) {
n2
} else {
n1
}
}
}

2.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
package com.sky.scala.exercise15.map.dataProcess

import scala.collection.mutable

object calculateCharCount {
def main(args: Array[String]): Unit = {
val content = "AAAAAAAAAAAAAAAAABBBBBBBBBBBBBBBBBBCCCCCCCCCCCCCCCCCDDDDDDD"
val value = content.foldLeft(Map[Char, Int]())(calculating)
println(value)
val value2 = content.foldLeft(mutable.Map[Char, Int]())(calculating2)
println(value2)
}

def calculating(map: Map[Char, Int], c: Char): Map[Char, Int] = {
// 使用的不可变map,每次返回的都是不同的map,浪费资源
map + (c -> (map.getOrElse(c, 0) + 1))
}

def calculating2(map: mutable.Map[Char, Int], c: Char): mutable.Map[Char, Int] = {
map += (c -> (map.getOrElse(c, 0) + 1))
}
}

3.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
package com.sky.scala.exercise15.map.dataProcess

import scala.collection.mutable.ArrayBuffer

object FoldLeftExercise {
def main(args: Array[String]): Unit = {
val content = "AAAAAAAAAAAAAAAAABBBBBBBBBBBBBBBBBBCCCCCCCCCCCCCCCCCDDDDDDD"
var arrayBuffer = new ArrayBuffer[Char]()
val functionToTuple = content.foldLeft(arrayBuffer)(foldLefts)
println(functionToTuple)
}

def foldLefts(abf: ArrayBuffer[Char], c: Char): ArrayBuffer[Char] = {
abf.append(c)
}
}