当前位置: 移动技术网 > IT编程>开发语言>Java > Scala入门之List使用详解

Scala入门之List使用详解

2019年07月19日  | 移动技术网IT编程  | 我要评论
scala中使用list scala是函数式风格与面向对象共存的编程语言,方法不应该有副作用是函数风格编程的一个重要的理念。方法唯一的效果应该是计算并返回值,用这种方式工

scala中使用list

scala是函数式风格与面向对象共存的编程语言,方法不应该有副作用是函数风格编程的一个重要的理念。方法唯一的效果应该是计算并返回值,用这种方式工作的好处就是方法之间很少纠缠在一起,因此就更加可靠和可重用。另一个好处(静态类型语言)是传入传出方法的所有东西都被类型检查器检查,因此逻辑错误会更有可能把自己表现为类型错误。把这个函数式编程的哲学应用到对象世界里以为着使对象不可变。

前面一章介绍的array数组是一个所有对象都共享相同类型的可变序列。比方说array[string]仅包含string。尽管实例化之后你无法改变array的长度。因此,array是可变的对象。
说到共享相同类型的不可变对象类型,scala的list类才是。和数组一样,list[string]包含的仅仅是string。scala的list不同于java的java.util.list,总是不可变的(java的list是可变)。更准确的说法,scala的list是设计给函数式风格的编程用的。

(1)list类型定义以及list的特点:

//字符串类型list
scala> val fruit=list("apple","banana","orange")
fruit: list[string] = list(apple, banana, orange)

//前一个语句与下面语句等同
scala> val fruit=list.apply("apple","banana","orange")
fruit: list[string] = list(apple, banana, orange)

//数值类型list
scala> val nums=list(1,2,3,4,5)
nums: list[int] = list(1, 2, 3, 4, 5)

//多重list,list的子元素为list
scala> val list = list(list(1, 2, 3), list("adfa", "asdfa", "asdf"))
list: list[list[any]] = list(list(1, 2, 3), list(adfa, asdfa, asdf))

//遍历list
scala> for(i <- list; from=i; j<-from)println(j)
1
2
3
adfa
asdfa
asdf

(2)list与array的区别:

1、list一旦创建,已有元素的值不能改变,可以使用添加元素或删除元素生成一个新的集合返回。
如前面的nums,改变其值的话,编译器就会报错。而array就可以成功

scala>nums(3)=4
<console>:10: error: value update is not a member of list[int]
       nums(3)=4
       ^

2、list具有递归结构(recursive structure),例如链表结构

list类型和气他类型集合一样,它具有协变性(covariant),即对于类型s和t,如果s是t的子类型,则list[s]也是list[t]的子类型。
例如:

scala>var liststr:list[object] = list("this", "is", "covariant", "example")
liststr:list[object] = list(this, is, covariant, example)

//空的list,其类行为nothing,nothing在scala的继承层次中的最底层
//,即nothing是任何scala其它类型如string,object等的子类
scala> var liststr = list()
liststr:list[nothing] = list()

scala>var liststr:list[string] = list()
liststr:list[string] = list()

(3)list常用构造方法

//1、常用::及nil进行列表构建
scala> val nums = 1 :: (2:: (3:: (4 :: nil)))
nums: list[int] = list(1, 2, 3, 4)


//由于::操作符的优先级是从右向左的,因此上一条语句等同于下面这条语句
scala> val nums = 1::2::3::4::nil
nums:list[int] = list(1, 2, 3, 4)
至于::操作符的使用将在下面介绍

(4)list常用操作

//判断是否为空
scala> nums.isempty
res5: boolean = false

//取第一个元素
scala> nums.head
res6: int = 1

//取列表第二个元素
scala>nums.tail.head
res7: int = 2

//取第三个元素
scala>nums.tail.tail.head
res8: int = 3

//插入操作
//在第二个位置插入一个元素
scala>nums.head::(3::nums.tail)
res11: list[int] = list(1, 3, 2, 3, 4)

scala> nums.head::(nums.tail.head::(4::nums.tail.tail))
res12: list[int] = list(1, 2, 4, 3, 4)

//插入排序算法实现
def isort(xs: list[int]):list[int] = {
  if(xs.isempty) nil
  else insert(xs.head, issort(xs.tail))
}

def insert(x:int, xs:list[int]):list[int] = {
  if(xs.isempty || x <= xs.head) x::xs
  else xs.head :: insert(x, xs.tail)
}

