• 【Scala专栏】字符串与集合


      Scala中的字符串在本质上就是Java的字符串String,
    在这里插入图片描述
    所以在用法上除了要符合Scala的语法以外,其他方面是如出一辙的。
      Scala中的集合分为可变和不可变,默认声明的结果是不可变的。
      不可变和可变指的是:当集合进行增删操作(长度发生变化)时,不可变集合会返回新的集合,原集合不会变化,而可变集合会在原集合上进行修改。

    一、String/StringBuilder

    object Lesson_String {
      def main(args: Array[String]): Unit = {
        val str = "abcd"
        val str1 = new String("abcd")
        // Java/Scala输出都是true
        println(str.equals(str1))
        // Scala输出是true, Java中这个是false
        println(str == str1)
        val str2 = "ABCD"
        // 忽视大小写的匹配,输出true
        println(str.equalsIgnoreCase(str2))
        // b的index
        println(str.indexOf(98))
        println(str.indexOf("bd"))
        /** StringBuilder * */
        // Scala中无参构造可以不写()
    //    val strBuilder = new StringBuilder
        val strBuilder = new StringBuilder()
        strBuilder.append("abc")
        strBuilder + 'd'
        // 字符串用++=
        strBuilder ++= "efg"
        strBuilder += 'h'
        strBuilder.append(1.0)
        strBuilder.append(18f)
        println(s"strBuilder: $strBuilder")
      }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28

    println(s"strBuilder: $strBuilder"),这是一种占位符填充式的String字符串拼接的方式,是一个语法糖,比起直接用"+"来拼接字符串能更加优雅

    二、Array

    创建一维数组并赋值

    val arr1 = new Array[Int](3)
    arr1(0) = 10   // 等价于Java: arr1[0] = 10;
    // 创建String类型的数组,直接赋值: 其本质是会去调Array对象中重写的apply()方法
    val arr2 = Array[String]("s100", "s200", "s300")
    // 源码:
    /*    def apply[T: ClassTag](xs: T*): Array[T] = {
          val array = new Array[T](xs.length)
          var i = 0
          for (x <- xs.iterator) { array(i) = x; i += 1 }
          array
        }*/
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    创建二维数组并赋值

    val twoDimenArray = new Array[Array[Int]](3)
    twoDimenArray(0) = Array[Int](1, 2, 3, 4)
    twoDimenArray(1) = Array[Int](5, 6, 7, 8)
    twoDimenArray(2) = Array[Int](9, 10, 11, 12)
    
    • 1
    • 2
    • 3
    • 4

    concat函数: 拼接Array

    Array.concat(arr3, arr4).foreach(println)
    
    • 1

    fill函数: 初始化不可变Array

    val immutableArray = Array.fill(3)("hello1")
    immutableArray.foreach(println)
    
    • 1
    • 2

    初始化可变的Array

     val mutableArray = ArrayBuffer[String]("hello","scala")
     mutableArray.+=("!")
     mutableArray.+=:("!")
     mutableArray.append("!","!")
     mutableArray.foreach(println)
    
    • 1
    • 2
    • 3
    • 4
    • 5

    三、List

    创建list

    val list = List[String]("hello scala", "hello java", "hello spark")
    
    • 1

    map函数 => n:m输入输出

    val splitList: List[Array[String]] = list.map(ele => ele.split(" "))
    
    • 1

    flatMap => n:1输入输出

    val flatSplitList: List[String] = list.flatMap(ele => ele.split(" "))
    
    • 1

    filter => true的会留下

    val filterList: List[String] = list.filter(ele => {
      "hello scala".equals(ele)
    })
    
    • 1
    • 2
    • 3

    count => 统计true的element数量

    val count: Int = list.count(ele => {
      ele.length > 7
    })
    
    • 1
    • 2
    • 3

    可变的List

    val listBuffer: ListBuffer[Int] = ListBuffer[Int](1, 2, 3)
    listBuffer.append(7)
    listBuffer.+=:(-1)
    println(s"listBuffer: $listBuffer")
    
    • 1
    • 2
    • 3
    • 4

    笔者注:以上这些流式计算的函数,可以在编程时大大减少代码的编写量,效果很强大,也是函数式编程的一大特点。 Java8中的stream流也是借鉴了这种函数编程的思想而出现的。 不仅是List集合,对于其他集合也是一样的使用,未来在使用flink/spark等流批统一的计算框架时,会经常用到

    四、Set

    创建Set

    val set: Set[Int] = Set[Int](1, 2, 3, 4, 4, 5)
    val set1: Set[Int] = Set[Int](4, 5)
    
    • 1
    • 2

    取交集/差集/并集

    // 取交集
    val set2: Set[Int] = set.intersect(set1)
    println(set2)
    // 差集: set - set1
    val set3: Set[Int] = set.diff(set1)
    println(set3)
    // 操作符: &取交集
    val set4: Set[Int] = set & set1
    println(set4)
    // 操作符: &~diff
    val set5: Set[Int] = set &~ set1
    println(set5)
    // 操作符: |取并集
    val set6: Set[Int] = set | set1
    println(set6)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    filter: true的会留下

    val filterSet: Set[Int] = set.filter(ele => {
       ele > 2
    })
    println(filterSet)
    
    • 1
    • 2
    • 3
    • 4

    可变Set

    val mutableSet: mutable.Set[Int] = mutable.Set[Int](7, 7, 7)
    mutableSet.+=(77)
    println(mutableSet)
    
    • 1
    • 2
    • 3

    五、Map

    Map中的每个元素,实际上的存储结构其实是Tuble_2(2元组)类型,这个数据类型等下会提到,我们先来上手Map的Api

    创建map

    val map = Map[String, Int]("a" -> 100, "b" -> 200,("c", 300),("c", 400))
    
    • 1

    map中直接get(“key”)返回是Option类型,这个类型是Some(有值)/None(无值)的父类

    返回Some

    // Some(100)
    val elementA: Option[Int] = map.get("a")
    println(elementA)
    val aValue: Int = elementA.get
    println(aValue)
    
    • 1
    • 2
    • 3
    • 4
    • 5

    返回None

    val elementD: Option[Int] = map.get("d")
    
    • 1

    获取值并赋予默认值

    // getOrElse
    val dDefaultValue: Int = elementD.getOrElse(777)
    println(dDefaultValue)
    
    • 1
    • 2
    • 3

    获取keys

    // keys
    val keys: Iterable[String] = map.keys
    keys.foreach(println)
    
    • 1
    • 2
    • 3

    根据keys遍历得到values

    keys.foreach(key => {
      val value = map(key)
      println(s"key=$key,value=$value")
    })
    
    • 1
    • 2
    • 3
    • 4

    直接获取values

    val values: Iterable[Int] = map.values
    values.foreach(value => println(s"value=$value"))
    
    • 1
    • 2

    合并map

    // map.++()
    val map1 = Map[String,Int](("a",1),("b",2),("c",3),("d",4))
    val map2 = Map[String,Int](("a",100),("b",200),("c",300),("e",500))
    val map3: Map[String, Int] = map1.++(map2)
    
    • 1
    • 2
    • 3
    • 4

    可变的map

    val mutableMap = mutable.Map[String,Int](("a",1),("b",2),("c",3),("d",4),("e",5))
    mutableMap.put("a",100)
    
    • 1
    • 2

    filter函数

    val mapFilter: mutable.Map[String, Int] = mutableMap.filter(tuple => {
      "a".equals(tuple._1) && 100 == (tuple._2)
    })
    
    • 1
    • 2
    • 3

    六、Tuple

    Tuple,同Python中的Tuple一样的概念,但是Scala中最多支持Tuple中有22个元素,也就是Tuple22,而Python中则没有这个限制。

    什么是元组?

    一堆元素放在一个()里面
    与列表一样,与列表不同的是元组可以包含不同类型的元素.元组的值是通过将单个的值包含在圆括号中构成的.
    元组可以new, 也可以不new, 也可以直接写(ele1,ele*)

    创建元组

    val tuple1: Tuple1[String] = new Tuple1("hello tuple")
    val tuple2: (String, Int) = new Tuple2("hello tuple", 100)
    val tuple3: (Int, Boolean, Char) = new Tuple3(1, true, 'C')
    // 类似object.apply()的实现方式, 但其实是class
    val tuple4: (Int, Double, String, Boolean) = Tuple4(1, 3.4, "abc", false)
    val tuple6: (Int, Int, Int, Int, Int, String) = (1, 2, 3, 4, 5, "abc")
    // 最大的tuple
    val tuple22 = new Tuple22(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    遍历元组:不能通过for循环遍历,只能通过iterator迭代器遍历

    val tupleIterator: Iterator[Any] = tuple6.productIterator    while(tupleIterator.hasNext){
      println(tupleIterator.next())
    }
    tupleIterator.foreach(println)
    
    • 1
    • 2
    • 3
    • 4

    对于二元组Tuple2特有的交换2个元素的方法Tuple2.swap

    val tuple2 = Tuple2(1,2)
    tuple2.swap
    // 这里会输出(2,1)
    
    • 1
    • 2
    • 3

    scala中的下划线_有2个作用,一个是在遍历时指代集合中的每一个元素,例如有这样一个迭代器Iterator((3,1),(2,3)),就可以用在遍历时用_代替里面的元组元素,例如:

    val tupleIterator = Iterator((3,1),(2,3))
    tupleIterator.foreach(println(_))
    上面这行可以进一步简化为: tupleIterator.foreach(println)
    
    • 1
    • 2
    • 3

    下划线_还有一个作用是用来获取元组中的元素,比如有这样一个二元组tuple2 = (1,3),那么我们用tuple2_2就可以获取到其中的元素3

    出个小作业,下面这行输出的结果是什么?答案请分享在评论区

    知识补充: minBy可以根据元素的位置输出最小值

    val t: (Int, Iterator[(Int,Int)]) = (122,Iterator[(Int,Int)]((3,1),(2,3)))
    val tuple: (Int, Int) = t._2.minBy(_._2)
    println(tuple)
    
    • 1
    • 2
    • 3

    今天的内容也比较多,要认真学习和理解哦,我们下期再见!

  • 相关阅读:
    使用RS485芯片进行串口通讯
    微擎模块 拍图取字 1.7.0 | 智慧农场 1.5.5后台模块+前端小程序
    RSA加密与解密原理
    数仓之全量表、增量表、快照表、切片表、拉链表
    基于FPGA开发板的按键消抖实验
    petite-vue源码剖析-属性绑定`v-bind`的工作原理
    Layui + Flask | 表单元素(组件篇)(06)
    Freemodbus 移植过程记录
    解决 uni-app app使用 onBackPress 监听返回后关闭popup 以及使用 uni-simple-router 有冲突问题
    Netty编解码器和handler的调用机制
  • 原文地址:https://blog.csdn.net/haohaoxuexiyai/article/details/128146469