scala List列表

scala列表

Scala的 list 类是不可变的, 大小及其中元素都不能修改, 它由链表实现.

List类是后进先出(LIFO), 类似栈访问模式的最好实现. 如果需要另外一种访问模式, 如FIFO可以考虑List之外的集合. List的前置, 头尾访问的时间复杂度都是o(1), 对于列表中的大多数的操作都是o(n)


创建与初始化
scala> val list = 1::2::3::Nil
list: List[Int] = List(1, 2, 3)
scala> val x = List(1,2.0,33D, 4000L)
x: List[Double] = List(1.0, 2.0, 33.0, 4000.0)

scala> val x = List(1,2.0,33D, 4000L)
x: List[Double] = List(1.0, 2.0, 33.0, 4000.0)

scala> val x = List.range(1,10)
x: List[Int] = List(1, 2, 3, 4, 5, 6, 7, 8, 9)

scala> val x = List.range(1,10,2)
x: List[Int] = List(1, 3, 5, 7, 9)

scala> val x = List.fill(5)("hello")
x: List[String] = List(hello, hello, hello, hello, hello)

scala> val x = List.tabulate(5)(n => n*n)
x: List[Int] = List(0, 1, 4, 9, 16)

scala> val x = collection.mutable.ListBuffer(1,2,3).toList
x: List[Int] = List(1, 2, 3)

scala> "hello".toList
res0: List[Char] = List(h, e, l, l, o)

List.tabulate() 方法是通过给定的函数来创建列表。 方法的第一个参数为元素的数量,可以是二维的,第二个参数为指定的函数起始值为 0

Nil是一个空的List,定义为List[Nothing],根据List的定义List[+A],所有Nil是所有List[T]的子类
:: 也叫做cons 方法接受两个参数:一个头元素,必须是单个元素,一个尾元素, 是另外一个List, 用这种方式去构造List,结尾必须是Nil元素

Scala的List与java中的List类不同,如java的ArrayList, 所以一个java.util.List可以转化为Scaka Buffer或者seq, 而不是Scala List


创建可变List

List是不可变的,想使用可变列表 可以使用ListBuffer, 在必要时再将ListBuffer转换为List

如果创建要经常改变的列表,推荐在需要改变时使用ListBuffer, 需要时再转换为List

import scala.collection.mutable.ListBuffer

var fruits = new ListBuffer[String]()

//add one element at a time to the ListBuffer
fruits += "Apple"
fruits += "Banana"
fruits += "Orange"

//add multiple elements
fruits += ("Strawberry", "Kiwi", "Pineapple")

//remove one element
fruits -= "Apple"

//remove multiple element
fruits -=("Banana", "Orange")

//remove multiple elements specified by another sequence
fruits --= seq("kiwi", "Pineapple")

//convert the ListBuffer to a List when you need to
val fruitsList = fruits.toList

scaladoc指出一个ListBuffer是”一个基于列表的缓冲实现, 前置和附加操作的开销都是常量时间. 其他大多数的操作复杂度都是线性时间.” 因此, 想要通过索引的方式(如 list(1000)) 访问元素, 用ArrayBuffer,而不是ListBuffer

ListBuffer是一个可变的. 线性的序列(相对与索引序列,像一个数组或者ArrayBuffer),语法和java中的StringBuffer或者StringBuilder类似,就像是在需要时将这些类转换为String…

虽然不能修改List中的元素,但是可以用::方法将元素贴在列表的结尾,创建一个新的List

scala> val x = List(2)
x: List[Int] = List(2)

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

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

添加/获取子集/删除

添加

val x = list(2)
val y = 1::x
val z = 0::y

添加时, 与其不断地将这个操作结果重新赋给一个新的变量, 不如将变量声明为var, 然后将结果重新赋给自己:

scala> var x = List(2)
x: List[Int] = List(2)

scala> x = 1::x
x: List[Int] = List(1, 2)

scala> x = 0::x
x: List[Int] = List(0, 1, 2)

:: 方法在列表前面添加元素,然后将结果赋给一个新的list
:: 是向右关联的, 列表都是从右向左构造而成的

scala> val a = 3::Nil
a: List[Int] = List(3)

scala> val a2 = 2::a
a2: List[Int] = List(2, 3)

scala> val a3= 3::a2
a3: List[Int] = List(3, 2, 3)

获取子集
通常使用filter, partition, splitAt, take等方法获取子集

删除
删除元素时可以使用可变序列的所有方法从中删除元素

import scala.collection.mutable.listBuffer
val x = listBUffer(1,2,3,4,5,6,7,8,9)
x -= 5
x -= (2, 3)
x.remove(0)
x.remove(1,3)
x --= seq(7,8,9)

合并连接

使用++ 、 concat 、 ::: 方法合并两个列表

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

scala> val b = 4::5::6::Nil
b: List[Int] = List(4, 5, 6)

