• Scala Collection简介


    [comment]: # Scala Collection简介

    Traversable vs Iterable

    Traversable, Iterable 都是trait。
    Iterable 继承 Traversable。
    Traversable: 支持foreach.
    Iterable: 支持Interator方法。

    Immutable vs mutable

    Scala的Collection有Immutable和mutable两个大家族。
    Immutable: 不可变。初始化后不会发生变化。scala的默认collections。性能更好。
    Mutable: 可变。初始化后,可以发生变化。在多线程的访问时,会使用到锁。
    可以定义event,来监视数值的变化。

            // Immutable vs mutable
            println("--- Immutable vs mutable ---")
            val listImm = 1 to 5
            println("Immutable list: cannot do: listImm(0) = 100")
            println("Immutable list: " + listImm)
            val listMutable = scala.collection.mutable.MutableList[Int](1,2,3,4,5)
            listMutable(0) = 100
            println("Mutable list: " + listMutable)
    

    输出:

    --- Immutable vs mutable ---
    Immutable list: cannot do: listImm(0) = 100
    Immutable list: Range(1, 2, 3, 4, 5)
    Mutable list: MutableList(100, 2, 3, 4, 5)
    

    Seq vs Set vs Map

    Seq, Set, Map都是trait。
    Seq: 对象可以重复。
    Set: 对象不能重复。
    Map: 是一个key-value实现,key不能重复。

    LinearSeq vs IndexedSeq

    LinearSeq, IndexedSeq都是trait。
    LinearSeq: 提供高效head and tail的分割.
    IndexedSeq: 提供高效的随机访问。

            // Support head and tail
            println("--- head and tail ---")
            val list1 = Seq(1, 2, 3)
            println(list1)
            println("head and tail: split head and tail.")
            list1 match {
                case h::t => println("head: " + h + "
    tail: " + t)
            }
    

    输出:

    --- head and tail ---
    List(1, 2, 3)
    head and tail: split head and tail.
    head: 1
    tail: List(2, 3)
    

    TreeSet vs HashSet vs BitSet

    TreeSet, HashSet, BitSet都是class。
    TreeSet: 一个树的Set实现。通过值的大小判断,需要一个implicit Ordering的实现。
    HashSet: 一个Set实现, 使用Hash值来确定对象的唯一性。
    BitSet: 一个只存储Long的Set实现,返回boolean值。用于管理大量的标志位。

            // BitSet
            println("--- BitSet ---")
            println("BitSet: Used to store and access a large amount of flags.")
            val bitSet = scala.collection.mutable.BitSet(1,3,4)
            bitSet.remove(4)
            bitSet.add(5)
            println(bitSet)
            for(i <- (1 to 5)) println("BitSet: " + i + ": " + bitSet(i))
    

    输出:

    --- BitSet ---
    BitSet: Used to store and access a large amount of flags.
    BitSet(1, 3, 5)
    BitSet: 1: true
    BitSet: 2: false
    BitSet: 3: true
    BitSet: 4: false
    BitSet: 5: true
    

    TreeMaps vs HashMaps

    TreeMaps, HashMaps都是class。
    TreeMaps: 一个Tree的Map实现。
    HashMaps: 一个Hash key的Map实现。

    Vector vs List vs Stream

    Vector, List, Stream都是immutable。
    Vector: 对于随机访问性能最好。推荐使用。
    List: 对于head/tail的访问性能最好。
    Stream: lazy估值,主要用于无限数列(infinite sequences)。

            // Stream
            println("--- Stream ---")
            val fibs: Stream[Int] = {
                def f(a: Int, b: Int): Stream[Int] = a #:: f(b, a + b)
                f(0, 1)
            }
            println("Stream: is lazy: " + fibs)
            fibs(5)
            println("Stream: after get 5: " + fibs)
            println("--- ")
            println("Stream: an infinite stream of incrementing numbers starting from 1 ")
            println(List("a", "b", "c") zip (Stream from 1))
    

    输出:

    --- Stream ---
    Stream: is lazy: Stream(0, ?)
    Stream: after get 5: Stream(0, 1, 1, 2, 3, 5, ?)
    --- 
    Stream: an infinite stream of incrementing numbers starting from 1 
    List((a,1), (b,2), (c,3))
    

    Views

    Views类似于数据库的view,lasy,性能很好。

    map vs zip vs drop/take vs filter vs group vs sliding

    map 每个元素到一个函数,把所有函数的结果组成一个新的collection

    println("Map: " + listMap + " to: " + listMap.map(x => x * x))
    println(listMap map (x => x * x))
    

    输出:

    --- map ---
    Map: Range(1, 2, 3, 4, 5) to: Vector(1, 4, 9, 16, 25)
    Vector(1, 4, 9, 16, 25)
    

    filter:生成一个条件过滤后的Range

            // filter
            println("--- filter ---")
            val listFilter = (1 to 10)
            println("filter: " + listFilter + " to: " + listFilter.filter(x => x % 2 == 0))
            println(listFilter filter (x => x % 2 == 0))
    

    输出:

    --- filter ---
    filter: Range(1, 2, 3, 4, 5, 6, 7, 8, 9, 10) to: Vector(2, 4, 6, 8, 10)
    Vector(2, 4, 6, 8, 10)
    

    drop & filter:从当前的List中选取一段,生成一个Range

            // drop and take
            println("--- drop and take ---")
            val listTake = (1 to 10)
            println("take: " + listTake + " to: " + listTake.drop(5).take(3))
            println(listTake drop(5) take(3))
    

    输出:

    --- drop and take ---
    take: Range(1, 2, 3, 4, 5, 6, 7, 8, 9, 10) to: Range(6, 7, 8)
    Range(6, 7, 8)
    

    zip: 将两个List做列合并。

            // zip
            println("--- zip ---")
            val listZip1 = (1 to 5)
            val listZip2 = List("A", "B", "C", "D", "E")
            println("Zip: " + listZip1 + " and " + listZip1 + " to: " + listZip1.zip(listZip2))
            println(listZip1 zip listZip2)
    

    输出:

    --- zip ---
    Zip: Range(1, 2, 3, 4, 5) and Range(1, 2, 3, 4, 5) to: Vector((1,A), (2,B), (3,C), (4,D), (5,E))
    Vector((1,A), (2,B), (3,C), (4,D), (5,E))
    

    grouped: 将collection按照指定的size组合成多个Vector,返回这个List的iterator。

            // grouped
            println("--- grouped ---")
            val listgroup = (1 to 10)
            val listgroupIterator = listgroup.grouped(3)
            println("grouped: " + listgroup + " with size 3 to: " + listgroupIterator)
            listgroupIterator foreach println
    

    输出:

    --- grouped ---
    grouped: Range(1, 2, 3, 4, 5, 6, 7, 8, 9, 10) with size 3 to: non-empty iterator
    Vector(1, 2, 3)
    Vector(4, 5, 6)
    Vector(7, 8, 9)
    Vector(10)
    

    sliding: 将collection按照指定的size组合成一个滑动的块,返回这个块的iterator。

            // sliding
            println("--- sliding ---")
            val listSliding = (2 to 10 by 2)
            val listSlidingIterator = listSliding.sliding(3)
            println("sliding: " + listSliding + " with size 3 to: " + listSlidingIterator)
            listSlidingIterator foreach println
            println("----")
            println("sliding: tails")
            listSliding.tails foreach println
    

    输出:

    --- sliding ---
    sliding: Vector(2, 4, 6, 8, 10) with size 3 to: non-empty iterator
    Vector(2, 4, 6)
    Vector(4, 6, 8)
    Vector(6, 8, 10)
    ----
    sliding: tails
    Vector(2, 4, 6, 8, 10)
    Vector(4, 6, 8, 10)
    Vector(6, 8, 10)
    Vector(8, 10)
    Vector(10)
    Vector()
    

    reduce vs reduceLeft vs reduceRigh vs fold vs foldLeft vs foldRight vs scan vs scanLeft vs scanRight

    都适用于cumulate计算。
    reduce, reduceLeft, reduceRight: 计算一个单独的累计结果。
    fold, foldLeft, foldRight: 计算一个单独的累计结果,带一个起始值。
    scan, scanLeft, scanRight: 得到的是一个List。List的长度和以前一样,分别是对应的单步累计结果。有一个起始种子。
    reduce, fold, scan: 用于并行计算。
    reduceLeft, foldLeft, scanLeft: 从前到后线性计算。
    reduceRight, foldRight, scanRight: 从后到前线性计算。
    foldLeft是线性计算。

            // fold & reduce & scan
            println("--- fold & reduce & scan ---")
            val listAdd = List(1,2,3,4,5)
            def addOp(a: Int, b: Int): Int = {
                println(a + ":" + b)
                a + b
            }
            println("--- reduce")
            println("reduce: " + listAdd + " to: " + listAdd.par.reduce(addOp(_, _)))
            println("--- reduceLeft")
            println("reduceLeft: " + listAdd + " to: " + listAdd.reduceLeft(addOp(_, _)))
            println("--- reduceRight")
            println("reduceRight: " + listAdd + " to: " + listAdd.reduceRight(addOp(_, _)))
    

    输出:

    --- fold & reduce & scan ---
    --- reduce
    1:2
    4:5
    3:9
    3:12
    reduce: List(1, 2, 3, 4, 5) to: 15
    --- reduceLeft
    1:2
    3:3
    6:4
    10:5
    reduceLeft: List(1, 2, 3, 4, 5) to: 15
    --- reduceRight
    4:5
    3:9
    2:12
    1:14
    reduceRight: List(1, 2, 3, 4, 5) to: 15
    
            println("--- fold")
            println("fold: " + listAdd + " to: " + listAdd.par.fold(100)(addOp(_, _)))
            println("--- foldLeft")
            println("foldLeft: " + listAdd + " to: " + listAdd.foldLeft(100)(addOp(_, _)))
            println("--- foldRight")
            println("foldRight: " + listAdd + " to: " + listAdd.foldRight(100)(addOp(_, _)))
    

    输出:

    --- fold
    100:1
    100:2
    100:5
    100:3
    100:4
    101:102
    104:105
    103:209
    203:312
    fold: List(1, 2, 3, 4, 5) to: 515
    --- foldLeft
    100:1
    101:2
    103:3
    106:4
    110:5
    foldLeft: List(1, 2, 3, 4, 5) to: 115
    --- foldRight
    5:100
    4:105
    3:109
    2:112
    1:114
    foldRight: List(1, 2, 3, 4, 5) to: 115
    
            println("--- scan")
            println("scan: " + listAdd + " to: " + listAdd.par.scan(100)(addOp(_, _)))
            println("--- scanLeft")
            println("scanLeft: " + listAdd + " to: " + listAdd.scanLeft(100)(addOp(_, _)))
            println("--- scanRight")
            println("scanRight: " + listAdd + " to: " + listAdd.scanRight(100)(addOp(_, _)))
    

    输出:

    --- scan
    4:5
    1:2
    3:4
    3:9
    3:3
    3:7
    3:12
    100:1
    3:3
    1:2
    10:5
    6:4
    scan: List(1, 2, 3, 4, 5) to: ParVector(100, 101, 3, 6, 10, 15)
    --- scanLeft
    100:1
    101:2
    103:3
    106:4
    110:5
    scanLeft: List(1, 2, 3, 4, 5) to: List(100, 101, 103, 106, 110, 115)
    --- scanRight
    5:100
    4:105
    3:109
    2:112
    1:114
    scanRight: List(1, 2, 3, 4, 5) to: List(115, 114, 112, 109, 105, 100)
    

    参照

  • 相关阅读:
    file & iconv
    UML类图思考
    Rust PhantomData and dropck rgb
    golang recover rgb
    帮上小学的女儿写的一篇文章春夏秋冬
    SAP B1在添加物料主数据时,出现错误提示‘xxxx代码已存在’的解决方法
    SAP B1外协物料处理方法
    SAP B1外发加工件成本的处理方法(曹玉平于奥莱照明)
    SAP B1存在的BUG
    交叉表的实殃及向SQL SERVER数据库中插入数据时,出现乱码或???(问号)的解决方法。
  • 原文地址:https://www.cnblogs.com/steven-yang/p/5875766.html
Copyright © 2020-2023  润新知