Scala語言基礎(chǔ)

Scala Doc

This is used to explain how to use the scala.

Prerequisites

  1. jdk.18
  2. scala-2.11.8

Installation

1.jdk

tar -zxvf jdk-8u191-linux-x64.tar.gz -C /user/local/java
vi /etc/profile
export JAVA_HOME=/user/local/java/jdk1.8.0_191
export PATH=$JAVA_HOME/bin:$PATH

2.Scala

tar -zxvf scala-2.11.8.tgz -C /user/local/
vi /etc/profile
export $SCALA_HOME=/user/local/scala-2.11.8
export PATH=$SCALA_HOME/bin:$PATH
source /etc/profile
java -version
    java version "1.8.0_191"
scala -version
    Scala code runner version 2.11.8 -- Copyright 2002-2016, LAMP/EPFL

Demo

  1. 創(chuàng)建maven項(xiàng)目,按照scala模版創(chuàng)建,等到IDEA自己將需要的jar加載進(jìn)來
  2. 修改pom文件,將原先創(chuàng)建的scala文件刪除
<properties>
    <scala.version>2.11.8</scala.version>
    <hadoop.version>2.6.0-cdh5.7.0</hadoop.version>
    <spark.version>2.2.0</spark.version>
  </properties>

3.創(chuàng)建object:創(chuàng)建HelloWorldApp object.

package com.edu.spark

object HelloWorldApp {
  def main(args: Array[String]): Unit = {
    println("Hello World!!!")
  }
}

4.運(yùn)行
在這個(gè)類中選擇右鍵,選擇Run HelloWorldApp選項(xiàng),查看輸出為:

Hello World!!!

Scala CLI

  1. 系統(tǒng)默認(rèn)變量
scala> 3+5
res0: Int = 8

在上面的代碼中,res是result的縮寫,后面的0表示變量的標(biāo)記,是從開始,后面:Int表示這個(gè)變量為int類型,=8表示值為8。

2.自定義變量

2.1 常量

scala>  val money:Int = 10000
money: Int = 10000
scala> money:Int = 18000
<console>:1: error: ';' expected but '=' found.
money:Int = 18000

使用val 定義的變量為常量,一旦賦值之后不能進(jìn)行修改,如果需要重新賦值,可以使用下面的方法:

scala>  val money:Int = 10000
money: Int = 10000
scala> val money:Int = 18000
money: Int = 18000

2.2 變量

scala> var money:Int = 10000
money: Int = 10000
scala> money = 18000
money: Int = 18000

定義一個(gè)變量可以直接進(jìn)行修改。

可以將val認(rèn)為是value的縮寫,是一個(gè)指定的值,不能變,而var是variable的縮寫,是一個(gè)可變的量。

  1. 類型推導(dǎo)
scala> var city="beijing"
city: String = beijing

scala可以直接進(jìn)行類型推導(dǎo),就是根據(jù)值來推導(dǎo)變量的類型。

  1. 數(shù)據(jù)類型
scala> var money:Float=1000.54;
<console>:11: error: type mismatch;
 found   : Double(1000.54)
 required: Float
       var money:Float=1000.54;
                       ^
scala> var money:Float=1000.54f;
money: Float = 1000.54

在對Float、Long數(shù)據(jù)類型的數(shù)據(jù)進(jìn)行操作時(shí),需要指定類型,例如1000.54f,100000L,20000.234d。

scala> 10.isInstanceOf[Int]
res2: Boolean = true

判斷某個(gè)變量或者值是否為某個(gè)特定的類型

scala> 10.asInstanceOf[Long]
res3: Long = 10

類型轉(zhuǎn)換:將這個(gè)值進(jìn)行類型轉(zhuǎn)換,變成其他數(shù)據(jù)類型,要考慮之間的兼容。

函數(shù)定義

函數(shù)定義結(jié)構(gòu)如下:

