scala map,foreach,flatMap等方法对比

map方法

应用

map方法用于对集合中的元素进行处理,返回值还是一个集合,和原集合的类型相同

scala>  val x=Array(1,2,3)
x: Array[Int] = Array(1, 2, 3)

scala> x.map(_*2)
res24: Array[Int] = Array(2, 4, 6)

scala> val y=List(1,2,3)
y: List[Int] = List(1, 2, 3)

scala> y.map(_*2)
res26: List[Int] = List(2, 4, 6)

scala> val z=Set(1,2,3)
z: scala.collection.immutable.Set[Int] = Set(1, 2, 3)

scala> z.map(_*2)
res27: scala.collection.immutable.Set[Int] = Set(2, 4, 6)
//返回值类型为Array[Unit] []中为每个元素经过处理后的类型
scala> x.map(println)
1
2
3
res25: Array[Unit] = Array((), (), ())

帮助信息

scala.collection.TraversableLike
def map[B, That](f: A => B)(implicit bf: CanBuildFrom[Repr, B, That]): That

Builds a new collection by applying a function to all elements of this general collection.
通过将函数应用于此常规集合的所有元素来生成新集合。
Params:
参数:
f – the function to apply to each element.
f–应用于每个元素的函数。
bf – an implicit value of class CanBuildFrom which determines the result class That from the current representation type Repr and and the new element type B.

Type parameters:
类型参数:
B – the element type of the returned collection.
B–返回集合的元素类型。
That – the class of the returned collection. Where possible, That is the same class as the current collection class Repr, but this depends on the element type B being admissible for that class, which means that an implicit instance of type CanBuildFrom[Repr, B, That] is found.
That–返回集合的类。在可能的情况下,该类与当前集合类Repr是同一个类,但这取决于该类允许的元素类型B,这意味着找到了CanBuildFrom[Repr,B,That]类型的隐式实例。
Returns:
a new collection of type That resulting from applying the given function f to each element of this general collection and collecting the results.
将给定函数f应用于此常规集合的每个元素并收集结果而得到的类型的新集合。

源码

 def map[B, That](f: A => B)(implicit bf: CanBuildFrom[Repr, B, That]): That = {
    def builder = { // extracted to keep method size under 35 bytes, so that it can be JIT-inlined
      val b = bf(repr)
      b.sizeHint(this)
      b
    }
    val b = builder
    for (x <- this) b += f(x)
    b.result
  }

foreach方法

用于对集合中的每个元素进行处理,无返回值

scala> val x=List(1,2,3)
x: List[Int] = List(1, 2, 3)
//foreach用于对集合中的每个元素进行处理
//foreach方法返回值无类型
scala> val l=x.foreach(x=>println(x*2))
2
4
6
l: Unit = ()

scala> l.getClass
res36: Class[Unit] = void
//map方法是有返回值的,返回值是个集合类型
scala> val m=x.map(_*2)
m: List[Int] = List(2, 4, 6)
//查看返回值的类型
scala> m.getClass
res37: Class[_ <: List[Int]] = class scala.collection.immutable.$colon$colon

官方帮助
在这里插入图片描述

foreach和map方法的不同

foreach和map方法都可以对集合中的元素进行遍历,然后处理,不同之处在于foreach是没有返回值的. 而map是可以返回一个集合用于下一步的处理.

flatten方法

flatten方法用于把一个集合中的元素拆分出来,也就是说,你集合中的元素必须还是个集合. 集合中的元素不是集合,是没法用这个方法的


scala> val l= List(List(1,2),List(3,4))
l: List[List[Int]] = List(List(1, 2), List(3, 4))

scala> l.flatten
res49: List[Int] = List(1, 2, 3, 4)

scala> val m=List("abc","def")
m: List[String] = List(abc, def)

scala> m.flatten
res50: List[Char] = List(a, b, c, d, e, f)

帮助
flatten使用时无需参数,有一个隐式参数.

def flatten[U](implicit asTrav: T => Traversable[U], m: ClassTag[U]): Array[U]
Flattens a two-dimensional array by concatenating all its rows into a single array.
Params:
asTrav – A function that converts elements of this array to rows - arrays of type U.
Type parameters:
U – Type of row elements.
Returns:
An array obtained by concatenating rows of this array.

