Scala入門基礎

一.數據類型概述

看官網:DOCUMENTION→Tour of Scala→Unified Types

Unified Types | Tour of Scala | Scala Documentation (scala-lang.org)

(一).類型的基本概念

Any是最頂層,也叫超類型或頂級類型,它下面有一個值類型AnyVal和一個引用類型AnyRef。

值類型AnyVal包括Double、Float、Long、Int、Short、Byte、Unit、Boolean、Char類型;

引用類型AnyRef包括List、Option、YourClass。

Nothing是最底層,也叫底部類型。

任意一種類型都有一個子類:Nothing

整型

整型的默認類型是Int

Byte: -128-127

Short:-32768-32767

Int 整型的默認類型

Long(使用Long類型,在數字后面加上L)

整型可以分為有符號類型(+、-)和無符號類型(只能存非負數)

練習:

整型

1.報錯type mismatch是因為類型不匹配

2.報錯integer number too large是因為超出了范圍

浮點類型

浮點類型的默認類型是Double

Float:32位,單精度(使用Float類型末尾加F)

Double:64位,雙精度(使用Double類型末尾加D)

浮點類型

使用Float類型小數點太長的話會導致精度丟失。

Char類型

使用Char類型用單引號擴起來即可。

Char類型

c1.toInt 將c1轉換成Int類型(a的ascall碼值為97;b的ascall碼值為98;)

Boolean類型

true? ?0

false? 1

val flag:Boolean = true 返回:flag:Boolean = true

val flag:Boolean = false 返回:flag:Boolean = false

補充知識

println()輸出

1. \t 制表符

2. \n 制列符

3. \\ 轉譯符

(二).類型轉換

精度低的類型往精度高的轉換(越往右邊精度越高)

Int+Double→Double
因為n1是Long類型,往Int轉不了
強轉:可能會導致精度丟失
1.先做類型轉換再做四則運算;2.小括號優(yōu)先

判斷某數值的類型

小技巧:記不住代碼的時候可以按“Tab”鍵補齊。

10.isInstanceOf[Int] #判斷10是否為Int類型

10.0.isInstanceOf[Int] #判斷10.0是否為Int類型

10.0.asInstanceOf[Int] #把10.0轉換為Int類型

(三).字符串操作

單行字符串操作

右鍵basic→New→Scala class:TypeApp

val money = 67850

println("輸出:"+money)

printf ("%d",money)? //%d:代表10進制

println()

printf("%f", math.Pi)? //%f:代表float類型

println()

printf("%s %f %d", "abc", 1.6, 4)? //%s代表String字符串類型

附:println(text:String,xs:Any*) Unit 其中xs:Any*代表前面的“xs”所有類型都可以

val name = "PK"

?val age = 32

掌握這種但是不建議:

?val info = "name="+name+",age="+age

println(info)??

建議使用字符串插值:

val info = s"name=$name,age=$age" //s是固定的寫法,用$直接引用就好了

println(info)

上述操作可以直接println(s"name=$name,age=${age-1}")? //用{}做帶運算的,【注意】只要是這種樣式,一進s“”里面,在$前面加{}就對了。

多行字符串操作““””

常用于多行mysql的輸入輸出

val welcome =

? ? ? """

? ? ? ? |歡迎來到若澤大數據

? ? ? ? |這里是未來

? ? ? ? |我是006-武漢-阿坤

? ? ? ? |""".stripMargin

? ? println(welcome)

例1:

var sql=

? """

? ? |select e.empno,e.ename,e.deptno,d.dname

? ? |from

? ? |emp e join dept d

? ? |on e.deptno=d.deptno

? ? |""".stripMargin

? ? println(sql)

例2:

var day="20211122"

? ? println(

? ? ? s"""

? ? ? ? |select * from xxx where day='$day'

? ? ? ? |""".stripMargin)

(四).運算符

1.pom文件加spark-core依賴(Project→target→pom.xml點開)

【注】:pom文件導入包依賴,可參考:pom文件導入maven依賴 - 簡書 (jianshu.com)

添加:

<dependency>

? ? <groupId>org.apache.spark</groupId>

? ? <artifactId>spark-core-2.12</artifactId>

? ? <version>3.1.1</version>

</dependency>

2.IDEA如何找源碼? 點擊右上角放大鏡,然后輸入需要的文件名,比如SparkContext.scala

字符串操作

scala> 10/3? 返回res24:Int =3? //相當于除后取整數

scala> a=10/3? 返回a:Int =3

scala> a:Double=10/3? 返回a:Double =3.0? //Int類型/Int類型結果Int類型,最后轉成Double類型

scala>val a:Double=10.0/3? 返回a:Double =3.333333333333335

scala>a.formatted("%.3f")? 返回res25:String=3.333? //%.3f取三位小數→%.nf取n位小數