//连接操作
scala>list(1, 2, 3):::list(4, 5, 6)
res13: list[int] = list(1, 2, 3, 4, 5, 6)

//去除最后一个元素外的元素,返回的是列表
scala> nums.init
res13: list[int] = list(1, 2, 3)

//取出列表最后一个元素
scala>nums.last
res14: int = 4

//列表元素倒置
scala> nums.reverse
res15: list[int] = list(4, 3, 2, 1)

//一些好玩的方法调用
scala> nums.reverse.reverse == nums


//丢弃前面n个元素
scala>nums drop 3
res16: list[int] = list(4)

//获取前面n个元素
scala>nums take 1
res17: list[int] = list[1]

//将列表进行分割
scala> nums.splitat(2)
res18: (list[int], list[int]) = (list(1, 2),list(3, 4))

//前一个操作与下列语句等同
scala> (nums.take(2),nums.drop(2))
res19: (list[int], list[int]) = (list(1, 2),list(3, 4))

//zip操作
scala> val nums=list(1,2,3,4)
nums: list[int] = list(1, 2, 3, 4)

scala> val chars=list('1','2','3','4')
chars: list[char] = list(1, 2, 3, 4)

//返回的是list类型的元组(tuple),返回的元素个数与最小的list集合的元素个数一样
scala> nums zip chars
res20: list[(int, char)] = list((1,1), (2,2), (3,3), (4,4))

//list tostring方法
scala> nums.tostring
res21: string = list(1, 2, 3, 4)

//list mkstring方法
scala> nums.mkstring
res22: string = 1234

//转换成数组
scala> nums.toarray
res23: array[int] = array(1, 2, 3, 4)

(5)list伴生对象方法

//apply方法
scala> list.apply(1, 2, 3)
res24: list[int] = list(1, 2, 3)

//range方法,构建某一值范围内的list
scala> list.range(2, 6)
res25: list[int] = list(2, 3, 4, 5)

//步长为2
scala> list.range(2, 6,2)
res26: list[int] = list(2, 4)

//步长为-1
scala> list.range(2, 6,-1)
res27: list[int] = list()

scala> list.range(6,2 ,-1)
res28: list[int] = list(6, 5, 4, 3)

//构建相同元素的list
scala> list.make(5, "hey")
res29: list[string] = list(hey, hey, hey, hey, hey)

//unzip方法
scala> list.unzip(res20)
res30: (list[int], list[char]) = (list(1, 2, 3, 4),list(1, 2, 3, 4))

//list.flatten,将列表平滑成第一个无素
scala> val xss =
   | list(list('a', 'b'), list('c'), list('d', 'e'))
xss: list[list[char]] = list(list(a, b), list(c), list(d, e))
scala> xss.flatten
res31: list[char] = list(a, b, c, d, e)

//列表连接
scala> list.concat(list('a', 'b'), list('c'))
res32: list[char] = list(a
, b, c)

(6)::和:::操作符介绍

list中常用'::',发音为"cons"。cons把一个新元素组合到已有元素的最前端,然后返回结果list。

scala> val twothree = list(2, 3)
scala> val onetwothree = 1 :: twothree
scala> onetwothree
onetwothree: list[int] = list(1, 2, 3)

上面表达式"1::twothree"中,::是右操作数,列表twothree的方法。可能会有疑惑。表达式怎么是右边参数的方法,这是scala语言的一个例外的情况:如果一个方法操作符标注,如a * b,那么方法被左操作数调用,就像a.* (b)--除非方法名以冒号结尾。这种情况下,方法被右操作数调用。

list有个方法叫":::",用于实现叠加两个列表。

scala> val one = list('a', 'b')
val one = list('a', 'b')
scala> val two = list('c', 'd')

scala> one:::two
res1: list[char] = list(a, b, c, d)

下面是list的方法列表:

注意:

类list没有提供append操作,因为随着列表变长append的耗时将呈线性增长,而使用::做前缀则仅花费常量时间。如果你想通过添加元素来构造列表,你的选择是把它们前缀进去,当你完成之后再调用reverse;或使用listbuffer,一种提供append操作的可变列表,当你完成之后调用tolist。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持移动技术网。

如您对本文有疑问或者有任何想说的,请点击进行留言回复,万千网友为您解惑!

相关文章:

验证码:
移动技术网