柚子快報(bào)激活碼778899分享:開(kāi)發(fā)語(yǔ)言 Scala學(xué)習(xí)
柚子快報(bào)激活碼778899分享:開(kāi)發(fā)語(yǔ)言 Scala學(xué)習(xí)
Scala
1、基礎(chǔ)知識(shí)
/**
* 變量:在程序的運(yùn)行過(guò)程中,其值可以發(fā)生改變的量
* 在scala中定義一個(gè)變量,需要使用一個(gè)關(guān)鍵詞:var
*
* 常量:在程序的運(yùn)行過(guò)程中,其值不可以發(fā)生改變的量
* 在scala中定義一個(gè)變量,需要使用一個(gè)關(guān)鍵詞:val
*
* 注意:
* 1、變量一旦定義,它的類(lèi)型就確定,可以不用手動(dòng)指定類(lèi)型,根據(jù)賦的值自動(dòng)推斷出類(lèi)型
* 2、也可以手動(dòng)的指定變量的數(shù)據(jù)類(lèi)型,完整的寫(xiě)法:var 變量名:數(shù)據(jù)類(lèi)型 = 值
*
* scala中的數(shù)據(jù)類(lèi)型和java的數(shù)據(jù)類(lèi)型對(duì)應(yīng)關(guān)系:
* java: scala:
* byte Byte
* short Short
* int Int
* long Long
* float Float
* double Double
* boolean Boolean
* char Char
*/
* 其實(shí)是一個(gè)函數(shù),底層是通過(guò)StringBuilder鏈接字符的
/**
* scala中字符串的使用
* 字符串:由若干個(gè)字符組成的序列
*/
查看變量數(shù)據(jù)類(lèi)型
var a = 100
println(a)
println(a.getClass)
100
int
200
Scala 中使用三重雙引號(hào) (""") 定義的多行字符串,并且使用 stripMargin 方法去除每行開(kāi)頭的垂直線。這種方式在處理 SQL 查詢(xún)語(yǔ)句等多行字符串時(shí)非常常見(jiàn)。
var d:String =
"""
|select
|*
|from
|pf
|""".stripMargin
println(d)
select
*
from
pf
java中String類(lèi)中的功能在scala中正常使用
var e = "python,java,scala,spark"
val arr: Array[String] = e.split(",")
//簡(jiǎn)式寫(xiě)法 val arr: Array[String] = e split ","
println(arr)
println("=" * 50)
//scala中的數(shù)組和java中的數(shù)組一樣,也是有索引的,也是從0開(kāi)始的 注意:索引使用小括號(hào)括住
println(arr(0))
println(arr(1))
println(arr(2))
println(arr(3))
[Ljava.lang.String;@36d64342
==================================================
python
java
scala
spark
/**
* 在scala中字符串是如何做拼接的?
* 1、使用+號(hào)拼接 這種拼接方式比較消耗性能
* 2、使用StringBuilder
* 3、前提:有一組序列,使用scala特有的函數(shù) mkString
* 4、使用scala特有的字符串傳遞方式 s"${變量}" 底層就是使用StringBuilder方式拼接的
*/
var res1 = a1 + "," + a2 + "," + a3
println(res1)
val res2 = new StringBuilder()
res2.append(a1).append("-").append(a2).append("-").append(a3)
println(res2)
val res3: String = arr.mkString("&")
println(res3)
val res4 = s"${a1}#${a2.toUpperCase()}#${a3.toUpperCase}"
println(res4)
I,love,you
I-love-you
python&java&scala&spark
I#LOVE#YOU
Scala只能讀文件,不能寫(xiě)文件
//讀取文件
val bs: BufferedSource = Source.fromFile("scala/data/words.txt")
val iterator: Iterator[String] = bs.getLines()
while (iterator.hasNext){
val str: String = iterator.next()
println(str)
}
//使用for循環(huán)遍歷文件內(nèi)容
for (e <- iterator){
println(e)
}
hello|world
java|hadoop|linux
java|scala|hadoop
hive|java|hello|world
2、異常
scala中的異常和java的很像
package com.shujia.jichu
import java.io.{BufferedReader, FileNotFoundException, FileReader}
import java.util.Scanner
object Demo4Exception {
def main(args: Array[String]): Unit = {
/**
* scala中的異常和java的很像
*/
try{
println(10/0)
val arr: Array[Int] = Array(1, 2, 3, 4, 5)
println(arr(5))
val br: BufferedReader = new BufferedReader(new FileReader("scala/data/words888.txt"))
/**
* 也可以手動(dòng)的拋出異常
*/
val scanner = new Scanner(System.in)
print("請(qǐng)輸入一個(gè)除數(shù):")
val i: Int = scanner.nextInt()
if(i!=0){
println(10/i)
}else{
throw new ArithmeticException("你輸入的除數(shù)為0")
//自己拋出的異常也會(huì)被下面的cath所捕獲,且系統(tǒng)的錯(cuò)誤提示為自己定義拋出的
}
}catch {
//類(lèi)似于sql語(yǔ)句中case when
case e:ArithmeticException=>
e.printStackTrace() //系統(tǒng)的錯(cuò)誤提示
//println("除0異常") //自定義錯(cuò)誤提示
case e:ArrayIndexOutOfBoundsException=>
println("數(shù)組越界異常")
case e:FileNotFoundException=>
println("系統(tǒng)找不到指定的文件")
//在Scala的模式匹配中,_ 符號(hào)通常用作通配符,表示匹配任何值。因此,case _ => 會(huì)捕獲所有未被前面具體case語(yǔ)句匹配的情況。
//當(dāng)該語(yǔ)句放到最前面時(shí)則可匹配到任何異常,無(wú)法去下面找到具體的異常
case _=>
println("出現(xiàn)異常")
}finally {
//今后finally中的處理大部分情況下都與釋放資源有關(guān)
println("這是finall代碼塊")
}
//當(dāng)捕獲到異常后才能正常打印,否則不能打印。當(dāng)try代碼有多個(gè)錯(cuò)誤時(shí),當(dāng)?shù)谝粋€(gè)錯(cuò)誤被捕獲時(shí)就不會(huì)執(zhí)行下面有錯(cuò)誤的代碼了
println("hello world")
}
}
3、函數(shù)
函數(shù)特點(diǎn)
/**
* def: 定義函數(shù)或者方法的關(guān)鍵字
* main: 是函數(shù)或者方法的名字,符合標(biāo)識(shí)符的命名規(guī)則
* args: 函數(shù)形參的名字
* Array[String]: 參數(shù)的數(shù)據(jù)類(lèi)型是一個(gè)元素為字符串的數(shù)組
* =: 后面跟著函數(shù)體
* Unit: 等同于java中的void 表示無(wú)返回值的意思
* 在不同的地方定義,稱(chēng)呼不一樣
* 函數(shù):在object中定義的叫做函數(shù)
* 方法:在class中定義的叫做方法
* scala中調(diào)用函數(shù)必須在函數(shù)定義之后
*調(diào)用類(lèi)里的方法必須要用類(lèi)的對(duì)象調(diào)用
*/
def main(args: Array[String]): Unit = {
//函數(shù)體
}
函數(shù)的定義
//定義格式一:如果函數(shù)有返回值,且最后一句話作為返回值的話return可以不寫(xiě)
def add3(a: Int,b: Int): Int = {
a + b
}
//定義格式二:如果函數(shù)體只有一句話大括號(hào)也可以不寫(xiě)
def add4(a: Int,b: Int): Int = a + b
//定義格式三:如果函數(shù)沒(méi)有參數(shù)時(shí)小括號(hào)也可以不寫(xiě)
def show = println("鵬飛是飛蓬大將軍")
函數(shù)的調(diào)用
//調(diào)用方式一:Object中的函數(shù)可以使用列名調(diào)用,類(lèi)似于靜態(tài)方法一樣
val res4: Int = Demo5Function.add(20, 30)
println(res4)
//調(diào)用形式2:object中的函數(shù)調(diào)用時(shí),可以省略類(lèi)名
val res4: Int = add(20, 30)
println(res4)
Scala中的遞歸
object Demo6Function {
/**
* scala中的函數(shù)也可以遞歸
* 方法定義時(shí),調(diào)用自身的現(xiàn)象
* 條件:要有出口,不然就是死遞歸
*/
def main(args: Array[String]): Unit = {
val res: Int = jieCheng(5)
//當(dāng)只有一個(gè)變量時(shí)可以省去大括號(hào)
println(s"5的階乘是:$res")
//當(dāng)調(diào)用的方法只有一個(gè)參數(shù)時(shí)
println(s"5的階乘是:${Demo6Function jieCheng 5}")
}
//求出5的階乘
def jieCheng(number: Int): Int = {
if(number == 1){
1
}else{
number * jieCheng(number - 1)
}
}
}
scala中的類(lèi)與構(gòu)造方法
class Student(name: String,age: Int){
//當(dāng)創(chuàng)建對(duì)象時(shí)自動(dòng)打印,相當(dāng)于對(duì)象的初始化
println("鵬飛你好牛啊")
/**
* 定義成員變量
*/
val _name: String = name
val _age: Int = age
var _gender: String = _ 這個(gè)下劃線其實(shí)就是起到一個(gè)占位的作用,就表示將來(lái)會(huì)賦予默認(rèn)值
/**
* 構(gòu)造方法也可以寫(xiě)多個(gè)
*/
//在Scala中,一個(gè)輔助構(gòu)造函數(shù)(auxiliary constructor)可以通過(guò)調(diào)用同一個(gè)類(lèi)的其他構(gòu)造函數(shù)來(lái)初始化對(duì)象。
// 您嘗試調(diào)用了另一個(gè)構(gòu)造函數(shù) this(name: String, age: Int),這是合法的用法,用來(lái)避免代碼重復(fù)。
def this(name: String,age: Int,gender: String){
this(name: String,age: Int)
_gender = gender
}
/**
* 也可以重寫(xiě)方法
*/
override def toString: String = {
"姓名:" + _name + "," + "年齡:" + _age + "," + "性別:" + _gender
}
}
//創(chuàng)建對(duì)象
val stu: Student = new Student("鵬飛", 18, "男")
println(stu)
姓名:鵬飛,年齡:18,性別:男
4、Scala樣例類(lèi)
/**
* scala提供了一個(gè)非常好用的功能:樣例類(lèi)
* 較少用戶(hù)創(chuàng)建類(lèi)所編寫(xiě)代碼量,只需要定義成員變量即可,自動(dòng)擴(kuò)充成員變量,構(gòu)造方法,重寫(xiě)toString方法
*/
package com.shujia.jichu
object Demo8CaseClass {
def main(args: Array[String]): Unit = {
val pf = new Teacher("鵬飛", 18, "刷百度")
println(pf)
println(pf.name)
println(pf.age)
println(pf.like)
//當(dāng)樣例類(lèi)定義的參數(shù)為可變參數(shù)時(shí),可以對(duì)該參數(shù)進(jìn)行修改
pf.like = "敲代碼"
println(pf)
}
}
case class Teacher(name: String,age: Int,var like: String)
Teacher(鵬飛,18,刷百度)
鵬飛
18
刷百度
Teacher(鵬飛,18,敲代碼)
scala的apply函數(shù)(當(dāng)創(chuàng)建對(duì)象是自動(dòng)調(diào)用該函數(shù))
object Demo9Apply {
def main(args: Array[String]): Unit = {
val book: Book = Book()
println(book)
}
}
object Book{
def apply(): Book = {
new Book("李白", 20)
}
}
class Book(name: String,price: Int){
val _name: String = name
val _price: Int = price
override def toString: String = "書(shū)名:" + _name + "," + "價(jià)格:" + _price
}
書(shū)名:李白,價(jià)格:20
5、Scala中函數(shù)式編程
/**
* scala中的函數(shù)式編程
*
* 面向?qū)ο缶幊蹋簩?duì)象當(dāng)作參數(shù)一樣傳來(lái)傳去
* 1、對(duì)象可以當(dāng)作方法參數(shù)傳遞
* 2、對(duì)象也可以當(dāng)作方法的返回值返回
* 當(dāng)看到類(lèi),抽象類(lèi),接口的時(shí)候,今后無(wú)論是參數(shù)類(lèi)型還是返回值類(lèi)型,都需要提供對(duì)應(yīng)的實(shí)現(xiàn)類(lèi)對(duì)象
*
* 面向函數(shù)式編程:將函數(shù)當(dāng)作參數(shù)一樣傳來(lái)傳去
* 1、函數(shù)A當(dāng)作函數(shù)B的參數(shù)進(jìn)行傳遞
* 2、函數(shù)A當(dāng)作函數(shù)B的返回值返回
*
* 在scala中,將函數(shù)也當(dāng)作一個(gè)對(duì)象,對(duì)象就有類(lèi)型
* 函數(shù)在scala也有類(lèi)型的說(shuō)法
* 參數(shù)類(lèi)型=>返回值類(lèi)型
*
*/
//是一個(gè)參數(shù)為字符串類(lèi)型,返回值是整數(shù)類(lèi)型的函數(shù)
def fun1(str: String): Int = {
str.toInt + 100
}
val res1: Int = fun1("100")
println(res1)//200
//將一個(gè)函數(shù) fun1 賦值給另一個(gè)變量 fun2,并且指定了 fun2 的類(lèi)型為 String => Int,使得fun2就有了fun1的處理邏輯
val fun2: String => Int = fun1
val res2: Int = fun2("300")
println(res2)//400
/**
* 函數(shù)A作為函數(shù)B的參數(shù)定義
* 本質(zhì)上是將函數(shù)A的處理邏輯主體傳給了函數(shù)B,在函數(shù)B中使用這個(gè)處理邏輯
*/
def fun1(f: String => Int): Int = {
val result: Int = f("100")
result + 100
}
def show1(s: String): Int = {
s.toInt
}
val res1: Int = fun1(show1)
println(res1)
def show2(s: String): Int = {
s.toInt + 100
}
val res2: Int = fun1(show2)
println(res2)
200
300
//當(dāng)函數(shù)的參數(shù)類(lèi)型為函數(shù)類(lèi)型時(shí),該函數(shù)參數(shù)可以使用另外一個(gè)參數(shù)
def fun2(s: String,f: String => Int): Int = {
val re: Int = f(s)
re + 100
}
def show3(s: String): Int = {
s.toInt
}
val res3: Int = fun2("100", show3)
println(res3)
200
//使用lambda表達(dá)式改寫(xiě)為函數(shù)類(lèi)型作為參數(shù)傳遞的調(diào)用形式
println(fun2("100",(s: String) => s.toInt))
println(fun2("100",(s: String) => s.toInt + 100))
200
300
//在scala中,數(shù)據(jù)類(lèi)型可以自動(dòng)類(lèi)型推斷因?yàn)楹瘮?shù)類(lèi)型在f中已經(jīng)定義了
fun2("2000", s => s.toInt+1000)
//如果當(dāng)作參數(shù)的函數(shù)的參數(shù)(s)只在函數(shù)主體(s.toInt+1000)使用了一次,那么可以使用_代替(該函數(shù)只有一個(gè)參數(shù)s)
fun2("2000", _.toInt + 1000)
當(dāng)函數(shù)作為返回值時(shí)
/**
* fun1: 參數(shù)是String類(lèi)型,返回值是一個(gè)函數(shù)(參數(shù)是String類(lèi)型,返回值是Int)
*/
//定義方式一
def fun1(s: String): String => Int = {
def show(s1: String): Int = {
s.toInt + s1.toInt
}
//在 Scala 中,當(dāng)你定義或引用一個(gè)函數(shù)時(shí),如果該函數(shù)沒(méi)有參數(shù)或者只有一個(gè)參數(shù),可以省略括號(hào)。
show
}
//定義方式二
def fun1(s: String)(s1: String): Int = {
s.toInt + s1.toInt
}
//調(diào)用方式一
val new_fun1: String => Int = fun1("10")
val res: Int = new_fun1("10")
val res3: Int = new_fun1("20")
val res4: Int = new_fun1("30")
println(res)//10
println(res1)
println(res2)
//調(diào)用方式二
val res2: Int = fun1("20")("20")
println(res2)//40
//調(diào)用方式三
val new_fun1: String => Int = fun1("10",_)
val res: Int = new_fun1("10")
6、集合
6.1、List
package com.shujia.jichu
object Demo14List {
def main(args: Array[String]): Unit = {
//特點(diǎn)元素有序,可以重復(fù),長(zhǎng)度固定
val list1: List[Int] = List(26, 78, 23, 89, 26, 66, 89, 26, 78, 45)
//獲取集合的長(zhǎng)度
println(list1.size)
println(list1.length)
println("="*50)
//可以通過(guò)索引獲取元素
println(list1(0))
println(list1(1))
println(list1(2))
println(list1(3))
println(list1(4))
println("="*50)
//獲取集合第一個(gè)元素和最后一個(gè)元素
println(list1.head)
println(list1.last)
println("="*50)
//指定分隔符來(lái)拼接集合中元素
println(list1.mkString("|"))
println("="*50)
//反轉(zhuǎn)集合,返回一個(gè)新的集合
val reverse_list1: List[Int] = list1.reverse
println(reverse_list1)
println("="*50)
//集合去重,返回一個(gè)新的集合
val distinct_list: List[Int] = list1.distinct
println(distinct_list)
println("="*50)
//返回集合,除第一個(gè)元素外的其他元素
val tail_list: List[Int] = list1.tail
println(tail_list)
println("="*50)
//從左邊取若干個(gè)元素
val take_list: List[Int] = list1.take(5)
println(take_list)
println("="*50)
//從右邊取若干個(gè)元素
val takeRight_list: List[Int] = list1.takeRight(5)
println(takeRight_list)
println("="*50)
//從集合第一個(gè)開(kāi)始判斷數(shù)據(jù),取符合條件的,遇到不符合條件的停止判斷
val filter_list: List[Int] = list1.takeWhile((e: Int) => e % 2 == 0)
println(filter_list)
println("="*50)
var ouSum: Int = 0
var jiSum: Int = 0
/**
* 高階函數(shù):
* foreach: 將集合中的元素依次取出傳入到后面的函數(shù)中
* 注意:沒(méi)有返回值的,要么就輸出,要么就其他方式處理掉了
*/
list1.foreach((e: Int) => {
if(e % 2 == 0){
ouSum += e
}else{
jiSum += e
}
})
println(s"list1集合中偶數(shù)和為:$ouSum")
println(s"list1集合中奇數(shù)和為:$jiSum")
println("="*50)
/**
* 高階函數(shù):
* map: 依次處理每一個(gè)元素,得到一個(gè)新的結(jié)果,返回到一個(gè)新的集合中
*/
val mapList: List[Int] = list1.map((e: Int) => e * 2)
println(mapList)
println("="*50)
/**
* 高階函數(shù):
* filter: 保留符合條件的元素
*/
val filterList: List[Int] = list1.filter((e: Int) => e % 2 == 0)
println(filterList)
println("="*50)
/**
* 高階函數(shù):
* sortBy: 排序
* sortWith: 兩個(gè)數(shù)之間的關(guān)系排序
*/
val sortByList: List[Int] = list1.sortBy((e: Int) => e)
println(sortByList)
println("="*50)
val sortWithSort: List[Int] = list1.sortWith((x: Int, y: Int) => x > y)
println(sortWithSort)
println("="*50)
/**
* 高階函數(shù):
* flatMap: 扁平化(一個(gè)變多個(gè))
*/
val list2: List[String] = List("hello|world|java", "hello|hadoop|flink", "scala|spark|hadoop")
val flatMapList: List[String] = list2.flatMap((e: String) => e.split("\\|"))
println(flatMapList)
println("="*50)
/**
* 高階函數(shù):
* groupBy: 分組
*/
val list3: List[String] = List("hello", "world", "java", "hadoop", "flink", "java", "hadoop", "flink", "flink", "java", "hadoop", "flink", "java", "hadoop", "hello", "world", "java", "hadoop", "hello", "world", "java", "hadoop")
val groupByList: Map[String, List[String]] = list3.groupBy((e: String) => e)
println(groupByList)
println("="*50)
}
}
10
10
==================================================
26
78
23
89
26
==================================================
26
45
==================================================
26|78|23|89|26|66|89|26|78|45
==================================================
List(45, 78, 26, 89, 66, 26, 89, 23, 78, 26)
==================================================
List(26, 78, 23, 89, 66, 45)
==================================================
List(78, 23, 89, 26, 66, 89, 26, 78, 45)
==================================================
List(26, 78, 23, 89, 26)
==================================================
List(66, 89, 26, 78, 45)
==================================================
List(26, 78)
==================================================
list1集合中偶數(shù)和為:300
list1集合中奇數(shù)和為:246
==================================================
List(52, 156, 46, 178, 52, 132, 178, 52, 156, 90)
==================================================
List(26, 78, 26, 66, 26, 78)
==================================================
List(23, 26, 26, 26, 45, 66, 78, 78, 89, 89)
==================================================
List(89, 89, 78, 78, 66, 45, 26, 26, 26, 23)
==================================================
List(hello, world, java, hello, hadoop, flink, scala, spark, hadoop)
==================================================
Map(world -> List(world, world, world), java -> List(java, java, java, java, java, java), flink -> List(flink, flink, flink, flink), hadoop -> List(hadoop, hadoop, hadoop, hadoop, hadoop, hadoop), hello -> List(hello, hello, hello))
6.2、Set集合
package com.shujia.jichu
object Demo15Set {
def main(args: Array[String]): Unit = {
/**
* set集合:scala中的Set集合也是不可變的,除了排序相關(guān)的函數(shù)以外,List集合有的高階函數(shù),Set集合也有
*/
//Set集合是無(wú)序的,但是它本身是自然排序
val set1: Set[Int] = Set(23, 89, 4, 433, 68)
val set2: Set[Int] = Set(23, 89, 45, 433, 6823)
println(s"set1集合的自然排序$set1")
println(s"set2集合的自然排序$set2")
//求交集
val jiaojiSet: Set[Int] = set1.intersect(set2)
println(jiaojiSet)
println("="*50)
//求并集
val bingjiSet: Set[Int] = set1 | set2
println(bingjiSet)
println("="*50)
//求差集
val chajiSet: Set[Int] = set1 &~ (set2)
println(chajiSet)
println("="*50)
/**
* Set集合和List集合能不能互相轉(zhuǎn)換?
* 可以的
* 業(yè)務(wù)對(duì)List集合中的元素去重
*/
val list: List[Int] = List(23, 67, 456, 78, 54, 98, 455, 67, 23, 85)
println(list)
val set: Set[Int] = list.toSet
println(set)
val newList: List[Int] = set.toList
println(newList)
}
}
set1集合的自然排序Set(89, 23, 433, 4, 68)
set2集合的自然排序Set(6823, 89, 45, 23, 433)
Set(89, 23, 433)
==================================================
Set(6823, 89, 45, 23, 433, 4, 68)
==================================================
Set(4, 68)
==================================================
List(23, 67, 456, 78, 54, 98, 455, 67, 23, 85)
Set(78, 85, 456, 54, 98, 455, 67, 23)
List(78, 85, 456, 54, 98, 455, 67, 23)
6.3、可變集合
package com.shujia.jichu
import scala.collection.mutable
import scala.collection.mutable.ListBuffer
import scala.collection.mutable.HashSet
object Demo16Mutable {
def main(args: Array[String]): Unit = {
/**
* 通過(guò)觀察api發(fā)現(xiàn),不可變的集合是屬于scala.collection.immutable包下的
* 如果將來(lái)想要使用可變的集合,就要去scala.collection.mutable包下尋找
*/
/**
* 這里的可變List集合,上午說(shuō)的功能函數(shù),這里都可以調(diào)用
* 創(chuàng)建一個(gè)可變的List集合ListBuffer
*/
val mutableList: ListBuffer[Int] = new ListBuffer[Int]
println(mutableList)
//添加元素
mutableList.+=(11)
mutableList.+=(12)
mutableList.+=(13)
mutableList.+=(13)
mutableList.+=(14)
mutableList.+=(15)
println(mutableList)
println("="*50)
//刪除元素(刪除第一個(gè)出現(xiàn)的)
mutableList.-=(13)
println(mutableList)
println("="*50)
//批量添加元素
mutableList.+=(66,77,88,99)
println(mutableList)
println("="*50)
//批量刪除元素
mutableList.-=(66,77,88,99)
println(mutableList)
println("="*50)
/**
* 可變的Set集合
*/
val hashSet = new mutable.HashSet[Int]()
println(hashSet)
hashSet.+=(33,45,89,23)
println(hashSet)
}
}
ListBuffer()
ListBuffer(11, 12, 13, 13, 14, 15)
==================================================
ListBuffer(11, 12, 13, 14, 15)
==================================================
ListBuffer(11, 12, 13, 14, 15, 66, 77, 88, 99)
==================================================
ListBuffer(11, 12, 13, 14, 15)
==================================================
Set()
Set(33, 45, 89, 23)
6.4、元組(Tuple)
package com.shujia.jichu
object Demo17Tuple {
def main(args: Array[String]): Unit = {
/**
* 大小,值是固定的,根據(jù)創(chuàng)建的類(lèi)來(lái)定,每個(gè)元素的數(shù)據(jù)類(lèi)型可以是不一樣,最高可以創(chuàng)建存儲(chǔ)22個(gè)元素的元組
*/
val tuple1: (Int, Int, Int, Int) = Tuple4(1, 2, 3, 4)
println(tuple1)
println("="*50)
val stu = new Stu("1001", "鵬飛大將軍", 18, "玩三國(guó)殺")
val tuple: (Int, Stu) = Tuple2(1001, stu)
println(tuple)
println(tuple._2.name)
}
}
case class Stu(id: String,name: String,age: Int,like: String)
(1,2,3,4)
==================================================
(1001,Stu(1001,鵬飛大將軍,18,玩三國(guó)殺))
鵬飛大將軍
6.5、Map集合
package com.shujia.jichu
object Demo18Map {
def main(args: Array[String]): Unit = {
//創(chuàng)建Map集合
//鍵是唯一的,鍵一樣的時(shí)候,值會(huì)被覆蓋
val map: Map[Int, String] = Map((1001, "張三"), (1002, "李四"), (1001, "趙六"), 1003 -> "琪琪")
println(map)
println("="*50)
//通過(guò)建獲取值
println(map(1001))
//通過(guò)小括號(hào)獲取時(shí),當(dāng)鍵不存在時(shí),會(huì)報(bào)錯(cuò)
// println(map(1004))
//通過(guò)get獲取時(shí),當(dāng)鍵不存在時(shí)會(huì)返回一個(gè)None
println(map.get(1004))
//根據(jù)鍵獲取值,若鍵不存在,返回提供的默認(rèn)值,默認(rèn)值的類(lèi)型可以是任意數(shù)據(jù)類(lèi)型
println(map.getOrElse(1004,"myself"))
//獲取所有的鍵,返回值為所有鍵組成的迭代器
val keys: Iterable[Int] = map.keys
for (e <- keys){
println(e)
}
println("="*50)
//獲取所有的值,返回值為所有值組成的迭代器
val values: Iterable[String] = map.values
for (e <- values){
println(e)
}
println("="*50)
//遍歷Map集合第一種方式,先獲取所有的鍵,根據(jù)鍵獲取每個(gè)值
for (e <- keys){
val value: String = map(e)
// val value: Option[String] = map.get(e)
// val value: Any = map.getOrElse(e, 0)
println(s"map集合的鍵為$e,對(duì)應(yīng)的值為$value")
}
println("="*50)
//遍歷Map集合第二種方式,直接遍歷map集合,得到每一個(gè)鍵值對(duì)組成的元組
for (kv <- map){
println(s"map集合的鍵為${kv._1},對(duì)應(yīng)的值為${kv._2}")
}
println("="*50)
//遍歷Map集合第三種方式,foreach
map.foreach((kv: (Int,String)) => println(s"map集合的鍵為${kv._1},對(duì)應(yīng)的值為${kv._2}") )
}
}
Map(1001 -> 趙六, 1002 -> 李四, 1003 -> 琪琪)
==================================================
趙六
None
myself
1001
1002
1003
==================================================
趙六
李四
琪琪
==================================================
map集合的鍵為1001,對(duì)應(yīng)的值為趙六
map集合的鍵為1002,對(duì)應(yīng)的值為李四
map集合的鍵為1003,對(duì)應(yīng)的值為琪琪
==================================================
map集合的鍵為1001,對(duì)應(yīng)的值為趙六
map集合的鍵為1002,對(duì)應(yīng)的值為李四
map集合的鍵為1003,對(duì)應(yīng)的值為琪琪
==================================================
map集合的鍵為1001,對(duì)應(yīng)的值為趙六
map集合的鍵為1002,對(duì)應(yīng)的值為李四
map集合的鍵為1003,對(duì)應(yīng)的值為琪琪
7、JDBC
package com.shujia.jichu
import java.sql.{Connection, Driver, DriverManager, PreparedStatement, ResultSet}
/**
* jdbc的連接步驟
* 1、注冊(cè)驅(qū)動(dòng)
* 2、創(chuàng)建數(shù)據(jù)庫(kù)連接對(duì)象
* 3、創(chuàng)建數(shù)據(jù)庫(kù)執(zhí)行對(duì)象
* 4、執(zhí)行Sql語(yǔ)句
* 5、如果有返回值的話,分析查詢(xún)結(jié)果結(jié)果
* 6、關(guān)閉連接對(duì)象
*/
object Demo20JDBC {
def main(args: Array[String]): Unit = {
//1、注冊(cè)驅(qū)動(dòng)
Class.forName("com.mysql.cj.jdbc.Driver")
//2、創(chuàng)建數(shù)據(jù)庫(kù)連接對(duì)象
//jdbc:數(shù)據(jù)庫(kù)名//host:port/數(shù)據(jù)庫(kù)?xxx=xxx&xxx=xxx
val conn: Connection = DriverManager.getConnection("jdbc:mysql://master:3306/demo01?useUnicode=true&characterEncoding=UTF-8&useSSL=false", "root", "123456")
//3、創(chuàng)建數(shù)據(jù)庫(kù)執(zhí)行對(duì)象
val statement: PreparedStatement = conn.prepareStatement("select id,name,age,gender,clazz from students where clazz=?")
//4、執(zhí)行sql語(yǔ)句
statement.setString(1,"理科一班")
val resultSet: ResultSet = statement.executeQuery()
//5、分析查詢(xún)結(jié)果
while (resultSet.next()){
val id: String = resultSet.getString("id")
val name: String = resultSet.getString("name")
val age: Int = resultSet.getInt("age")
val gender: String = resultSet.getString("gender")
val clazz: String = resultSet.getString("clazz")
println(s"學(xué)號(hào):$id, 姓名:$name, 年齡:$age, 性別:$gender, 班級(jí):$clazz")
}
//6、釋放資源
statement.close()
conn.close()
}
}
8、JSON
package com.shujia.jichu
import com.alibaba.fastjson.{JSON, JSONArray, JSONObject}
import scala.io.Source
object Demo21JSON {
def main(args: Array[String]): Unit = {
//將讀取到的每一行json語(yǔ)句存儲(chǔ)到List集合中
val lineList: List[String] = Source.fromFile("scala/data/stu.json").getLines().toList
//將集合中的元素轉(zhuǎn)換為特定格式的字符串(以換行符進(jìn)行分割)
val jsonStr: String = lineList.mkString("\r\n")
// println(jsonSrt)
//使用fastjson包中的JSON類(lèi),將一個(gè)字符串轉(zhuǎn)成json對(duì)象
//parseObject 將整體轉(zhuǎn)成一個(gè)json格式數(shù)據(jù)
//轉(zhuǎn)成json對(duì)象之后,可以通過(guò)鍵獲取值
val jsonObj: JSONObject = JSON.parseObject(jsonStr)
val str: String = jsonObj.getString("student_list")
//parseArray將一個(gè)"[{},{}]"變成一個(gè)元素是json對(duì)象的數(shù)組
val jSONArray: JSONArray = JSON.parseArray(str)
var i: Int = 0
while (i < jSONArray.size()){
val obj: JSONObject = jSONArray.getJSONObject(i)
val name: String = obj.getString("name")
val like: String = obj.getString("like")
i +=1
println(s"姓名:$name,愛(ài)好:$like")
}
}
}
//json文件
{
"flag": "SUCCESS",
"student_list": [
{
"id": "1001",
"name": "易政",
"age": 18,
"like": ["學(xué)習(xí)","看美女","打游戲"]
},{
"id": "1002",
"name": "小虎",
"age": 19,
"like": ["踢足球","打聯(lián)盟","睡覺(jué)"]
}
]
}
姓名:易政,愛(ài)好:["學(xué)習(xí)","看美女","打游戲"]
姓名:小虎,愛(ài)好:["踢足球","打聯(lián)盟","睡覺(jué)"]
9、JAVA集合轉(zhuǎn)換為Scala集合
package com.shujia.jichu
import java.util
object Demo22scala2java {
def main(args: Array[String]): Unit = {
val javaList = new util.ArrayList[Int]()
javaList.add(11)
javaList.add(12)
javaList.add(13)
javaList.add(14)
javaList.add(15)
javaList.add(16)
println(javaList)
/**
* 將java中的集合轉(zhuǎn)成scala中的集合
*
* java中的集合本來(lái)是沒(méi)有轉(zhuǎn)換scala的功能,需要導(dǎo)入隱式轉(zhuǎn)換
* scala中的導(dǎo)包,可以在任意地方
*
*/
import scala.collection.JavaConverters._
val scalaList: List[Int] = javaList.asScala.toList
println(scalaList)
/**
* scala中的集合轉(zhuǎn)java的集合
*/
val newJavaList: util.List[Int] = scalaList.asJava
println(newJavaList)
}
}
[11, 12, 13, 14, 15, 16]
List(11, 12, 13, 14, 15, 16)
[11, 12, 13, 14, 15, 16]
10、模式匹配
package com.shujia.jichu
import java.util.Scanner
import scala.io.Source
object Demo23Match {
def main(args: Array[String]): Unit = {
/**
* 模式匹配,就可以幫助我們開(kāi)發(fā)的時(shí)候,減少代碼量,讓邏輯看起來(lái)更加清晰,以及可以避免一些異常
* 語(yǔ)法:
* 表達(dá)式 match {
* case 值|[變量名:類(lèi)型]|元組|數(shù)組|對(duì)象=>
* 匹配成功執(zhí)行的語(yǔ)句
* case xxx=>
* xxx
* _ xxx=>
* xxx
* }
*
* 模式匹配中,如果沒(méi)有對(duì)應(yīng)的匹配,那么就報(bào)錯(cuò)!!!
*/
/**
* 可以匹配變量值
* 如果匹配不到則報(bào)錯(cuò)
* 也可以使用_表示匹配到了其他值
*/
val i: Int = 100
i match {
case 20 => println("該值是20")
case 50 => println("該值是50")
case _ => println("其他值")
}
/**
* 匹配數(shù)據(jù)類(lèi)型
* _: Int :前面的表示占位符名字任意,:后面的表示數(shù)據(jù)類(lèi)型
*/
val flag: Any = true
flag match {
case _: Int => println("該值是Int類(lèi)型")
case _: Boolean => println("該值是Boolean類(lèi)型")
}
/**
* 匹配元組
*/
val tuple: (String, String, Int) = Tuple3("1001", "李亮", 18)
tuple match {
case (id: String,name:String,age:Int) => println(s"學(xué)號(hào): $id,姓名:$name,年齡:$age")
}
/**
* 匹配數(shù)組
*/
val array: Array[Any] = Array("1001", "鵬飛大將軍", 100, "男", "大數(shù)據(jù)30期")
array match {
case Array(id: String,name: String,age: Int,gender: String,calzz: String) =>
println(s"學(xué)號(hào):$id,姓名:$name,年齡:$age,性別:$gender,班級(jí):$calzz")
}
/**
* 模式匹配的應(yīng)用1:避免異常
*
*/
val map: Map[String, String] = Map(("1001", "張三"), ("1002", "李四"))
val result1: Option[String] = map.get("1001")
val result2: Any = map.getOrElse("1001", 0)
println(result1)
println(result2)
println(result1.get)
val scanner = new Scanner(System.in)
println("請(qǐng)輸入你要查詢(xún)的鍵")
val key: String = scanner.next()
map.get(key) match {
case Some(a: Any) => println(s"鍵為:$key,值為:$a")
case None => println(s"${key}鍵不存在")
}
/**
* 模式匹配的應(yīng)用2:簡(jiǎn)化代碼
*
*/
val lineList: List[String] = Source.fromFile("scala/data/students.txt").getLines().toList
val arrayList: List[Array[String]] = lineList.map((line: String) => line.split(","))
val tuples: List[(String, String, String, String, String)] = arrayList.map((s: Array[String]) => {
val id: String = s(0)
val name: String = s(1)
val age: String = s(2)
val gender: String = s(3)
val calzz: String = s(4)
(id, name, age, gender, calzz)
})
tuples.foreach(println)
arrayList.map({
case Array(id:String,name:String,age:String,gender:String,clazz:String) =>
(id,name,age,gender,clazz)
}).foreach(println)
}
}
11、隱式轉(zhuǎn)換
11.1、隱式轉(zhuǎn)換函數(shù)
//當(dāng)調(diào)用函數(shù)的參數(shù)類(lèi)型為隱式轉(zhuǎn)換函數(shù)的返回值時(shí),雖然所給的參數(shù)不為函數(shù)所需參數(shù),但通過(guò)隱式轉(zhuǎn)換函數(shù)可以將非所需類(lèi)型的參數(shù)轉(zhuǎn)換為所需類(lèi)型的參數(shù)
//需求:調(diào)用fun1函數(shù),就只傳字符串,不會(huì)報(bào)錯(cuò)
//定義隱式轉(zhuǎn)換函數(shù)
//在需要返回值類(lèi)型的功能的時(shí)候,自動(dòng)地根據(jù)已有隱式轉(zhuǎn)換函數(shù)將參數(shù)的類(lèi)型轉(zhuǎn)成返回值的類(lèi)型
//應(yīng)用一:
implicit def implicitFun1(s: String): Int = {
return Integer.parseInt(s)
}
def fun1(a: Int): Int = {
a + 100
}
println(fun1("100"))
200
//應(yīng)用二
implicit def implicitFun4(s: String) = Integer.parseInt(s)
println("1000" + 500)//優(yōu)先使用字符串的拼接功能
println("1000" - 500)//因?yàn)樽址荒苓M(jìn)行減法運(yùn)算,故須通過(guò)隱式轉(zhuǎn)換函數(shù)來(lái)得到需要的類(lèi)型
500
11.2、隱式轉(zhuǎn)換類(lèi)
package com.shujia.jichu
import scala.io.Source
object Demo25implicit {
def main(args: Array[String]): Unit = {
val demo1 = new Demo99("scala/data/students.txt")
demo1.show().foreach(println)
val demo2 = new Demo99("鵬飛大將軍")
demo2.li()
}
//`implicit' modifier cannot be used for top-level objects
//implicit class Demo12(path: String) {
//implicit使用的地方,不能超過(guò)object作用域
implicit class Demo99(path: String){
def show(): List[String] = {
Source.fromFile(path).getLines().toList
}
def li(): Unit = {
println(s"${path}是一個(gè)好孩子")
}
}
}
300
300
30
20
11.3、隱式轉(zhuǎn)換變量
package com.shujia.jichu
object Demo26implicit {
def main(args: Array[String]): Unit = {
//函數(shù)柯里化
def fun1(a1: Int)(a2: Int): Int = {
a1 + a2
}
//只給一個(gè)參數(shù)返回的是一個(gè)函數(shù)
val newFun1: Int => Int = fun1(100)
println(newFun1(200))
//返回的是一個(gè)數(shù)值
val result: Int = fun1(100)(200)
println(result)
def fun2(a1: Int)(implicit a2: Int): Int = a1 + a2
implicit val a: Int = 10
//當(dāng)提供了足夠的變量后,就不會(huì)使用隱式轉(zhuǎn)換變量
println(fun2(10)(20))
//當(dāng)提供的變量不足時(shí),就會(huì)去尋找是否有符合類(lèi)型的隱式轉(zhuǎn)換變量
println(fun2(10))
}
}
11.4、面試題
/**
* 面試題:
* scala中的隱式轉(zhuǎn)換知道嗎?說(shuō)一說(shuō)
* 答:
* 知道。
* 1、scala中的隱式轉(zhuǎn)換,本質(zhì)上就是將一個(gè)類(lèi)型轉(zhuǎn)換成另一個(gè)類(lèi)型去使用另一個(gè)類(lèi)型中的功能
* 2、scala中的隱式轉(zhuǎn)換分為3種:隱式轉(zhuǎn)換函數(shù),隱式轉(zhuǎn)換類(lèi),隱式轉(zhuǎn)換變量
* 3、隱式轉(zhuǎn)換函數(shù),在使用隱式轉(zhuǎn)換函數(shù)返回值類(lèi)型的功能的時(shí)候,可以自動(dòng)的將參數(shù)的類(lèi)型轉(zhuǎn)成返回值類(lèi)型進(jìn)行使用
* 4、隱式轉(zhuǎn)換類(lèi),可以自動(dòng)的將構(gòu)造方法的參數(shù)類(lèi)型轉(zhuǎn)成類(lèi)的類(lèi)型,將來(lái)可以直接使用構(gòu)造方法中的類(lèi)型調(diào)用類(lèi)中的方法
* 5、隱式轉(zhuǎn)換變量,配合函數(shù)定義中的隱式轉(zhuǎn)換參數(shù)使用,
* 將來(lái)調(diào)用函數(shù)的時(shí)候,可以不用傳入隱式轉(zhuǎn)換參數(shù)的值,自動(dòng)使用對(duì)應(yīng)類(lèi)型的隱式轉(zhuǎn)換變量
* 當(dāng)然,也可以手動(dòng)傳入具體的值給隱式轉(zhuǎn)換參數(shù)。
*
*/
12、Scala進(jìn)階
12.1、題目
階段一
基于學(xué)生、分?jǐn)?shù)、科目數(shù)據(jù)使用Scala語(yǔ)言完成下面的練習(xí)
中括號(hào)為最終要求輸出的格式
題目較為基礎(chǔ)
統(tǒng)計(jì)班級(jí)人數(shù) [班級(jí),人數(shù)]
統(tǒng)計(jì)學(xué)生的總分 [學(xué)號(hào),學(xué)生姓名,學(xué)生年齡,總分]
階段二
數(shù)據(jù)同階段二一樣
題目難度偏大
1、統(tǒng)計(jì)年級(jí)排名前十學(xué)生各科的分?jǐn)?shù) [學(xué)號(hào), 姓名,班級(jí),科目,分?jǐn)?shù)]
2、統(tǒng)計(jì)總分大于年級(jí)平均分的學(xué)生 [學(xué)號(hào),姓名,班級(jí),總分]
3、統(tǒng)計(jì)每科都及格的學(xué)生 [學(xué)號(hào),姓名,班級(jí),科目,分?jǐn)?shù)]
4、統(tǒng)計(jì)每個(gè)班級(jí)的前三名 [學(xué)號(hào),姓名,班級(jí),分?jǐn)?shù)]
5、統(tǒng)計(jì)偏科最嚴(yán)重的前100名學(xué)生 [學(xué)號(hào),姓名,班級(jí),科目,分?jǐn)?shù)]
12.2、代碼
package com.shujia.jinjie
import scala.collection.immutable
import scala.io.Source
object HomeWork {
//定義一些變量,樣例類(lèi),為后續(xù)的開(kāi)發(fā)做準(zhǔn)備
/**
* 定義一些樣例類(lèi) 類(lèi)似于java的封裝
*/
private case class Student(id: String, name: String, age: Int, gender: String, clazz: String)
private case class Score(id: String, subject_id: String, score: Int)
private case class Subject(subject_id: String, subject_name: String, subject_score: Int)
/**
* 定義三個(gè)存儲(chǔ)三個(gè)不同對(duì)象的List集合
*/
private var stuList: List[Student] = _
private var scoreList: List[Score] = _
private var subjectList: List[Subject] = _
/**
* 定義一些map集合
* stuInfoMap (stu.id, stu.name + "," + stu.clazz)
* subNameMap (subject.subject_id, subject.subject_name)
* subScoreMap (subject.subject_id, subject.subject_score)
*/
private var stuInfoMap: Map[String, String] = _
private var subNameMap: Map[String, String] = _
private var subScoreMap: Map[String, Int] = _
//初始化變量
private def loadData(): Unit = {
//讀取學(xué)生數(shù)據(jù)
stuList = "scala/data/students.txt".load()
.map {
case Array(id: String, name: String, age: String, gender: String, clazz: String) =>
Student(id, name, age.toInt, gender, clazz)
}
//讀取成績(jī)數(shù)據(jù)
scoreList = "scala/data/score.txt".load()
.map {
case Array(id: String, subject_id: String, score: String) =>
Score(id, subject_id, score.toInt)
}
//讀取科目數(shù)據(jù)
subjectList = "scala/data/subject.txt".load()
.map {
case Array(subject_id: String, subject_name: String, subject_score: String) =>
Subject(subject_id, subject_name, subject_score.toInt)
}
//處理三個(gè)map集合
//stuInfoMap 存儲(chǔ)了學(xué)生的學(xué)號(hào)為鍵,姓名和班級(jí)作為值
stuInfoMap = stuList.map((stu: Student) => (stu.id, stu.name + "," + stu.clazz)).toMap
subNameMap = subjectList.map((sub: Subject) => (sub.subject_id, sub.subject_name)).toMap
subScoreMap = subjectList.map((sub: Subject) => (sub.subject_id, sub.subject_score)).toMap
}
/**
* 根據(jù)學(xué)號(hào)集合打印【學(xué)號(hào),姓名,班級(jí),科目,分?jǐn)?shù)】
*/
private def printStudentInfoWithId(ids: List[String]): Unit = {
// 從總的學(xué)生成績(jī)信息中過(guò)濾出來(lái)
scoreList.filter((sco: Score) => ids.contains(sco.id))
.map {
case Score(id: String, subject_id: String, score: Int) => {
//根據(jù)學(xué)號(hào),查找姓名和班級(jí) stuInfoMap
val nameWithClazz: String = stuInfoMap.getOrElse(id, "查無(wú)此人")
//根據(jù)科目編號(hào),查找科目的名字 subNameMap
val subject_name: String = subNameMap.getOrElse(subject_id, "無(wú)此科目")
s"[$id,$nameWithClazz,$subject_name,$score]"
}
}.foreach(println)
}
/**
* 統(tǒng)計(jì)班級(jí)人數(shù) [班級(jí),人數(shù)]
*/
private def xuQiu1(): Unit = {
stuList.groupBy((stu: Student) => stu.clazz)
.map((kv: (String, List[Student])) => {
s"[${kv._1},${kv._2.size}]"
}).foreach(println)
}
/**
* 統(tǒng)計(jì)學(xué)生的總分 [學(xué)號(hào),學(xué)生姓名,學(xué)生年齡,總分]
*/
private def xuQiu2(): Unit = {
val stringToInt: Map[String, Int] = scoreList.groupBy((sco: Score) => sco.id)
.map((kv: (String, List[Score])) => {
(kv._1, kv._2.map(_.score).sum)
})
val ids: List[String] = stringToInt.map {
case (id: String, _: Int) => id
}.toList
stuList.filter((stu: Student) => ids.contains(stu.id))
.map((stu: Student) => {
val sumScore: Int = stringToInt.getOrElse(stu.id, 0)
s"[${stu.id},${stu.name},${stu.age},$sumScore]"
}).foreach(println)
}
/**
* 統(tǒng)計(jì)年級(jí)排名前十學(xué)生各科的分?jǐn)?shù) [學(xué)號(hào),姓名,班級(jí),科目,分?jǐn)?shù)]
*/
private def xuQiu3(): Unit = {
val ids: List[String] = scoreList.groupBy((s: Score) => s.id) // 按照學(xué)號(hào)進(jìn)行分組
.map((kv: (String, List[Score])) => {
(kv._1, kv._2.map(_.score).sum) // 求每個(gè)學(xué)生的總分
})
.toList
.sortBy(-_._2)
.take(10)
.map(_._1)
printStudentInfoWithId(ids) // 學(xué)號(hào),姓名,班級(jí),科目,分?jǐn)?shù)
}
/**
* 統(tǒng)計(jì)總分大于年級(jí)平均分的學(xué)生 [學(xué)號(hào),姓名,班級(jí),總分]
*/
private def xuQiu4(): Unit = {
//先計(jì)算年級(jí)平均分 372
val avgScore: Int = scoreList.map(_.score).sum / stuList.size
// println(avgScore)
//計(jì)算每個(gè)人總分進(jìn)行過(guò)濾
scoreList.groupBy((s: Score) => s.id) // 按照學(xué)號(hào)進(jìn)行分組
.map((kv: (String, List[Score])) => {
(kv._1, kv._2.map(_.score).sum) // 求每個(gè)學(xué)生的總分
})
.filter(_._2 > avgScore)
.map((t: (String, Int)) => {
//根據(jù)stuInfoMap獲取學(xué)生的姓名和班級(jí)
val nameWithClazz: String = stuInfoMap.getOrElse(t._1, "查無(wú)此人")
s"[${t._1},$nameWithClazz,${t._2}]"
}).foreach(println)
}
/**
* 統(tǒng)計(jì)每科都及格的學(xué)生 [學(xué)號(hào),姓名,班級(jí),科目,分?jǐn)?shù)]
*/
private def xuQiu5(): Unit = {
//1500100001,1000001,98
val ids: List[String] = scoreList.filter((sco: Score) => sco.score >= subScoreMap.getOrElse(sco.subject_id, 0) * 0.6)
.groupBy(_.id) // 根據(jù)學(xué)號(hào)分組,過(guò)濾6門(mén)考試都及格的學(xué)生
.filter(_._2.size == 6)
.keys
.toList
printStudentInfoWithId(ids)
}
/**
* 統(tǒng)計(jì)每個(gè)班級(jí)的前三名 [學(xué)號(hào),姓名,班級(jí),分?jǐn)?shù)]
*/
private def xuQiu6(): Unit = {
val ids: List[String] = scoreList
.groupBy((s: Score) => s.id) // 按照學(xué)號(hào)進(jìn)行分組
.map((kv: (String, List[Score])) => {
val nameWithClazz: String = stuInfoMap.getOrElse(kv._1, "查無(wú)此人")
val infos: Array[String] = nameWithClazz.split(",")
val name: String = infos(0)
val clazz: String = infos(1)
(kv._1, name, clazz, kv._2.map(_.score).sum) // 求每個(gè)學(xué)生的總分
})
.groupBy(_._3) // 根據(jù)班級(jí)進(jìn)行分組
.flatMap((kv: (String, Iterable[(String, String, String, Int)])) => {
kv._2.toList.sortBy(-_._4).take(3)
}).map(_._1).toList
// 從總的學(xué)生成績(jī)信息中過(guò)濾出來(lái)
scoreList.filter((sco: Score) => ids.contains(sco.id))
.map {
case Score(id: String, subject_id: String, score: Int) => {
//根據(jù)學(xué)號(hào),查找姓名和班級(jí) stuInfoMap
val nameWithClazz: String = stuInfoMap.getOrElse(id, "查無(wú)此人")
s"[$id,$nameWithClazz,$score]"
}
}.foreach(println)
}
/**
* 統(tǒng)計(jì)偏科最嚴(yán)重的前100名學(xué)生 [學(xué)號(hào),姓名,班級(jí),科目,分?jǐn)?shù)]
*
* 方差
* (每個(gè)人的各科分?jǐn)?shù)-6門(mén)考試的平均分)^2 / 科目數(shù)
*
*/
private def xuQiu7(): Unit = {
//歸一化
val ids: List[String] = scoreList.map {
case Score(id: String, subject_id: String, score: Int) =>
(id: String, subject_id: String, score * 100 / subScoreMap.getOrElse(subject_id, 0))
}.groupBy(_._1) //根據(jù)學(xué)號(hào)進(jìn)行分組
.map((kv: (String, List[(String, String, Int)])) => {
val id: String = kv._1
val scoreList: List[(String, String, Int)] = kv._2
//每個(gè)人的平均分
val avgScore: Int = scoreList.map(_._3).sum / scoreList.size
//求方差
val fangCha: Double = scoreList.map((t3: (String, String, Int)) => Math.pow(t3._3 - avgScore, 2)).sum / scoreList.size
(id, fangCha)
})
.toList
.sortBy(-_._2)
.take(100)
.map(_._1)
printStudentInfoWithId(ids)
}
def main(args: Array[String]): Unit = {
loadData()
// xuQiu1()
// xuQiu2()
// xuQiu3()
// xuQiu4()
// xuQiu5()
// xuQiu6()
// xuQiu7()
}
//定義一個(gè)隱式轉(zhuǎn)換類(lèi)
//將來(lái)可以直接通過(guò)文件路徑獲取一個(gè)封裝了行數(shù)據(jù)的集合
implicit class Load(path: String) {
def load(): List[Array[String]] = {
Source.fromFile(path).getLines().toList.map((line: String) => line.split(","))
}
}
}
柚子快報(bào)激活碼778899分享:開(kāi)發(fā)語(yǔ)言 Scala學(xué)習(xí)
推薦文章
本文內(nèi)容根據(jù)網(wǎng)絡(luò)資料整理,出于傳遞更多信息之目的,不代表金鑰匙跨境贊同其觀點(diǎn)和立場(chǎng)。
轉(zhuǎn)載請(qǐng)注明,如有侵權(quán),聯(lián)系刪除。