scala>10%3? 返回res27:Int=1? //10對3取模(取余)

!=不等于
&&與;||或;!(a && b)取反
加減運算操作

二.Scala語句

(一).if語句

scala中沒有swhich語句

右鍵basic→New→Scala class:IfApp

if單分支

val num = 10

if(num % 2 == 0){

println(s"$num 是偶數")

}

if單分支

if雙分支

val num = 10

if(num % 2 == 0){

? ? ? println(s"$num 是偶數")

? ? }else{

? ? ? println(s"$num 是奇數")

? ? }

if多分支

val score = StdIn.readInt()

? ? if(score==100){

? ? ? println("滿分,牛啊牛啊")

? ? }else if (score>80 && score<100){

? ? ? println("還可以,加油")

? ? }else if (score>60 && score<=80){

? ? ? println("還行吧")

? ? }else {

? ? ? println("小菜雞")

? ? }

if多分支

求兩個數的最大值

【注】命名:駝峰標識,即命名兩個或兩個以上單詞放在一起的時候,每個單詞的第一個字母大寫

val a=10

? ? val b=20

?var result=Int.MinValue? //求最大值這里放最小值;求最小值這里放最大值

? ? if (a>b){

? ? ? result=a

? ? }else {

? ? ? result=b

? ? }

? ? println(s"最大值是:$result")

上述操作太繁瑣了,可以直接這樣:

val a=10

? ? val b=20

?val maxNumber = if(a>b) a else b

? ?println(s"最大值是 $maxNumber")

? ? }

正常寫法:

val a=10

? ? val b=20

val maxNumber = if (a>b) {

? ? a}else {

? ? ? b}

? ? ? println(s"最大值是 $maxNumber")

? ? }? //在scala中,如果{}里面只有一行,那么{}可以省略,但是建議一定要把{}加上

if語句套用if語句

val group=StdIn.readChar()

