前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >有趣的Scala列表

有趣的Scala列表

作者头像
哒呵呵
发布2018-08-06 11:32:22
5030
发布2018-08-06 11:32:22
举报
文章被收录于专栏:鸿的学习笔记鸿的学习笔记

Scala的列表结构可以理解为一个样例类,因为它不需要使用new方法,例如:

代码语言:javascript
复制
scala> val a = List("a","b","c")
a: List[String] = List(a, b, c)

除了这种方法构建列表外,还可以使用::符号构建

代码语言:javascript
复制
scala> val t = "a" :: "b" :: "c" :: Nil
t: List[String] = List(a, b, c)

其中Nil表示空列表,::符号表示在列表前面追加元素,所以如果没有后面的Nil,Scala就会报错。

代码语言:javascript
复制
scala> val t = "a"::"b"::"c"
<console>:7: error: value :: is not a member of String
       val t = "a"::"b"::"c"

列表不同于数组Array,它是链表结构。并且列表元素必须要是同样的类型,如果列表里混用其它类型,那么它们的类型默认为Any类。所有类型的父类。

代码语言:javascript
复制
scala> val b = List("a",'b')
b: List[Any] = List(a, b)

有趣的一点在于,如果类型S是类型T的子类,那么List[S]也是List[T]的子类。这也是为什么下面的例子可以成立,因为空列表List[Nothing]是所有类型的子类,那么也是List[T]的子类型。

代码语言:javascript
复制
scala> val c:List[Int] = List()
c: List[Int] = List()
scala> List()
res5: List[Nothing] = List()

Scala的列表核心是三个方法:head(返回首元素),tail(除首元素以外的元素),isEmpty(判断是否为空)。

代码语言:javascript
复制
scala> val a = List(1,2,3)
a: List[Int] = List(1, 2, 3)
scala> a.head
res0: Int = 1
scala> a.tail
res1: List[Int] = List(2, 3)
scala> a.isEmpty
res2: Boolean = false

Scala的列表可以利用模式匹配实现和Python一样的解包

代码语言:javascript
复制
scala> val t = List(1,2,3)
t: List[Int] = List(1, 2, 3)
scala> val List(a,b,c) = t
a: Int = 1
b: Int = 2
c: Int = 3
scala> a
res3: Int = 1
scala> b
res4: Int = 2
scala> c
res5: Int = 3

当然如果你不确定元素数量的话,可以利用列表构建符号::去匹配元素,没有匹配上的元素都会变成列表赋给rest。

代码语言:javascript
复制
scala> val t = List(1,2,3,4)
t: List[Int] = List(1, 2, 3, 4)
scala> val a::b::rest = t
a: Int = 1
b: Int = 2
rest: List[Int] = List(3, 4)

下面聊下Scala列表的初阶方法和高阶方法,两者的区别仅在于初阶方法不接受函数作为参数传入,高阶可以。

  • 列表的拼接,使用:::符号
代码语言:javascript
复制
scala> val a = List(1,2,3)
a: List[Int] = List(1, 2, 3)
scala> val b = List(4,5,6)
b: List[Int] = List(4, 5, 6)
scala> a ::: b
res0: List[Int] = List(1, 2, 3, 4, 5, 6)

用模式匹配去看待列表拼接可以理解为:

代码语言:javascript
复制
scala> def concat[T](x:List[T],y:List[T]):List[T] =
     | x match {
     | case List() => y
     | case x :: xs => x :: concat(xs,y)
     | }
concat: [T](x: List[T], y: List[T])List[T]
scala> concat(a,b)
res2: List[Int] = List(1, 2, 3, 4, 5, 6)

只不过这里的concat定义的是函数,而不是列表的中缀方法。

  • 对应head和tail方法,还用init和last方法 init方法返回除末尾元素外的列表,last返回最后一个元素,显然对于链表结构,它们的运算量都是O(n)级别的
代码语言:javascript
复制
scala> a.init
res3: List[Int] = List(1, 2)
scala> a.last
res4: Int = 3
  • map、foreach,filter map函数很出名了,对列表每个元素做处理
代码语言:javascript
复制
scala> a.map(_+3)
res5: List[Int] = List(4, 5, 6)

foreach和map很类似,不过需要传入的是返回为Unit的函数

代码语言:javascript
复制
scala> var sum = 0
sum: Int = 0

scala> a.foreach(sum += _)

scala> sum
res7: Int = 6

filter则是过滤元素

代码语言:javascript
复制
scala> a.filter(_<2)
res8: List[Int] = List(1)
本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2018-05-10,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 鸿的学习笔记 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档