首页 > 其他 > 详细

Scala 集合(一)

时间:2020-04-02 17:26:16      阅读:81      评论:0      收藏:0      [点我收藏+]

Mutable和ImMutable

scala.collection包含可变和不可变。eg:collection.IndexedSeq[T]] 就是 collection.immutable.IndexedSeq[T]和collection.mutable.IndexedSeq[T]这两类的超类,只是mutable包在immutable包的基础上添加了一些辅助性的修改操作。

mutable (可变集合)

  • 可以在适当的地方被更新或扩展,可以修改,添加,移除一个集合的元素。
  • 如果想要同时使用可变和不可变集合类,只导入collection.mutable包即可。
  • mutable 集合类继承关系
    技术分享图片

immutable (不可变集合)

  • 不会被改变。但仍可以进行模拟添加,移除或更新操作。但是这些操作将在每一种情况下都返回一个新的集合,同时使原来的集合不发生改变。
  • 默认情况之下,使用不可变集合类。
  • immutable 集合类继承关系
    技术分享图片

Trait Traversable

Traversable(遍历)是容器(collection)类的最高级别特性(trait),它唯一的抽象操作是foreach:
def foreach[U](f: Elem => U)
需要实现Traversable的容器(collection)类仅仅需要定义与之相关的方法,其他所有方法可都可以从Traversable中继承。
foreach方法用于遍历容器(collection)内的所有元素和每个元素进行指定的操作(比如说f操作)。操作类型是Elem => U,其中Elem是容器(collection)中元素的类型,U是一个任意的返回值类型。对f的调用仅仅是容器遍历的副作用,实际上所有函数f的计算结果都被foreach抛弃了。
Traversable同时定义的很多具体方法,如下表所示。这些方法可以划分为以下类别:

  • 相加操作++(addition)表示把两个traversable对象附加在一起或者把一个迭代器的所有元素添加到traversable对象的尾部。
  • Map操作有map,flatMap和collect,它们可以通过对容器中的元素进行某些运算来生成一个新的容器。
  • 转换器(Conversion)操作包括toArray,toList,toIterable,toSeq,toIndexedSeq,toStream,toSet,和toMap,它们可以按照某种特定的方法对一个Traversable 容器进行转换。等容器类型已经与所需类型相匹配的时候,所有这些转换器都会不加改变的返回该容器。例如,对一个list使用toList,返回的结果就是list本身。
  • 拷贝(Copying)操作有copyToBuffer和copyToArray。从字面意思就可以知道,它们分别用于把容器中的元素元素拷贝到一个缓冲区或者数组里。
  • Size info操作包括有isEmpty,nonEmpty,size和hasDefiniteSize。Traversable容器有有限和无限之分。比方说,自然数流Stream.from(0)就是一个无限的traversable 容器。hasDefiniteSize方法能够判断一个容器是否可能是无限的。若hasDefiniteSize返回值为ture,容器肯定有限。若返回值为false,根据完整信息才能判断容器(collection)是无限还是有限。
  • 元素检索(ElementRetrieval) 操作有head,last,headOption,lastOption和find。这些操作可以查找容器的第一个元素或者最后一个元素,或者第一个符合某种条件的元素。注意,尽管如此,但也不是所有的容器都明确定义了什么是“第一个”或”最后一个“。例如,通过哈希值储存元素的哈希集合(hashSet),每次运行哈希值都会发生改变。在这种情况下,程序每次运行都可能会导致哈希集合的”第一个“元素发生变化。如果一个容器总是以相同的规则排列元素,那这个容器是有序的。大多数容器都是有序的,但有些不是(例如哈希集合)– 排序会造成一些额外消耗。排序对于重复性测试和辅助调试是不可或缺的。这就是为什么Scala容器中的所有容器类型都把有序作为可选项。例如,带有序性的HashSet就是LinkedHashSet。
  • 子容器检索(sub-collection Retrieval) 操作有tail,init,slice,take,drop,takeWhilte,dropWhile,filter,filteNot和withFilter。它们都可以通过范围索引或一些论断的判断返回某些子容器。
  • 拆分(Subdivision)操作有splitAt,span,partition和groupBy,它们用于把一个容器(collection)里的元素分割成多个子容器。
  • 元素测试(Element test) 包括有exists,forall和count,它们可以用一个给定论断来对容器中的元素进行判断。
  • 折叠(Folds)操作有foldLeft,foldRight,/:,:\,reduceLeft和reduceRight,用于对连续性元素的二进制操作。
  • 特殊折叠(Specific folds)包括sum, product, min, max。它们主要用于特定类型的容器(数值或比较)。
  • 字符串(String)操作有mkString,addString和stringPrefix,可以将一个容器通过可选的方式转换为字符串。
  • 视图(View)操作包含两个view方法的重载体。一个view对象可以当作是一个容器客观地展示。接下来将会介绍更多有关视图内容。