flatMap方法

需要先map后展开的时候可以想起这个方法用一下~

//构建字符串序列
scala> val fruits = Seq("apple", "banana", "orange")
fruits: Seq[String] = List(apple, banana, orange)
//利用map处理seq的每个元素
scala> fruits.map(_.toUpperCase)
res0: Seq[String] = List(APPLE, BANANA, ORANGE)
//展开字符串,字符串本质char数组
scala> fruits.flatten
res1: Seq[Char] = List(a, p, p, l, e, b, a, n, a, n, a, o, r, a, n, g, e)
//先map再展开 等价于flatMap
scala> fruits.map(_.toUpperCase).flatten
res2: Seq[Char] = List(A, P, P, L, E, B, A, N, A, N, A, O, R, A, N, G, E)
//map flatten可以合二为一
scala> fruits.flatMap(_.toUpperCase)
res3: Seq[Char] = List(A, P, P, L, E, B, A, N, A, N, A, O, R, A, N, G, E)
//先去部分值之后再展开
scala> fruits.flatMap(_.take(3))
res4: Seq[Char] = List(a, p, p, b, a, n, o, r, a)
//先反转再展开
scala> fruits.flatMap(_.reverse)
res5: Seq[Char] = List(e, l, p, p, a, a, n, a, n, a, b, e, g, n, a, r, o)
//先反转再大写再展开
scala> fruits.flatMap(_.reverse.toUpperCase)
res6: Seq[Char] = List(E, L, P, P, A, A, N, A, N, A, B, E, G, N, A, R, O)

//先拆分成数组再展开,其实这步没有必要,字符串本身就是数组
scala> fruits.flatMap(_.split(""))
res8: Seq[String] = List(a, p, p, l, e, b, a, n, a, n, a, o, r, a, n, g, e)
//同上,先拆分成数组再展开
scala> fruits.flatMap(_.toUpperCase.split(""))
res9: Seq[String] = List(A, P, P, L, E, B, A, N, A, N, A, O, R, A, N, G, E)


// 先翻倍再展开
scala> fruits.flatMap(_*2)
res11: Seq[Char] = List(a, p, p, l, e, a, p, p, l, e, b, a, n, a, n, a, b, a, n, a, n, a, o, r, a, n, g, e, o, r, a, n, g, e)

//可以直接展开的 就没必要先调用java的split方法转数组
scala> fruits.flatten
res13: Seq[Char] = List(a, p, p, l, e, b, a, n, a, n, a, o, r, a, n, g, e)

再比如

scala>  val list = List(1,2,3,4,5)
list: List[Int] = List(1, 2, 3, 4, 5)
//为list中的每个元素生成一个三元tuple
scala>  def g(v:Int) = List(v-1, v, v+1)
g: (v: Int)List[Int]

scala> list.map(x=>g(x))
res14: List[List[Int]] = List(List(0, 1, 2), List(1, 2, 3), List(2, 3, 4), List(3, 4, 5), List(4, 5, 6))

scala> res14.flatten
res15: List[Int] = List(0, 1, 2, 1, 2, 3, 2, 3, 4, 3, 4, 5, 4, 5, 6)
//实现对list中元素先扩展后展开的效果
scala> list.flatMap(x=>g(x))
res16: List[Int] = List(0, 1, 2, 1, 2, 3, 2, 3, 4, 3, 4, 5, 4, 5, 6)

map转vector

scala>  val map = Map(1 -> "one", 2 -> "two", 3 -> "three")
map: scala.collection.immutable.Map[Int,String] = Map(1 -> one, 2 -> two, 3 -> three)

scala> 1.to(map.size).flatMap(map.get)
res17: scala.collection.immutable.IndexedSeq[String] = Vector(one, two, three)

scala> 1.to(map.size).map(map.get)
res18: scala.collection.immutable.IndexedSeq[Option[String]] = Vector(Some(one), Some(two), Some(three))

scala> 1.to(map.size)
res19: scala.collection.immutable.Range.Inclusive = Range(1, 2, 3)

scala> 1.to(map.size).map(map.get(_))
res20: scala.collection.immutable.IndexedSeq[Option[String]] = Vector(Some(one), Some(two), Some(three))
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值