1. 程式人生 > 實用技巧 >Scala:(三) 字串、集合(Array、List、Set、Map)、元組(tuple)

Scala:(三) 字串、集合(Array、List、Set、Map)、元組(tuple)

本文意在精簡,掌握最常用的,最基本的用法,不斷完善,一招鮮而吃遍天

字串

在 Scala 中,字串的型別實際上是 Java String,它本身沒有 String 類,定義一個string類,其型別就是 String (java.lang.String)。
在 Scala 中,String 是一個不可變的物件,所以該物件不可被修改。這就意味著你如果修改字串就會產生一個新的字串物件。

由於scala中的String類和Java中的是同一個,所以其自帶方法是相同的。常用方法如下所示:
常用string自帶方法

返回值 方法 註釋
String concat(String str) 將指定字串連線到此字串的結尾
boolean contentEquals(StringBuffer sb) 將此字串與指定的 StringBuffer 比較。
boolean endsWith(String suffix) 測試此字串是否以指定的字尾結束 ,同理還有startsWith
boolean equals(Object anObject) 將此字串與指定的物件比較
boolean equalsIgnoreCase(String anotherString) 將此 String 與另一個 String 比較,不考慮大小寫
int indexOf(String str, int fromIndex) 返回指定子字串在此字串中第一次出現處的索引,從指定的索引開始,後一個引數可為空
int length() 返回此字串的長度
boolean matches(String regex) 告知此字串是否匹配給定的正則表示式
String replace(char oldChar, char newChar) 返回一個新的字串,它是通過用 newChar 替換此字串中出現的所有 oldChar 得到的
String replaceAll(String regex, String replacement) 使用給定的 replacement 替換此字串所有匹配給定的正則表示式的子字串
String[] split(String regex) 根據給定正則表示式的匹配拆分此字串
String substring(int beginIndex, int endIndex) 返回一個新的字串,它是此字串的一個子字串,後一個引數可為空
String toLowerCase() 使用預設語言環境的規則將此 String 中的所有字元都轉換為小寫
String toUpperCase() 使用預設語言環境的規則將此 String 中的所有字元都轉換為大寫
String toUpperCase(Locale locale) 使用給定 Locale 的規則將此 String 中的所有字元都轉換為大寫
String trim() 刪除指定字串的首尾空白符
string String.valueOf(x) 返回指定型別引數的字串表示形式
... ... 其他方法在此不一一列舉

StringBuilder

集合


scala的集合設計,整體上分為三大類,所有的集合都擴充套件自Iterable特質:

  1. Seq,序列。是一組有序的元素。 諸如Array,List
  2. Set,集。 是一組無序的,沒有重複元素的集合。 諸如:
  3. Map,對映。是一組k-v對。key不可重複 諸如:

在Scala中集合有可變(mutable)和不可變(immutable)兩種型別,immutable型別的集合初始化後就不能改變了(注意與val修飾的變數進行區別)

Array

Scala 語言中提供的陣列是用來儲存固定大小的同類型元素,陣列中某個指定的元素是通過索引來訪問的,元素索引從0開始。
建立陣列

// 建立陣列有兩種方式:
// 1. 直接new Array[Int](3) 此種是定長陣列,括號內必須填長度
val array1 = new Array[Int](2)
    array1(0) = 1
    array1(1) = 1
    array1(2) = 1 //此行會報錯,因為建立的是定長的陣列,只有兩個元素
// 2.  建立Int型別的陣列,直接賦值
val array2=Array[Int](1,2,3)

如要看到數組裡的全部內容,除了遍歷外,還可以使用toBuffer

其實也可不加泛型

陣列的遍歷

// 遍歷的兩種方式
//直接for迴圈
    for(i <- array2){
      println(i)
    }
    // foreach
    array2.foreach(i => {
      println(i)
    })


多維陣列的定義和遍歷

 val array3 = new Array[Array[String]](2)
    array3(0)=Array("1","2")
    array3(1)=Array("4","5")
    for(i <- 0 until array3.length){
      for(j <- 0 until array3(i).length){
        print(array3(i)(j)+"	")
      }
      println()
    }

    array3.foreach(i =>{
      println(i.toBuffer)
      i.foreach(j => {
        println(j)
      })
    })