def  函數(shù)名(參數(shù)以及類型):返回值類型={  //方法體
  //不需要return,最后一行的數(shù)據(jù)當(dāng)作函數(shù)的返回值
}
例句:
def add(x: Int, y: Int): Int = {
    x + y
}
其他方式如下:
def add1(x: Int, y: Int) = {
    x + y
}
def add2(x: Int, y: Int)= x + y

如果這個(gè)方法沒有返回值,可以使用下面的寫法:
def sayHello(): Unit ={
    print("say hello")
}
在調(diào)用無參數(shù)的函數(shù)時(shí),可以直接使用函數(shù)名來調(diào)用,不需要攜帶后面的括號

函數(shù)應(yīng)用

  1. to
scala> 1 to 10
res5: scala.collection.immutable.Range.Inclusive = Range(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
scala> 1.to(10)
res6: scala.collection.immutable.Range.Inclusive = Range(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
上面兩種操作,結(jié)果是一樣的,都是一個(gè)range對象

2.until

scala> 1 until 10
res7: scala.collection.immutable.Range = Range(1, 2, 3, 4, 5, 6, 7, 8, 9)
scala> 1.until(10)
res8: scala.collection.immutable.Range = Range(1, 2, 3, 4, 5, 6, 7, 8, 9)
上面兩種操作,結(jié)果是一樣的,都是一個(gè)range對象

3.Range

Range定義:
class Range(val start: Int, val end: Int, val step: Int)
設(shè)置開始start,結(jié)束值end,每次的步長 step(默認(rèn)為1)
scala> Range(1,10)
res10: scala.collection.immutable.Range = Range(1, 2, 3, 4, 5, 6, 7, 8, 9)
  1. 對比

Range、until、to產(chǎn)生的對象都是Range
Range 與 until 基本一致,都是左閉右開的集合 從結(jié)果可以看出,比to 缺少一個(gè)inclusive,表示不包含最右邊這個(gè)數(shù)
to 是左閉右閉的集合 從結(jié)果可以看出,比Range,until多一個(gè)inclusive,表示包含最右邊這個(gè)數(shù)

遍歷

  1. 遍歷列表
foreach 對前面的集合中的每一個(gè)元素都要執(zhí)行一次這樣的操作
Array("Hadoop","Spark","Hive","Flink").foreach(x=>println(x))
或者
for(x<-Array("Hadoop","Spark","Hive","Flink")){
      println(x)
}
含有判斷條件的遍歷:
for(i<- 1 to 10 if(i%2 == 0)){
      println(i)
}

默認(rèn)參數(shù)

在方法中,有的參數(shù)有一個(gè)默認(rèn)值,這個(gè)參數(shù)為默認(rèn)參數(shù),在調(diào)用擁有默認(rèn)參數(shù)的方法時(shí),需要帶上括號,可以不傳參數(shù)

def sayName(name:String="xiaoyao"): Unit ={
    println(name)
}

命名參數(shù)

就是指定參數(shù)的名稱。

def speed(distance:Float,time:Float)={
    distance/time
}
調(diào)用時(shí),下面兩種方式都可以
println(speed(100,5))
println(speed(distance = 100,time = 5))

可變參數(shù)

可以有任意個(gè)數(shù)的參數(shù)。

def sum(argv:Int*) ={
    var result = 0
    for (element<- argv){
      result+=element
    }
    result
}
調(diào)用方式為:
println(sum(3,4))
println(sum(3,4,5))
println(sum(1 to 10 : _*))  

在scala中使用class作為關(guān)鍵字,定義相應(yīng)的類。在定義屬性時(shí),可以使用占位符來定義變量,必須要指定類型:

val name:String=_

屬性私有化:

private[this] var gender="male"

Scala注意事項(xiàng)

  1. 在Scala中聲明private變量,Scala編譯器會(huì)自動(dòng)生成get,set方法
  2. 在Scala中變量需要初始化
  3. 在Scala中沒有靜態(tài)修飾符,在object下的成員全部都是靜態(tài)的,如果在類中聲明了與該類相同的名字的object則該object是該類的”伴生對象”
    可以理解為Scala把類中的static集中放到了object對象中,伴生對象和類文件必須是同一個(gè)源文件,可以用伴生對象做一些初始化操作.
  4. 在Java中可以通過interface實(shí)現(xiàn)多繼承,在Scala中可以通過特征(trait)實(shí)現(xiàn)多重繼承,但是與Java不同的是,它可以定義自己的屬性和實(shí)現(xiàn)方法體
  5. object不能提供構(gòu)造器參數(shù),也就是說object必須是無參的

Object和Class的區(qū)別

  1. 在Scala中,類名可以和對象名為同一個(gè)名字,該對象稱為該類的伴生對象,類和伴生對象可以相互訪問他們的私有屬性,但是它們必須在同一個(gè)源文件中
  2. 類只會(huì)被編譯,不能直接執(zhí)行,類的聲明和主構(gòu)造器在一起被聲明,在一個(gè)類中,主構(gòu)造器只有一個(gè).
  3. 類和它的伴生對象可以相互訪問其私有成員
  4. class和object的一個(gè)差別是,object里面的屬性或者方法都是單例的,單例對象不帶參數(shù),而類可以.因?yàn)槟悴荒苡胣ew關(guān)鍵字實(shí)例化一個(gè)單例對象,你沒有機(jī)會(huì)傳遞給它參數(shù)
  5. object在調(diào)用時(shí),按照從上到下依次執(zhí)行,不調(diào)用的方法不執(zhí)行。object中的方法或者屬性可以通過object.method/object.properties, 不需要通過new方式獲取對象。
  6. class要獲取對象必須使用new方式,然后才能調(diào)用方法或者屬性,object不需要。

  7. 互為伴生對象+() 調(diào)用對象的apply方法,并且創(chuàng)建class實(shí)例。
(例如:var b=ApplyTest() // oject ApplyTest.apply())

8.如果為class實(shí)例+(),調(diào)用類自己的apply方法。

例如:
var c=new ApplyTest
println(c)
c()  //class apply

參考自:https://blog.csdn.net/qq_33813365/article/details/77869661

屬性

  1. 在類中需要定義一些屬性,一般使用var來進(jìn)行定義,在定義時(shí),有時(shí)候沒有默認(rèn)值,需要使用占位符來表示,并且要表明屬性的類型,否則會(huì)報(bào)錯(cuò)
  2. 私有屬性:只能在類內(nèi)部訪問,不能通過創(chuàng)建對象的方式來訪問私有屬性。
定義屬性
var name:String=_
// var name="doudou"
定義私有屬性
//private[this]不允許其他對象訪問,對象私有,只能這個(gè)對象訪問,這個(gè)對象的類中的方法也不可以訪問這個(gè)成員。其他對象中的方法也不可訪問。
private[this] var gender="male"

構(gòu)造器

  1. 在創(chuàng)建對象時(shí),使用關(guān)鍵字new時(shí),就是調(diào)用構(gòu)造函數(shù)的時(shí)候。
  2. 使用class來修飾的就是主構(gòu)造器,可以是有參也可以是無參。在主構(gòu)造器中可以創(chuàng)建附屬構(gòu)造器,也就是除了主構(gòu)造器之外的其他構(gòu)造器
  3. 附屬構(gòu)造器中的第一行必須是主構(gòu)造器或者其他附屬構(gòu)造器。每次實(shí)例化對象時(shí),都需要使用到主構(gòu)造器。

繼承

關(guān)鍵字為extends
1.在繼承時(shí),可以繼承主構(gòu)造器也可以繼承附屬構(gòu)造器。
2.在繼承時(shí),在主構(gòu)造器方法中擁有的屬性不是父類的屬性,需要使用var來修飾這個(gè)屬性。
3.如果需要對屬性或者方法進(jìn)行重寫,需要使用關(guān)鍵字override,來進(jìn)行重寫屬性或者函數(shù)。在重寫屬性時(shí),需要將屬性使用val來進(jìn)行定義。

抽象類

1.抽象類中一個(gè)或者多個(gè)方法只有定義沒有實(shí)現(xiàn)(方法體)。
2.抽象類不能直接使用,必須要有具體的實(shí)現(xiàn)類。

集合

Array

1.概念
數(shù)組是定長的一個(gè)集合,在創(chuàng)建的時(shí)候已經(jīng)確定整個(gè)數(shù)組的長度,不能進(jìn)行增加或者減少,只能在原先的數(shù)據(jù)上進(jìn)行操作。
在定義數(shù)組時(shí),如果沒有進(jìn)行賦值時(shí),默認(rèn)為數(shù)組類型的默認(rèn)值,數(shù)組的索引是從0開始的,一直到數(shù)組長度減去1,即[0,Array.length-1)。
如果下標(biāo)不再這個(gè)范圍時(shí),會(huì)輸出java.lang.ArrayIndexOutOfBoundsException異常。
元素可以重復(fù),元素類型都一樣

1.1定義固定長度的數(shù)組

var array=new Array[String](5) //數(shù)組元素的類型為string,默認(rèn)值為null,數(shù)組的長度為5。

1.2定義擁有初始化值的數(shù)組

var array=Array(0,0,0,0,0) //等同于上面的定義操作,在創(chuàng)建時(shí)調(diào)用apply方法,會(huì)自動(dòng)創(chuàng)建相應(yīng)的長度的array,并將值復(fù)制到相應(yīng)位置。 

2.操作

2.1數(shù)組長度

scala> var array=new Array[Int](5)
scala> array.length
res0: Int = 5

2.2更新元素

使用下標(biāo)更新數(shù)據(jù)
array(2)=2
array(2,5)

2.3最值

array.max
array.min

2.4求和

array.sum

2.5拼接

scala> array.mkString(",")
res11: String = 0,5,2,3,4
也可以指定開始和結(jié)束的符號,中間使用什么進(jìn)行連接
scala> array.mkString("[",",","]")
res12: String = [0,5,2,3,4]

2.6最后一個(gè)元素

array.last

2.7變成vector

println(array.to)

2.8是否包含

array.contains(2) //包含 true,不包含 false

2.8反轉(zhuǎn)

array.reverse.mkString(",) 

2.9 合并兩個(gè)數(shù)組

Array.concat(array,b.toArray).mkString(",")

2.10 判斷是否為空

array.isEmpty
array.nonEmpty

2.11拷貝數(shù)據(jù)到其他數(shù)組中

Array.copy(array,1,b.toArray,1,2)

2.12 生成一個(gè)數(shù)組

Array.range(1,5)
Array.range(1,5,2) //步長默認(rèn)為1

2.13生成一個(gè)空的數(shù)組

Array.empty  //也可以指定參數(shù)類型

ArrayBuffer

1.概念
ArrayBuffer是一個(gè)變長的數(shù)據(jù),就是長度不固定,可以動(dòng)態(tài)的增加或者刪除元素。
元素可以重復(fù)。

2.操作

2.1添加元素

//增加單個(gè)元素
scala> var b=ArrayBuffer[Int]()
b: scala.collection.mutable.ArrayBuffer[Int] = ArrayBuffer()
scala> b+=1
res13: scala.collection.mutable.ArrayBuffer[Int] = ArrayBuffer(1)
//增加多個(gè)元素,使用++來進(jìn)行操作
scala> b++=Array(6,7,8)
res15: scala.collection.mutable.ArrayBuffer[Int] = ArrayBuffer(1, 6, 7, 8)
scala> b++=ArrayBuffer(6,7,8)
res16: scala.collection.mutable.ArrayBuffer[Int] = ArrayBuffer(1, 6, 7, 8, 6, 7, 8)
//使用insert 可以指定插入的位置,可以同時(shí)插入多個(gè)元素,在指定的下標(biāo)之后插入
scala> b.insert(1,6,7)
scala> b
res26: scala.collection.mutable.ArrayBuffer[Int] = ArrayBuffer(1, 6, 7, 2, 3, 4, 5)
//append
scala> b.append(6)
scala> b
res45: scala.collection.mutable.ArrayBuffer[Int] = ArrayBuffer(4, 1, 2, 3, 4, 5, 6)

2.2刪除元素

//刪除單個(gè)元素
scala> b-=1
res13: scala.collection.mutable.ArrayBuffer[Int] = ArrayBuffer(6,7,8)
scala> b--=Array(6,7,8)
res15: scala.collection.mutable.ArrayBuffer[Int] = ArrayBuffer(6, 7, 8)
scala> b--=ArrayBuffer(6,7,8)
res16: scala.collection.mutable.ArrayBuffer[Int] = ArrayBuffer()
//使用remove執(zhí)行操作,可以移除指定下標(biāo)的值,或者從當(dāng)前下標(biāo)開始往后的幾個(gè)元素
scala> b.remove(1)
res28: Int = 6
scala> b
res29: scala.collection.mutable.ArrayBuffer[Int] = ArrayBuffer(1, 7, 2, 3, 4, 5)
scala> b.remove(1,3)
scala> b
res31: scala.collection.mutable.ArrayBuffer[Int] = ArrayBuffer(1, 4, 5)
//使用trimEnd(從最右邊開始數(shù)幾個(gè)數(shù)移除)或者trimStart(從最左邊開始數(shù)幾個(gè)數(shù)移除),他們的底層實(shí)現(xiàn)為remove
scala> b.trimEnd(1)
scala> b
res33: scala.collection.mutable.ArrayBuffer[Int] = ArrayBuffer(1, 4)
scala> b.trimStart(1)
scala> b
res35: scala.collection.mutable.ArrayBuffer[Int] = ArrayBuffer(4)

2.3拼接

與Array相同,請參考上面的操作。

2.4獲取數(shù)據(jù)

//從左邊開始,取幾個(gè)數(shù)據(jù)
scala> b.take(2)
res39: scala.collection.mutable.ArrayBuffer[Int] = ArrayBuffer(4, 1)
//取后邊幾個(gè)數(shù)據(jù)
scala> b.takeRight(3)
res41: scala.collection.mutable.ArrayBuffer[Int] = ArrayBuffer(3, 4, 5)

2.5轉(zhuǎn)換為array

scala> b.toArray
res43: Array[Int] = Array(4, 1, 2, 3, 4, 5)

2.6 tail

//獲取除了第一個(gè)元素之外的所有元素
scala> b.tail
res42: scala.collection.mutable.ArrayBuffer[Int] = ArrayBuffer(1, 2, 3, 4, 5)

2.7遍歷

//遍歷
for(element<-b){
      println(b)
}

2.8獲取數(shù)據(jù)的索引

b.indexOf(2) //從左側(cè)開始數(shù)
b.lastIndexOf(3) //上次出現(xiàn)的位置

2.9長度比較

b.lengthCompare(4) // result 1 b的長度比后面的數(shù)大
b.lengthCompare(5) // result 0 b的長度與后面的數(shù)相等
b.lengthCompare(6) // result -1 b的長度比后面的數(shù)小

2.10最后一個(gè)值

b.last //數(shù)組的最后一個(gè)元素

2.11變成vector

println(b.to)

2.12是否包含某個(gè)元素

b.contains(2) //包含 true,不包含 false

2.13反轉(zhuǎn)

b.reverse.mkString(",") 

2.14其他操作
最大值、最小值、求和、以及拼接都與Array操作一樣,不再贅述。

列表

List

  1. 概念

List

a.不可變鏈?zhǔn)降臄?shù)據(jù)結(jié)構(gòu)存儲(chǔ)有序數(shù)據(jù),
b.遵循后進(jìn)先出原則(棧),
c.訪問頭尾時(shí)間復(fù)雜度為1,其他元素為0(n),
d.結(jié)構(gòu)共享,不需要或者需要固定長度的內(nèi)容

2.操作

2.1不使用List構(gòu)建一個(gè)List對象

Nil  
//定義list對象
var l=List(1,2,3,4,5)
var l1=1 :: Nil  //List(1)
var l2=2 :: l1  //List(2,1) //將前面的元素放在最前面,把后面的元素放入到后面

2.2第一個(gè)元素

l.head //1

2.3后面的元素

l.tail //除了第一個(gè)之外后面的所有元素,List(2,3,4,5)

ListBuffer

1.操作
1.1添加元素

scala> lb+=(6,7,8)
res8: scala.collection.mutable.ListBuffer[Int] = ListBuffer(1, 2, 3, 4, 5, 6, 7, 8)
//如果是增加不可變集合,需要使用兩個(gè)加號
scala> lb++=List(9,10)
res10: scala.collection.mutable.ListBuffer[Int] = ListBuffer(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)

1.2轉(zhuǎn)成不可變List

scala> lb.toList
res11: List[Int] = List(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)

1.3轉(zhuǎn)成不可變Array

scala> lb.toArray
res12: Array[Int] = Array(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)

1.4求和

def sum(nums:Int*):Int ={
    if(nums.length==0) {
      0
    }else{
      nums.head + sum(nums.tail : _*) //后面這一步是將list變成可變參數(shù)
    }
}

Map

1.定義

var a=Map("name"->"xiaoyao","age"->30) //不可以修改值
var b=scala.collection.mutable.Map("name"->"xiaoyao","age"->30)

1.2獲取值

println(b.getOrElse("gender","unknown")) //如果沒有key,可以輸出后面的值,使用b.get("gender")來如果沒有值,獲取None對象,如果有值獲取Some對象,或者使用b("name")直接獲取值

1.3遍歷數(shù)據(jù)

//遍歷
for((key,value)<-b){
  println(key+":"+value)
}
for((key,_)<-b){
  println(key+":"+b.getOrElse(key,0))
}
for(key<-b.keySet){
  println(key+":"+b.getOrElse(key,0))
}
for(value<-b.values){
  println(value)
}

算子操作

map

map操作是對每一個(gè)元素進(jìn)行相同的操作

var l=List(1,2,3,4,5,6,7,8)
for(element<-l){
  println(element)
}
//對集合中的每一個(gè)元素都執(zhí)行相同的操作
println(l.map((x:Int)=>x*2))
println(l.map((x)=>x*2))
println(l.map(x=>x*2))
println(l.map(_ * 2))

foreach

//對每一個(gè)元素進(jìn)行遍歷
l.map(_*2).foreach(x=>println(x))
l.foreach(x=>println(x))

filter

//對元素進(jìn)行過濾
println(l.map(_*2).filter(_>8))

take

//獲取多少個(gè)元素,必須要指定獲取前n個(gè)元素,后面這個(gè)值必須要填寫
println(l.take(3))

sum

println(l.sum)

reduce

//將相鄰的兩個(gè)數(shù)據(jù)進(jìn)行操作
//(1,2,3,4,5,6,7,8)=>(3,3,4,5,6,7,8)=>(6,4,5,6,7,8)=>(10,5,6,7,8)=>(15,6,7,8)=>(21,7,8)=>(28,8)=>(36)
l.reduce((x,y)=>{
  println(x,y)
  x+y
})
println(l.reduceLeft(_+_))
//(1,2,3,4,5,6,7,8)=>(3,3,4,5,6,7,8)=>(6,4,5,6,7,8)=>(10,5,6,7,8)=>(15,6,7,8)=>(21,7,8)=>(28,8)=>(36)
l.reduceLeft((x,y)=>{
  println(x,y)
  x+y
})
println(l.reduceRight(_+_))
//(1,2,3,4,5,6,7,8)=>(1,2,3,4,5,6,15)=>(1,2,3,4,5,21)=>(1,2,3,4,26)=>(1,2,3,30)=>(1,2,33)=>(1,35)=>(36)
l.reduceRight((x,y)=>{
  println(x,y)
  x+y
})
println(l.reduce(_-_))
//(1,2,3,4,5,6,7,8)=>(-1,3,4,5,6,7,8)=>(-4,4,5,6,7,8)=>(-8,5,6,7,8)=>(-13,6,7,8)=>(-19,7,8)=>(-26,8)=>(-34)
l.reduce((x,y)=>{
  println(x,y)
  x-y
})
println(l.reduceLeft(_-_)) //(1,2,3,4,5,6,7,8)=>(-1,3,4,5,6,7,8)=>(-4,4,5,6,7,8)=>(-8,5,6,7,8)=>(-13,6,7,8)=>(-19,7,8)=>(-26,8)=>(-34)
//詳細(xì)步驟
l.reduceLeft((x,y)=>{
  x-y
})
println(l.reduceRight(_-_)) //(1,2,3,4,5,6,7,8)=>(1,2,3,4,5,6,-1)=>(1,2,3,4,5,7)=>(1,2,3,4,-2)=>(1,2,3,6)=>(1,2,-3)=>(1,5)=>(-4)
//詳細(xì)步驟
l.reduceRight((x,y)=>{
  println(x+":"+y)
  x-y
})

curry(顆?;?

def sum(a:Int,b:Int)=a+b
//顆?;?def add(a:Int)(b:Int)=a+b
sum(a:Int,b:Int)=add(a:Int)(b:Int)

fold

println("---fold---")
println(l.fold(1)(_+_))   //兩個(gè)括號連著,就是表示兩個(gè)參數(shù)求和,第一個(gè)括號的值可以理解為初始值,加上后面的參數(shù),如果是foldleft,是將這個(gè)數(shù)放到最左邊,如果是foldright,將這個(gè)數(shù)據(jù)放到最右邊
//運(yùn)算規(guī)則(1,1,2,3,4,5,6,7,8)=>(2,2,3,4,5,6,7,8)=>(4,3,4,5,6,7,8)=>(7,4,5,6,7,8)=>(11,5,6,7,8)=>(16,6,7,8)=>(22,7,8)=>(29,8)=>(37)
println("---foldleft+---")
l.foldLeft(1)((x,y)=>{
  println(x,y)
  x+y
})
println("---foldRight+---")
//運(yùn)算規(guī)則(1,2,3,4,5,6,7,8,1)=>(1,2,3,4,5,6,7,9)=>(1,2,3,4,5,6,16)=>(1,2,3,4,5,22)=>(1,2,3,4,27)=>(1,2,3,31)=>(1,2,34)=>(1,36)=>(37)
l.foldRight(1)((x,y)=>{
  println(x,y)
  x+y
})
println("---foldminus---")
println(l.fold(1)(_-_))   //(1,1,2,3,4,5,6,7,8)=>(0,2,3,4,5,6,7,8)=>(-2,3,4,5,6,7,8)=>(-5,4,5,6,7,8)=>(-9,5,6,7,8)=>(-14,6,7,8)=>(-20,7,8)=>(-27,8)=>(-35)
l.fold(1)((x,y)=>{
  println(x,y)
  x-y
})
println("---foldrightminus---")
//(1,2,3,4,5,6,7,8,1)=>(1,2,3,4,5,6,7,7)=>(1,2,3,4,5,6,0)=>(1,2,3,4,5,6)=>(1,2,3,4,-1)=>(1,2,3,5)=>(1,2,-2)=>(1,4)=>(-3)
println(l.foldRight(1)(_-_))
l.foldRight(1)((x,y)=>{
  println(x,y)
  x-y
})
println("---foldleftminus---")
println(l.foldLeft(1)(_-_))
//(1,1,2,3,4,5,6,7,8)=>(0,2,3,4,5,6,7,8)=>(-2,3,4,5,6,7,8)=>(-5,4,5,6,7,8)=>(-9,5,6,7,8)=>(-14,6,7,8)=>(-20,7,8)=>(-27,8)=>(-35)
l.foldLeft(1)((x,y)=>{
  println(x,y)
  x-y
})
//reduce操作,默認(rèn)從左邊開始進(jìn)行加或者減,即前兩個(gè)數(shù)進(jìn)行相加或者相減,依次往后推進(jìn),直到只有一個(gè)數(shù)據(jù)。
//reduceLeft 與reduce操作一致,不再贅述。
//reduceRight 從右邊開始往左方向走,先取追右邊的兩個(gè)數(shù),進(jìn)行相加或者相減,依次往左執(zhí)行,直到只有一個(gè)數(shù)據(jù)
//fold()()是一個(gè)顆?;僮鳎喈?dāng)于將兩個(gè)參數(shù)進(jìn)行相加(減);加(減)操作是把第一個(gè)參數(shù)放在最前面,從左往后加(減),依次進(jìn)行相加(減),直到只有一個(gè)數(shù);
//foldleft()()與fold操作一致
//foldright()()是要將第一個(gè)參數(shù)放到后面;從右往左進(jìn)行操作,直到只有一個(gè)數(shù)。

sum,max,min,count

println(l.min+":"+l.max+":"+l.sum)
//可以對數(shù)據(jù)進(jìn)行過濾
println(l.count(_>5))

flatmap

var f=List(List(1,2),List(3,4),List(5,6))
//將多個(gè)集合中的元素放入到一個(gè)集合中
println(f.flatten)
//flatmap=map+flatten
//flatmap是元素放到一個(gè)集合中,然后在進(jìn)行操作
println(f.flatMap(_.map(_*2)))
//map是針對元素的操作
println(f.map(_.map(_*2)))

文件操作

//讀取文件
val file=Source.fromFile("/Users/Downloads/test/people.txt")
for(line<-file.getLines()){
  println(line)
}
//指定url
Source.fromURL("")

隱士轉(zhuǎn)換

動(dòng)態(tài)增強(qiáng)類的功能。

//1.定義一個(gè)類
class RichFile(val file:File){
  def read()=Source.fromFile(file.getPath).mkString
}
//2.編寫隱士轉(zhuǎn)換的方法
implicit  def file2rich(file:File):RichFile=new RichFile(file)
//3.調(diào)用
val file=new File("/Users/Downloads/test/people.txt")
val content=file.read()
println(content)

模式匹配

val peoples=Array("xiaoyao","yishengxiaoyao","xiaoyaoyisheng","xiaoyaoshan")
val people=peoples(Random.nextInt(peoples.length))
people match {
  case "xiaoyao" => println("xiaoyao")
  case "yishengxiaoyao" => println("yishengxiaoyao")
  case "xiaoyaoyisheng" => println("xiaoyaoyisheng")
  case "xiaoyaoshan" => println("xiaoyaoshan")
    //沒有匹配到的選項(xiàng)
  case _ => println("no match")
}
greeting(Array("zhangsan")) //Hello zhangsan!
greeting(Array("li","wangwu")) //Hello li,wangwu!
greeting(Array("zhangsan","li","wangwu")) //Hello zhangsan and others!
greeting(Array("li","wangwu","zhangsan")) //Welcome!
def greeting(array: Array[String]): Unit ={
array match {
  case Array("zhangsan") => println("Hello zhangsan!")
  case Array(x,y) => println(s"Hello $x,$y!")
  case Array("zhangsan",_*) => println("Hello zhangsan and others!")
  case _ => println("Welcome!")
}
}

異常處理

try{
  val i=1/0
}catch {
  case e:ArithmeticException => println("除數(shù)不能為0!")
  case e:Exception => println("捕獲到異常!")
}finally {
  println("the finally module")
}

偏函數(shù)

def greetMan(name:String)= name match {
case "zhangsan" => println("Hello zhangsan!")
case "xiaoyao" => println("Hello xiaoyao!")
case _ => println("Welcome!")
}

/**
* 花括號內(nèi)沒有match的一組case就是一個(gè)偏函數(shù)
* 第一參數(shù)為輸入值的類型,第二個(gè)是輸出值的類型
*/
def greetManPartial:PartialFunction[String,String]={
case "zhangsan" => "Hello zhangsan!"
case "xiaoyao" => "Hello xiaoyao!"
case _ => "Welcome!"
}
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容