? ? if (group=='1'){

? ? ? print("你是一組的。。。")

? ? }else{

? ? ? println("你不是一組的。。")

? ? ? println("請輸入成績")

? ? ? var score =StdIn.readDouble()

? ? ? if(score>=99){

? ? ? ? println("牛啊牛啊")

? ? ? }else{

? ? ? ? println("去玩泥巴吧!")

}

(二).while循環(huán)語句

右鍵basic→New→Scala class:WhileApp

求1+100的和

var num = 1

? ? while (num<=100){

? ? ? num += 1

? ? ? //println("==>" +num)? //可以一步步打印出來看看執(zhí)行到了哪一步

? ? }

? ? println(num)

①Step Over一步一步地執(zhí)行,點一次執(zhí)行一次

②Step Into往里走,一般用不著

do while

var b =1

? ? do{

? ? ? b +=1

? ? }while(b<=100)

? ? println(b)

【面試題】:while循環(huán)有沒有返回值?

答:經測試,沒有返回值(或者說返回Unit值)

測試:

var c=1

? ? val res=while (c<=100){

? ? ? c +=1

? ? }

? ? println(res)

此時返回:()[空,代表沒有]

var c=1

? ? val res:Unit=while (c<=100){? //Unit:沒有值,相當于java中的void;Unit類型只有一個值()

? ? ? c +=1

? ? }

? ? println(res)

求1+2+3+...+99+100的和

var num=100

? ? var sum=0

? ? while(num>100){??//while循環(huán),當條件滿足時才會進入

? ? ? sum=sum+num

? ? ? num=num-1

? ? }

? ? println(sum)

var num=0

? ? var sum=0

? ? while(num<=100){? //while循環(huán),當條件滿足時才會進入

? ? ? sum=sum+num

? ? ? num=num+1

? ? }

? ? println(sum)

while循環(huán)中debug操作:

跳出while循環(huán)

1.指定某句話打印多少次

var flag=true? //flag用來作為一個指示變化的變量的名稱,一般設置一個變量flag,是一個來表示判斷的變量,當做標志。

? ? var cnt=1? ? //次數

? ? while(flag){

? ? ? if(cnt>5){

? ? ? ? flag=false

? ? ? }

? ? ? println(s"$cnt,沖鴨?。?!")

? ? ? cnt +=1? //每執(zhí)行一次cnt+1

? ? }

上述操作雖然是cnt > 5但實際輸出了六次,具體過程如下:

①cnt 1 > 5? 1 true(cnt 1不大于5)

②cnt 2 > 5? 2 true(cnt 2不大于5)

③cnt 3 > 5? 3 true(cnt 3不大于5)

④cnt 4 > 5? 4 true(cnt 4不大于5)

⑤cnt 5 > 5? 5 true(cnt 5不大于5)

⑥cnt 6 > 5(此時已經進了while循環(huán),所以還要輸出一次)? 6 flase(cnt 6大于5),輸出六次,跳出循環(huán)

2.遍歷10以內的數,==5時結束

var n = 1

? ? breakable {

? ? ? while(n < 10) {

? ? ? ? println("n =====" + n)

? ? ? ? n += 1

? ? ? ? if(n == 5) {

? ? ? ? ? break()

? ? ? ? }

? ? ? }

? ? }

println("exit")

此時返回:

n ===== 1

n ===== 2

n ===== 3

n ===== 4

exit

3.輸出10以內的奇數,跳過偶數

var n=0

? ? while(n<10){

? ? ? breakable{

? ? ? ? n += 1

? ? ? ? if(n % 2 !=0){

? ? ? ? ? println(n)

? ? ? ? }else{

? ? ? ? ? break()

? ? ? ? }

? ? ? }

? ? }

? ? println("exit")

此時返回:

1 3 5 7 9

exit

手動導包:上述2、3中最開始break和breakable都是紅色報錯字體,自動導包不可以的話需要手動導包:在package和object之間輸入import scala.util.control.Breaks._

scala中,break和breakable必須配套使用?。?!

(三).for語句

右鍵basic→New→Scala class:WhileApp

val a="abc"

? ? for (c <- a){? //把a里面每一個都賦給c

? ? ? println(c)

? ? }

for(i <- 1 to 10) println(i)? //把1-10里面每個東西賦值給i

等價于for(i <- 1.to(10)) println(i)? //to是一個左閉右閉的區(qū)間

for(i <- 1.until(10)) println(i)? //until是一個左閉右開的區(qū)間,不包括最后一個

for(i <- 1.to(10,2)) println(i)? //把1-10里面每個東西按步長為2賦值給i(復制到IDEA里面去可以查看to的源碼)

等價于for(i <- 1.to(10) by 2) println(i)

for(i <- 1.to(10) reverse) println(i)? //倒序輸出

等價于for(i <- 1 10 to 1 by -1) println(i)? //倒序且按步長為1輸出

Range (1,10) 實際上就是Range 1 until 10

Range (1,10,2) 實際上就是inexact Rage 1 until 10 by 2(其中2是步長step,步長不能為0)

輸出1到100范圍內的奇數

輸出1到100范圍內的奇數-普通方式

for(i <- 1 to 100){

? ? if(i % 2 ==1){

? ? ? println(i)

? ? }

? ? }

輸出1到100范圍內的奇數-循環(huán)守衛(wèi)

for(i<- 1 to 100 if i % 2 ==1){

? ? ? println(i)

? ? ? }

循環(huán)守衛(wèi)

輸出1到10且不為3

for(i<- 1 to 10 if i !=3){

println(i)

}

計算1到10的平方數

計算1到10的平方數-普通方式

for(i<- 1 to 10){

? ? ? println(i*i)

? ? }

計算1到10的平方數-循環(huán)返回值

val res=for(i<-1 to 10) yield i*i

? ? println(res)

循環(huán)返回值

把abcdef轉成大寫字母

把abcdef轉成大寫字母-循環(huán)返回值(low)

val result=for(s <- "abcdefg") yield s.toUpper

? ? println(result)

把abcdef轉成大寫字母-循環(huán)返回值(加小寫)(low)

val result=for(s <- "abcdefg") yield s.toString.toUpperCase+s

? ? println(result)

把abcdef轉成大寫字母-高階函數,函數式編程

"abcdefg".map(x => x.toString.toUpperCase()+x).foreach(println) //非常重要,生產上常用

三.function的定義與使用

function的引入:

val a=10

? val b=20

?val op = "-"

? ?if(op == "+"){

? ? println(a+b)

? ?}else if(op == "-"){? //java中要使用equals;scala中可以不用equals,直接使用“==”

? ? println(a-b)

這樣的操作太過于繁瑣冗余,代碼的復用性太低了,想辦法把a,b,op傳給compute:compute(a,b,op),此時引入function:

def 函數名/方法名(x:Int,y:Int):Int={?

? ?if(x>y) x else y? //求最大最小值

} //函數和方法不是同一個東西喲;(x:Int,y:Int)代表入參;Int代表返回值類型;有返回值用“=”

{}里面的叫做方法體,是不可以缺少的

①方法體的最后一行是作為整個方法的返回值的,不需要用return;

②方法體只有一行時,可以省略{}

③scala中,如果function沒有入參的話,()都可以省略

function簡單入門

簡單加法

def add(a:Int,b:Int):Int={

? ? ? a+b

? ? }

?println(add(2, 4))

省略花括號

def three()=1+2

function嵌套使用

?def fun1(a:Int){

? ? ?def fun2(b:Int){? //只定義了,不回去執(zhí)行,需要調用

? ? ?println(s"fun1.fun2...${a+b}")??

? ? }

? ? ?fun2(100)

? }

省略小括號

def three()=1+2

? println(three)? //沒有入參,可以省略小括號

function沒有返回值

def sayHello()={? //相當于sayHello():Unit沒有返回值

? ? println("你好")

? }

四.scala中參數相關概念

(一).默認參數

默認參數在spark中常常出現(xiàn),spark中配置是有一個全局配置,默認在一個配置文件spark-default.conf中,spark-default.conf是一個自定義的配置文件。

生產場景:

def loadConf(conf:String="spark-default.conf"):Unit={

println(conf)

loadConf()? //這里會默認調用spark-default.conf

如果直接loadConf("spark-default.conf") ,就直接調用這個了

實例:

def sayHello(name:String): Unit ={? //(name:String)這里可以放一個值進去作為默認值,也可以不放,后面再輸入一下,比如下面的“LK”

? ? ? ?println(s"Hello:$name")

? ?}

def sayHello(name:String="若澤"): Unit ={

? ? ? ?println(s"Hello:$name")

? ?}

(二).參數命名*

命名參數:按名稱命名傳遞(傳遞時不安坐標傳遞,而是按照名稱傳遞的)

調用:println(speed(100,10))? //太low了

println(speed(100,10))

調用: println(speed(time=10,distance=100)) //命名參數

(三).可變參數

例1:求很多數的和

def sum(nums: Int*):Int={? //Int*表示可以傳入n個Int的值,一定要放在參數的最后一位喲

? ?var res=0

? for(num <- nums){

? ? ? res+=num

? ? }

? ?res

?}

?def sum(nums: Int*):Int={

? ? var res=0

? ? ? for(num <- nums){

? ? ? res+=num

? ?}

? ?res

? ?}

?println(sum(1 to 10:_*))? //1 to 10:_*表示將1to10轉變成可變參數(將某個字段轉變成可變參數加“:_*”),這里把1 to 10理解為一個集合,把這個集合轉變成可變參數

例2

def printInfo(students:String*)={

? ? ? students.foreach(println) //foreach實際上把每個都編譯一下

? ? }

? printInfo("001","002","003")

def printInfo(students:String*)={

? ? ? students.foreach(println)

? ? }

? ? val array=Array("001","002","003")

? ? printInfo(array:_*)

五.遞歸

概念:

遞歸就是在運行過程中調用自己。只由一種(或多種)簡單的基本情況定義的一類對象或方法,并規(guī)定其他所有情況都能被還原其基本情況。遞歸關系就是實體自己和自己建立關系。

對于遞歸的,一定要手工的加上返回類型。

條件:

? ? ?1. 子問題須與原始問題為同樣的事,且更為簡單;

? ? ?2. 不能無限制地調用本身,須有個出口,化簡為非遞歸狀況處理。

例題:求階乘

def factorial(n:Long):Long={

?if (n==1) 1

? ?else n*factorial(n-1)

? }

?println(factorial(10))

}

def factorial(n:Long):Long={

? if (n==1) 1

? ? else n*factorial(n-1)

?}

?println(factorial(100000))

經典報錯:Exception in thread "main" java.lang.StackOverflowError? 出現(xiàn)溢出問題了

解決溢出問題—尾遞歸

? @tailrec

? ? def factorial2(n:Int, acc:BigInt):BigInt={ //acc聚合累加器

? ? ? if(n==1) acc? //如果等于1,調用自己

? ? ? else factorial2(n-1,n*acc)

? ? }

? ? println(factorial2(100000,acc=1))


思考題:函數在main方法里面和外面有什么區(qū)別?

?? 答: 只要能訪問到都是OK的,但是到后面隱式轉換就不然了。


已同步至:Scala入門基礎_comer_liu的博客-CSDN博客

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
【社區(qū)內容提示】社區(qū)部分內容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內容

  • scala下載和安裝 命令行使用 JAVA8環(huán)境 scala下載 unzip scala 配置環(huán)境變量 啟動 ./...
    kangapp閱讀 823評論 0 1
  • 首先,參照相關攻略,在Linux下分別下載安裝Java、Scala,然后配置Java和Scala環(huán)境變量。安裝完畢...
    flyskyzyl閱讀 564評論 0 3
  • Scala與Java的關系 Scala與Java的關系是非常緊密的!! 因為Scala是基于Java虛擬機,也就是...
    義焃閱讀 685評論 0 1
  • 1.1. 什么是Scala Scala是一種多范式的編程語言,其設計的初衷是要集成面向對象編程和函數式編程的各種特...
    文子軒閱讀 1,581評論 1 3
  • scala編程語言 作者:Martin OrderSky也是jvm開發(fā)團隊的核心成員之一,是java得泛型作者 s...
    XLMN閱讀 548評論 0 0

友情鏈接更多精彩內容