陣列的常用方法

陣列結合yield 或者 map,filter等使用(map filter等的用法,詳見函式與方法一章)


陣列求求和,最大最小值,排序

拉鍊操作

注意:拉鍊操作是將兩個序列組合到一起,若兩者長度不同,則生成的長度為較短的那個序列的長度

序列

Scala的集合有三大類:序列Seq、集Set、對映Map,所有的集合都擴充套件自Iterable特質
在Scala中集合有可變(mutable)和不可變(immutable)兩種型別,immutable型別的集合初始化後就不能改變了(注意與val修飾的變數進行區別)

不可變序列

不可變的序列 import scala.collection.immutable._
在Scala中列表要麼為空(Nil表示空列表)要麼是一個head元素加上一個tail列表。
List可新增元素,但新增元素後返回的其實是一個新的list

可變序列

可變的序列 import scala.collection.mutable._
ListBuffer可新增元素,但返回的其實還是原來那個listBuffer
類似於String和StringBuilder

list的建立

// 建立不可變序列
val list1 = List(1,2,3,4,5)

list的遍歷

 // for
  val list = List(1,2,3,4,5)
    for(x <- list){
      print(x)
    }
  // foreach
 list.foreach { x => println(x)}

可變序列的建立及元素增減
如下也可

//構建一個可變列表,初始有3個元素1,2,3
  val list = ListBuffer[Int](1,2,3)

/建立一個空的可變列表
  val lst1 = new ListBuffer[Int]
  //向lst1中追加元素,注意:沒有生成新的集合
  lst1 += 4
  lst1.append(5)

  //將lst1中的元素最近到lst0中, 注意:沒有生成新的集合
  lst0 ++= lst1

  //將lst0和lst1合併成一個新的ListBuffer 注意:生成了一個集合
  val lst2= lst0 ++ lst1

  //將元素追加到lst0的後面生成一個新的集合
  val lst3 = lst0 :+ 5

list的常用方法
注意:list是可以新增元素的,但其實list是一個不可變序列,其新增後返回的是一個新的集合

# :: 操作符是將給定的頭和尾建立一個新的列表,:: 操作符是右結合的,如9 :: 5 :: 2 :: Nil相當於 9 :: (5 :: (2 :: Nil))

    //將0插入到lst1的前面生成一個新的List
    val list2 = 0 :: list1
    val list3 = list1.::(0)
    val list4 = 0 +: list1
    val list5 = list1.+:(0)

    //將一個元素新增到lst1的後面產生一個新的集合
    val list6 = list1 :+ 3

    val list0 = List(4,5,6)
    //將2個list合併成一個新的List
    val list7 = list1 ++ list0
    //將lst1插入到lst0前面生成一個新的集合
    val list8 = list1 ++: list0

    //將lst0插入到lst1前面生成一個新的集合
    val list9 = list1.:::(list0)
    
    // count,map,filter函式
    //filter
    val list1  = list.filter { x => x>3 }
    list1.foreach { println}
    
    //count
    val value = list1.count { x => x>3 }
    println(value)
    
    //map
    val nameList = List(
    		"hello beijing",
    		"hello shanghai",
    		"hello shenzhen"
        )
    val mapResult:List[Array[String]] = nameList.map{ x => x.split(" ") }
    mapResult.foreach{println}    
    
    //flatmap
    val flatMapResult : List[String] = nameList.flatMap{ x => x.split(" ") }
    flatMapResult.foreach { println }

Set

同樣的,對於set,同樣分為可變Set和不可變Set,set會自動去重
set的建立和遍歷

// 不可變set
import scala.collection.immutable.HashSet
 val set1 = new HashSet[Int]()
  //將元素和set1合併生成一個新的set,原有set不變
  val set2 = set1 + 4
  //set中元素不能重複
  val set3 = set1 ++ Set(5, 6, 7)
  val set0 = Set(1,3,4) ++ set1
  println(set0.getClass)