scala> val c = a:::b
c: List[Int] = List(1, 2, 3, 4, 5, 6)

scala> val d = a++b
d: List[Int] = List(1, 2, 3, 4, 5, 6)

scala> val e = List.concat(a,b)
e: List[Int] = List(1, 2, 3, 4, 5, 6)

练习一:

object ListTest {
  def main(args: Array[String]): Unit = {
    val lst0 = List(1,8,2,3,6,4)
    println("lst0 : "+lst0)

    val lst1 = lst0.map { x => x*2 }
    println("lst1 : "+lst1)

    val lst2 = lst0.filter { x => x%2 == 0}
    println("lst2 : "+lst2)

    val lst3 = lst0.sorted
    println("lst3 : "+lst3)

    val lst4 = lst0.sortBy(x => -x)
    println("lst4 : "+lst4)

    val lst5 = lst0.sortWith((x,y)=> x<y )
    println("lst5 : "+lst5)

    val lst6 = lst0.reverse
    println("lst6 : "+lst6)

    //将lst0中的元素4个一组, 类型为Iterator[List[Int]]
    val it = lst0.grouped(4)
    for(x <- it){ println ("it "+x)}

    //将Iterator转换成List
    val lst7 = it.toList
    //lst7: List[List[Int]] = List(List(1, 8, 2, 3), List(6, 4))

    //将多个List压扁成一个List
    val lst8 = lst7.flatten
    //lst8: List[Int] = List(1, 8, 2, 3, 6, 4)
输出
lst0 : List(1, 8, 2, 3, 6, 4)
lst1 : List(2, 16, 4, 6, 12, 8)
lst2 : List(8, 2, 6, 4)
lst3 : List(1, 2, 3, 4, 6, 8)
lst4 : List(8, 6, 4, 3, 2, 1)
lst5 : List(1, 2, 3, 4, 6, 8)
lst6 : List(4, 6, 3, 2, 8, 1)
it List(1, 8, 2, 3)
it List(6, 4)
lst7 : List()
lst8 : List()

练习二:

scala> val a = Array ("a b c", "d e f", "h i j")
a: Array[String] = Array(a b c, d e f, h i j)
//先按空格切分, 再压平
scala> a.flatMap(_.split(" "))
res1: Array[String] = Array(a, b, c, d, e, f, h, i, j)

scala> var b = a.flatMap(_.split(" "))
b: Array[String] = Array(a, b, c, d, e, f, h, i, j)

scala> println(b(2))
c

scala> println(b)
[Ljava.lang.String;@6b8ef251

scala> print(b.toList)
List(a, b, c, d, e, f, h, i, j)

求和/乘
(reduce 实际调用的是reduceLeft => ((((1+8)+2))+3)+6)+4
1+8=9
9+2=11
11+3=14
…)

op:(A1,A1)=>A1

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

scala> lst0.reduce(_+_)
res5: Int = 24

scala> lst0.reduce(_*_)
res6: Int = 1152

reduce 实际调用 foldLeft
fold(初始值)

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

scala> 100+lst0.reduce(_+_)
res7: Int = 124

scala> lst0.fold(100)(_+_)
res8: Int = 124

scala> lst0.foldLeft(100)(_+_)
res9: Int = 124

scala> lst0.foldRight(100)(_+_)
res10: Int = 124

聚合
aggregate(0) 初始0
+.sum 子list内求和 (相当于map)
+ 所有子list求和(相当于reduce)
等同于:
aggregate(0)((x,y) => x + y.sum, (m,n) => m+n)
x=初始值0 (只加一次)
y.sum 子list和
m+n => ((list1.sum+list2.sum)+list3.sum)+list4.sum

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

//每个子list内求和(相当于map过程), 然后所有子list求和(相当于reduce)
scala> val result = arr.aggregate(0)(_+_.sum, _+_)
result: Int = 20

并集, 交集, 差集

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

scala> val L2 = List(5,6,4,7)
L2: List[Int] = List(5, 6, 4, 7)
//求并集
scala> val r1 = L1.union(L2)
r1: List[Int] = List(1, 2, 3, 4, 5, 6, 4, 7)
//求交集
scala> val r2 = L1.intersect(L2)
r2: List[Int] = List(4)
//求差集
scala> val r3 = L1.diff(L2)
r3: List[Int] = List(1, 2, 3)

scala> println(r3)
List(1, 2, 3)
scala> val m = Map(("a",1))
m: scala.collection.immutable.Map[String,Int] = Map(a -> 1)

list并行求和

scala> lst0.par.sum
res14: Int = 24

scala> lst0.par.map(_%2 ==0)
res15: scala.collection.parallel.immutable.ParSeq[Boolean] = ParVector(false, true, true, false, true, true)

scala> lst0.par.reduce((x,y) => x+y)
res16: Int = 24
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Pushkin.

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值