• Scala入门学习笔记四--List使用


    前言

    本篇将介绍一个和Array很相似的集合List,更多内容请参考:Scala教程

    本篇知识点概括

    • List的构造
    • List与Array的区别
    • List的常用方法
    • 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

    
    <p><b>(2)List与Array的区别:</b></p>
    1、List一旦创建,已有元素的值不能改变,可以使用添加元素或删除元素生成一个新的集合返回。
    如前面的nums,改变其值的话,编译器就会报错。而Array就可以成功
    

    scala>nums(3)=4
    :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()

    
    <p><b>(3)List常用构造方法</b></p>
    

    //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)
    至于::操作符的使用将在下面介绍

    
    <p><b>(4)List常用操作</b></p>
    ```java
    //判断是否为空
    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)

    
    <p><b>(6)::和:::操作符介绍</b></p>
    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的方法列表:  
    ![Listf方法](http://images2015.cnblogs.com/blog/633343/201607/633343-20160702163214781-1434972880.jpg)
    
    ![List方法](http://images2015.cnblogs.com/blog/633343/201607/633343-20160702163229968-495841413.jpg)
    
    <p style="color:red">注意:</p>
    类List没有提供append操作,因为随着列表变长append的耗时将呈线性增长,而使用::做前缀则仅花费常量时间。如果你想通过添加元素来构造列表,你的选择是把它们前缀进去,当你完成之后再调用reverse;或使用ListBuffer,一种提供append操作的可变列表,当你完成之后调用toList。
  • 相关阅读:
    CentOS7 运维
    【推荐】开源项目ElasticAmbari助力 ElasticSearch、Kibana、ambari服务高效运维管理
    逆向工程,调试Hello World !程序(更新中)
    校园网内网穿透
    搭建PXE服务及实现安装银河麒麟桌面操作系统
    Linux 的基础知识关于基本操作命令 --- No.3
    Unix/Linux fork前传
    60行C代码实现一个shell
    Linux 的基础知识回顾(安装vmware) ---- No.1 后面都以Centos8 为例
    vue v-bind绑定属性和样式
  • 原文地址:https://www.cnblogs.com/miqi1992/p/5635599.html
Copyright © 2020-2023  润新知