// 可變set
import scala.collection.mutable
 //建立一個可變的HashSet
  val set1 = new mutable.HashSet[Int]()
  //向HashSet中新增元素
  set1 += 2
  //add等價於+=
  set1.add(4)
  set1 ++= Set(1,3,5)
  println(set1)
  //刪除一個元素
  set1 -= 5
  set1.remove(2)
  println(set1)

set的遍歷

    val set1 = Set(1,2,3,4,4) //set會自動去重
    val set2 = Set(1,2,5)
  // set 的遍歷
  //foreach方式
  set1.foreach { println}
  //for迴圈的方式
   for(s <- set1){
      println(s)
    }

set的常用方法
最大最小count,交併差集,轉化為list轉化為string

  //set的交併差集,對於非Set集合,在做交集、並集、差集時必須轉換為Set,否則元素不去重沒有意義,對於非Set型別集合元素去重,可用distinct
  //交集
  val set3 = set1.intersect(set2)
  val set4 = set1.&(set2)
  //並集
  Set(1,2,3) ++ Set(2,4)
  Set(1,2,3) | Set(2,4)   // |方法等同於union方法
  Set(1,2,3) union Set(2,4)
  //差集
  set1.diff(set2).foreach { println }
  set1.&~(set2).foreach { println }
  //子集
  set1.subsetOf(set2)

Map

map是key-value的結構,其key不可重複,如key重複的話,前面對應的value會被後面的替換掉(還是挺實用的)
map的建立

  Map(1 -> "hello")
  Map(2,"world")
 //如下可以看到,map的初始化還是挺靈活的
val map = Map(
     "1" -> "hello",
      2 -> "world",
      (3,"scala")
)

map的遍歷和取值

map.get(“1”) 返回some(hello),是否有值
map.get(“1”).get返回hello,具體值
map.get(4).getOrElse(“no value”):如果map中沒有對應項,賦值為getOrElse傳的值。
遍歷仍是for 和foreach兩種方式

  //map遍歷
    for(x <- map){
      println("key:"+x._1+",  value:"+x._2)
    }

    map.foreach(f => {
      println("key:"+ f._1+",  value:"+f._2)
    })

  //遍歷key和value
  //遍歷key
    val keyIterable = map.keys
    keyIterable.foreach { key => {
      println("key:"+key+", value:"+map.get(key).get)
    } }
  //遍歷values
    val valueIterable = map.values
    valueIterable.foreach { value => {
      println("value: "+ value)
    } }

map的常用方法

  // map的合併,合併後相同key的value會被覆蓋掉
  map1.++(map2)    // map1中加入map2
  map1.++:(map2)   // map2中加入map1
  //map的filter過濾
   map.filter(_._2.equals("shsxt")).foreach(println)
  //map的count方法
   val count1  = map.count(p => {
      p._2.equals("scala")   //第二個元素是否是scala,返回個數【map的value是可重複】
    })
  //map是否包含某個key
  map.contains(2)
  //判斷map中符合條件的記錄是否存在
  println(map.exists(x =>{
      x._2.equals("scala")
    }))

元組 tuple

scala tuple與列表類似,也是不可變的,但與列表不同的是元組可以包含不同型別的元素。
元組的值是通過將單個的值包含在圓括號中構成的,目前 Scala 支援的元組最大長度為 22。對於更大長度你可以使用集合,或者擴充套件元組。
tuple也是不可變的,有句話形容tuple很合適,那就是 身有殘疾的只讀列表 。
tuple的建立

  val  tuple = new Tuple(1)
  val tuple2  = Tuple2(1,2)
  val tuple3 = Tuple3(1,2,3)
  // 最大支援到tuple22

tuple的遍歷和取值

  // tuple.productIterator得到迭代器,進而遍歷
  val tupleIterator = tuple10.productIterator
    while(tupleIterator.hasNext){
      println(tupleIterator.next())
    }
  //tuple的取值,使用._XX來獲取值
  val tuple2tuple2 = Tuple2((1,2),("hello","scala"))
  println(tuple2tuple2._1._2)

tuple的常用方法

  // swap元素翻轉,只針對tuple2
  tuple2.swap
  //toString  終於有個支援tostring的了
  println(tuple3.toString())