Scala入门之List使用详解

 更新时间:2019年06月16日 17:02:27   作者:小破孩  
这篇文章主要介绍了Scala入门之List使用详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧

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。

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

相关文章

  • SpringBoot+devtools实现热部署的示例代码

    SpringBoot+devtools实现热部署的示例代码

    在软件项目的开发过程中,不可避免的会经常修改代码,每次修改代码,都需要手动停止然后再启动服务,最后验证代码的正确性,今天通过这篇文章,我们一起来学习一下如何使用Spring Boot + devtools 轻松搞定热部署,需要的朋友可以参考下
    2024-08-08
  • SpringCloud服务之间Feign调用不会带上请求头header的解决方法

    SpringCloud服务之间Feign调用不会带上请求头header的解决方法

    在Spring Cloud中,使用Feign进行服务之间的调用时,默认情况下是不会传递header的,这篇文章给大家介绍SpringCloud服务之间Feign调用不会带上请求头header的解决方法,感兴趣的朋友一起看看吧
    2024-01-01
  • idea右键没有java class选项问题解决方案

    idea右键没有java class选项问题解决方案

    这篇文章主要介绍了idea右键没有java class选项问题解决方案,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2020-04-04
  • java数据结构循环队列的空满判断及长度计算

    java数据结构循环队列的空满判断及长度计算

    这篇文章主要为大家介绍了java数据结构循环队列的空满判断及长度计算,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2022-06-06
  • SpringBoot项目启动时初始化操作常见的几种方式

    SpringBoot项目启动时初始化操作常见的几种方式

    这篇文章主要介绍了SpringBoot项目启动时初始化操作常见的几种方式,这些方法可以帮助开发者在服务启动时自动执行必要的初始化操作,需要的朋友可以参考下
    2025-02-02
  • Java中将bean放入Spring容器中的几种方式详解

    Java中将bean放入Spring容器中的几种方式详解

    这篇文章主要介绍了Java中将bean放入Spring容器中的几种方式详解,在Spring框架中,有多种方式可以将Bean(即对象)放入Spring容器中,今天我们就来详细说一下这几种方式,需要的朋友可以参考下
    2023-07-07
  • Spring Boot3 跨域配置 Cors的方式

    Spring Boot3 跨域配置 Cors的方式

    这篇文章主要介绍了Spring Boot3 跨域配置 Cors,通过使用CORS,开发人员可以控制哪些外部网页可以访问他们的资源,从而提高应用程序的安全性,本文结合实例代码给大家介绍的非常详细,需要的朋友可以参考下
    2024-01-01
  • Springboot拦截filter中异常的处理

    Springboot拦截filter中异常的处理

    SpringBoot提供了全局异常处理机制可以拦截所有异常,包括Filter中的异常,本文主要介绍了Springboot拦截filter中异常的处理,具有一定的参考价值,感兴趣的可以了解一下
    2023-11-11
  • MyBatis使用嵌套查询collection和association的实现

    MyBatis使用嵌套查询collection和association的实现

    本文详细介绍了使用MyBatis框架进行数据库操作时,如何利用collection标签实现一对多的嵌套查询和使用association标签实现一对一的嵌套查询,感兴趣的可以了解一下
    2024-09-09
  • 详细总结各种排序算法(Java实现)

    详细总结各种排序算法(Java实现)

    下面小编就为大家带来一篇详细总结各种排序算法(Java实现)。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2017-09-09

最新评论