TRAIT ITERABLE

容器(collection)结构的上层还有另一个trait。这个trait里所有方法的定义都基于一个抽象方法,迭代器(iterator,会逐一的产生集合的所有元素)。从Traversable trait里继承来的foreach方法在这里也是利用iterator实现。下面是具体的实现。

def foreach[U](f: Elem => U): Unit = {
  val it = iterator
  while (it.hasNext) f(it.next())
}

foreach是Traversable所有操作的基础,所以它的性能表现很关键。
Iterable有两个方法返回迭代器:grouped和sliding。这些迭代器返回的不是单个元素,而是原容器(collection)元素的全部子序列。grouped方法返回元素的增量分块,sliding方法生成一个滑动元素的窗口。

Trait Iterable操作

抽象方法:
xs.iterator xs迭代器生成的每一个元素,以相同的顺序就像foreach一样遍历元素
其他迭代器:
xs grouped size 一个迭代器生成一个固定大小的容器(collection)块
xs sliding size 一个迭代器生成一个固定大小的滑动窗口作为容器(collection)的元素
子容器(Subcollection):
xs takeRight n 一个由xs的最后n个元素组成的collection(若定义的元素是无序,则由任意的n个元素组成)
xs dropRight n 一个由除了xs被取走(执行takeRight()方法) n个元素外的其余元素组成的collection
拉链方法(Zippers):
xs zip ys 把一对容器 xs和ys的包含的元素合成到一个iterabale
xs zipAll(ys, x, y) 一对容器 xs 和ys的相应的元素合并到一个iterable ,实现方式是通过附加的元素x或y,把短的序列被延展到相对更长的一个上
xs.zip WithIndex 把一对容器xs和它的序列,所包含的元素组成一个iterable
比对:
xs sameElements ys 测试 xs 和 ys 是否以相同的顺序包含相同的元素

REPL:

//iterator
scala> val a = List(1,2,3,4,5)
a: List[Int] = List(1, 2, 3, 4, 5)

scala> val aIterator = a.iterator
aIterator: Iterator[Int] = <iterator>

scala> aIterator.next()
res3: Int = 1

scala> aIterator.next()
res4: Int = 2

//grouped 
scala> val a = List(1,2,3,4,5)
a: List[Int] = List(1, 2, 3, 4, 5)

scala> val aIterator = a grouped 2
aIterator: Iterator[List[Int]] = <iterator>

scala> aIterator.next()
res0: List[Int] = List(1, 2)

scala> aIterator.next()
res1: List[Int] = List(3, 4)

scala> aIterator.next()
res2: List[Int] = List(5)

//sliding 
scala> val aIterator = a sliding 2
aIterator: Iterator[List[Int]] = <iterator>

scala> aIterator.next()
res5: List[Int] = List(1, 2)

scala> aIterator.next()
res6: List[Int] = List(2, 3)

scala> aIterator.next()
res7: List[Int] = List(3, 4)

//takeRight
scala> val aSubcollection = a takeRight 3
aSubcollection: List[Int] = List(3, 4, 5)

//dropRight
scala> val aSubcollection = a dropRight 2
aSubcollection: List[Int] = List(1, 2, 3)

scala> val aSubcollection = a dropRight 3
aSubcollection: List[Int] = List(1, 2)

//zip 
scala> val b = List("a","b","c","d","e","f")
b: List[String] = List(a, b, c, d, e, f)

scala> val sum = a zip b
sum: List[(Int, String)] = List((1,a), (2,b), (3,c), (4,d), (5,e))  //这里结果舍去了 “f”

//zipAll
scala> val sumAll = a zipAll(b,6,"z")
sumAll: List[(Int, String)] = List((1,a), (2,b), (3,c), (4,d), (5,e), (6,f))

//zipWithIndex
scala> b.zipWithIndex
res9: List[(String, Int)] = List((a,0), (b,1), (c,2), (d,3), (e,4), (f,5))

//sameElements 
scala> a sameElements b
res10: Boolean = false

Scala 集合(一)

原文:https://www.cnblogs.com/hanhande/p/12620618.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!