计算类声明一个集合vallistInt:List[Int]=List(1,2,3,4,5)最大值maxprintln("Max="+listInt.max)-------------------------------Max=5最小值minprintln("Min="+listInt.min)-------------------------------Min=1乘积productprintln("product="+listInt.product)--------------------------------------product=120排序创建一个集合vallistStr:List[String]=List("21","22","33","11","aa")vallistInt:List[Int]=List(1,2,3,4,5)sortBy()按照某个标准排序,参数传入一个函数按照大小排序valvalue2:List[Int]=listInt.sortBy(x=>x)println(value2.mkString(","))-----------------------------1,2,3,4,5按照个位的大小排序valvalue3:List[String]=listStr.sortBy((s)=>s.substring(1,2))println(value3.mkString(","))-----------------------------21,11,22,33,aasortWith()指定排序规则创建集合vallistInt:List[Int]=List(1,2,3,4,5)vallistStr1:List[String]=List("21","22","33","11")大小排序把>改成<就是升序valvalue4:List[Int]=listInt.sortWith((left,right)=>{left>right//左边的大于右边的降序})println(value4.mkString(","))-----------------------------5,4,3,2,1按照个位排序valvalue5:List[String]=listStr1.sortWith((left,right)=>{left.substring(1,2).toInt<right.substring(1,2).toInt})println(value5.mkString(","))-----------------------------21,11,22,33结构类对集合中的每个元素进行操作,每个元素的结构映射(变换)集合反转创建集合vallistInt:List[Int]=List(1,2,3,4,5)反转valreverse:List[Int]=listInt.reverseprintln(reverse.mkString(","))------------------------------5,4,3,2,1groupBy()分组,传入函数是需要指定Key值,会返回一个(K,List()),(K1,List()),..,这的Map集合创建集合vallistStr:List[String]=List("21","22","33","11","aa")按照自身分组privatevalvalue:Map[String,List[String]]=listStr.groupBy((x)=>{x})value.foreach(println)----------------------(11,List(11))(33,List(33))(22,List(22))(21,List(21))(aa,List(aa))按照首位数字分组valvalue1:Map[String,List[String]]=listStr.groupBy(x=>x.substring(0,1))value1.foreach(println)-----------------------(a,List(aa))(1,List(11))(2,List(21,22))(3,List(33))map()映射,元素结构转换创建集合vallistStr2=List("a","a","c","c","b","a")把每个元素转换成(元素,1)valvalue6:List[(String,Int)]=listStr2.map((x)=>(x,1))println(value6.mkString(","))-----------------------------(a,1),(a,1),(c,1),(c,1),(b,1),(a,1)偏平化创建集合vallistStr3=List("HelloScala","HelloPython","HelloJava")扁平化valvalue9:List[String]=listStr3.flatMap(x=>x.split(""))println(listStr3.mkString(","))println(value9.mkString(","))-------------------------------HelloScala,HelloPython,HelloJavaHello,Scala,Hello,Python,Hello,Java如果集合里的元素不太规律,就需要把进行判断处理vallistAny:List[Any]=List(1,List(2,3),List(4,5),66)valvalue12:List[Any]=listAny.flatMap((Any)=>{if(Any.isInstanceOf[List[Int]]){Any.asInstanceOf[List[Int]]//转换成可迭代的类型}else{List(Any)}})println(value12)------------------------------List(1,2,3,4,5,66)过滤判断为True的留下,False的去掉valListToInt:List[Int]=List(1,2,3,4)过滤大于2的数valvalue10:List[Int]=ListToInt.filter(x=>x>2)println(value10.mkString(","))------------------------------3,4zip创建集合valListToInt:List[Int]=List(1,2,3,4)valListToInt1:List[Int]=List(2,3,4,5)zip操作valvalue11:List[(Int,Int)]=ListToInt.zip(ListToInt1)println(value11.mkString(","))------------------------------(1,2),(2,3),(3,4),(4,5)其他(待补充)reduce()会对集合元素进行两两操作,最后得出一个值创建一个集合vallistInt:List[Int]=List(1,2,3,4,5)实现集合相加,跟sum()一样vali:Int=listInt.reduce((right,left)=>{right+left})println(i)----------15//实际逻辑((((1+2)+3)+4)+5)+6
元组元组就是使用()包裹起来的一组数它把无关的数据包裹成了一个整体,Map是通过键值对的方式建立关联创建元组valtuple:(String,Int,String)=("Scala",18,"123")取值println(tuple._1)//Scalaprintln(tuple._2)//18遍历for(t<-tuple.productIterator){println(t)}-----------------------Scala18123特殊如果元组里元素个数为2,称之为对偶,类似于Map的键值对创建注意是使用Map创建的valtupleMap:Map[Int,String]=Map((1,"AA"))遍历每传入的一个元素都是一个元组tupleMap.foreach((t)=>{println(t)})//t->就是一个元组
集合分类Scala集合分为两大类可变(mutable)和不可变(immutable)不可变:数组声明好,数组的长度就不能再改变可变:数组声明好,可就改变数组的长度三大集合Seq集合有序可重复代表List()不可变的List()默认无需导入创建vallist:List[Int]=List(1,2,3,4)修改内容list.updated(1,11)//通过索引修改查,遍历//查,取值list(索引)//遍历list.foreach(println)for(l<-list){println(l)}可变ListBuffer()需要导入创建集合varlistBuffer:ListBuffer[Int]=ListBuffer(1,2,3,4)增加元素listBuffer.insert(1,11)//索引插入listBuffer.append(1)//加在最后删除元素listBuffer.remove(1)//通过索引删值listBuffer.remove(1,2)//索引,几个listBuffer.drop(2)//从索引0开始删几个修改元素listBuffer.update(0,11)//通过索引修改元素查询,遍历元素//查询,取值listBuffer(索引)//遍历listBuffer.foreach(println)for(l<-listBuffer){println(l)}特殊的List()集合空集合println(List())//List()println(Nil)//List()用处1::2::NilSet集合无序不可重复使用Set集合需要记住,无序(就表示需要索引的操作不能用)主要使用是生成新的集合,本身变化不大创建Set集合//默认是不可变的valset:Set[Int]=Set(1,2,1,2,3,4)//可变Set集合valmSet:mutable.Set[Int]=mutable.Set(1,2,3,44,5,5,5,1,2)一些操作//添加删除varmSet1:mutable.Set[Int]=mSet+11println(mSet1.mkString(","))varmSet2:mutable.Set[Int]=mSet-1println(mSet2.mkString(","))---------------------------------------1,2,3,5,11,442,3,5,44Map集合无序,(k->v),key不能重复,value可重复。创建//创建不可变valmap:Map[String,Int]=Map("a"->1,"b"->2)//创建可变valmMap:mutable.Map[String,Int]=mutable.Map("aa"->1,"bb"->2,"cc"->3)增加valmap1:Map[String,Int]=map+("c"->3)println(map1.mkString(","))-------------------------------------------a->1,b->2,c->3修改valmap2:Map[String,Any]=map.updated("a","11")println(map2.mkString(","))//可变Map可以这样改mMap("aa")=11println(mMap.mkString(","))//还可以通过添加覆盖的思想修改valmap4:Map[String,Any]=map+("a"->"22")println(map4.mkString(","))---------------------------------------------------a->11,b->2aa->11,bb->2,cc->3a->22,b->2健取值vali:Int=map("a")println(i)---------------------1删除valmap3:Map[String,Int]=map-"a"println(map3.mkString(","))--------------------------------------b->2
引言Scala数组分为两大类可变(mutable)和不可变(immutable)Array()数组介绍Array为不可变数组不可变是指内存地址不变,一但确定,数组的长度不能变创建valints:Array[Int]=Array(1,2,3,4,5)数组取值注意是()ints(0)修改元素updata(索引,新值)//按照索引修改ints.update(1,10)//updata(索引,新值)添加元素不可变数组添加元素是指添加后产生新的数组,并不是在原数组添加//注意连接的符号valints1=ints:+12println(ints1.mkString(","))----------------------------1,2,3,4,5,12valints2=15+:intsprintln(ints2.mkString(","))----------------------------12,1,2,3,4,5遍历数组使用for循环遍历for(elem<-ints){println(elem)}使用方法foreach(函数)函数返回值要是Unit函数接收的参数就是数组的元素//下面是简化过程ints.foreach((i:Int)=>{println(i)})ints.foreach(println(_))ints.foreach(println)ArrayBuffer()介绍ArrayBuffer()为可变数组创建valarrayBuffer:ArrayBuffer[String]=ArrayBuffer("a","b","c","d")添加元素insert(索引,新元素)插入元素arrayBuffer.insert(1,"B")println(arrayBuffer.mkString(","))----------------------------------a,B,b,c,d+=组合元素+==组合数组arrayBuffer+="e"println(arrayBuffer.mkString(",")---------------------------------a,b,c,d,earrayBuffer++=Array("a","zz")println(arrayBuffer.mkString(",")---------------------------------a,b,c,d,e,a,zz删除元素使用索引删除arrayBuffer.remove(1)//索引删除arrayBuffer.remove(1,2)//从索引开始删几个arrayBuffer-=1删除数组中的指定元素数组中没有找到也不会报错arrayBuffer--=Array("a")修改元素arrayBuffer(0)="A"查看元素//通过索引获取println(arrayBuffer(0))遍历数组//函数arrayBuffer.foreach(println(_))//for循环for(buffer<-arrayBuffer){println(buffer)}数组可变性的转换可变转不可变toArrayvalarray:Array[String]=arrayBuffer.toArray不可变转可变toBuffervalbuffer1:mutable.Buffer[Int]=ints.toBuffer
引言Scala不仅是完全面向函数编程,还是完全面向对象语言。格式类的定义class类名{//类主体//定义类属性//Scala类属性是需要初始化的,初始化只需要_(下划线)就可以了varname:String=_varage:Int=_//类方法defshow(){函数逻辑}}类的使用//创建类对象val对象名:类属性=new类名称//获取类属性对象名.属性名//设置类属性对象名.属性名=值//执行类方法对象名.方法名()如果使用val声明属性,属性将不能被修改,底层会有final修饰私有属性属性被private修饰,将不能在类外边直接访问。小案例定义User类classUser{varname:String=_varage:Int=_defshow():Unit={println(s"name:$name;age:$age")}}类使用objectdemoextendsApp{//创建类对象valuser:User=newUser()//设置类属性user.name="Bob"user.age=16//获取类属性println(user.name)//执行类方法user.show()}----------------------------------Bobname:Bob;age:16
引言会涉及_(下划线)的其中一个用法Scala的宗旨:至简。所以把匿名函数作为函数的参数,可以进行很大程度的简化有一个参数的简化定义一个函数deffun(f:Int=>Unit):Unit={f(12)}执行函数传入匿名函数fun((a:Int)=>{println(a)})匿名函数的参数类型,可以被自动推断出来,可以简化fun((a)=>{println(a)})参数只有一个,代码在一行,代码块括号可以简化fun(a=>println(a))下面是println()函数的特殊简化,println()本身也是一个函数参数后面只用一次,可以用_(下划线)代替fun(println(_))fun(println)---------------12有多个参数的简化定义一个函数(两个参数)deffn(f:(Int,Int)=>Int):Unit={println(f(12,23))}执行函数传入匿名函数fn((a:Int,b:Int)=>{a+b})匿名函数的参数类型,可以被自动推断出来,可以简化fn((a,b)=>{a+b})代码在一行,代码块括号可以进一步简化fn((a,b)=>a+b)如果参数只用了一次可以使用_fn(_+_)-------35
引言Scala不仅是完全面向对象语言,而且还是完全面向函数编程语言,所以Scala叫做多范式编程语言,Scala的函数非常强大函数可以作为函数的返回值函数可以作为函数的参数函数可以赋值给变量函数作为返回值函数作为返回值,需要注意_(下换线)的用法把返回值函数写在外边//定义一个函数,作为返回值deffun(name:String):Unit={println(s"fun_name=$name")}//定义执行函数deffun1(name:String)={//加个_(下划线)表名该函数是返回值println(s"fun1_name=$name")fun_}//执行函数,返回值函数不会被执行fun1("Bob")-------------------------fun1_name=Bob//执行返回值函数fun1("Bob")("bigdataboy")-------------------------fun1_name=Bobfun_name=bigdataboy把返回值函数写在内部函数执行结果与上面一样,只是这样写跟容易理解deffun1(name:String)={//返回值函数deffun(name:String):Unit={println(s"fun_name=$name")}println(s"fun1_name=$name")fun_}函数柯里化就是把上面的格式进行简化,通过函数调用就可以看出来所以Scala里就会看到()()()()()()这样的调用deffun(name:String)(name1:String):Unit={println(s"name=$name")println(s"name1=$name1")}fun("Bob")("Bbigdataboy")----------------------------------------------fun1_name=Bobfun_name=bigdataboy函数作为参数把函数作为参数,不同点在于规定参数类型时的写法不一样deffun(f:String=>Unit):Unit={f()}//定义参数类型解析f:String=>Unit参数名称:传入函数的参数类型=>传入函数的返回值类型小例子自定义传入一段逻辑(函数)给函数deffun(f:Int=>Int,num:Int):Unit={//执行传入的函数(有参数也需要传参数)println(f(num))}参数函数//把传入的参数不做任何处理直接返回deffn(n:Int):Int={n}执行函数fun(fn,5)---------5传入匿名函数(作为参数)这也是Spark用的最多的,匿名函数可以看看这个//定义一个函数deffun(f:()=>Unit):Unit={f()}执行函数(传入匿名函数)fun(()=>{println("Hellobigdataboy")})---------------------------------------Hellobigdataboy函数赋值给变量变量可以接受一个匿名函数valadd=(a:Int,b:Int)=>a+b//调用println(add(12,34))---------------------------------46
如果你有Python基础,那么Scala的函数基础使用,你能快速的上手格式def函数名(参数名:参数类型,参数名:参数类型):返回值类型={方法体}defmani(args:Array[String]):Unit={print("Helloworld")}函数的入参(参数)和出参(返回值)有参数有返回值deffun(a:String):String={returna+"bigdataboy.cn"}println(fun("https://"))有参数没有返回值deffun(a:String):Unit={println(a)}fun("bigdataboy.cn")没有参数有返回值deffun():String={"HelloScala"}println(fun())没有参数没有返回值deffun():Unit={println("HelloScala")}fun()可变参数与Python类似,用*号表示可变参数可以传参,也可以不传参可变参数一般放在参数列表的最后面deffun(name:String*):Unit={println(name)}fun()fun("Bob","Black")--------------------------------List()ArraySeq(Bob,Black)默认参数默认参数与Python类似deffun(name:String,age:Int=13)={println(name,"-",age)}fun("Bob")fun(name="Bob",age=16)---------------------------------------(Bob,-,13)(Bob,-,16)精简函数格式如果能通过最后一行,推测出返回值类型,就可以不写返回值类型deffun()={println("Scala")"Scala"}//调用println(fun())--------------------ScalaScala可以使用分号隔开逻辑写成一行deffun()={println("Scala");"Scala"}//调用println(fun())--------------------ScalaScala在一行就可以去掉大括号。去掉大括号,写在一行就只对最近的一个逻辑有效,所以后面打印的是()deffun()=println("Scala");"Scala"//调用println(fun())--------------------Scala()如果函数,没有参数,可以去掉参数括号,但是在调用的时候,也不用加括号deffun=println("Scala");"Scala"//调用println(fun)-----Scala()小技巧:当明确没有返回值时,函数的=可以省略,编译器也就不会把最后一行代码作为返回值。deffun4(){println("Scala");"Scala"}println(fun4())--------------------------------------Scala()匿名函数格式()->{代码块}例子()->{vara=1varb=2println(a+b)}//写成一行分号区分代码块()->{vara=1;varb=2;println(a+b)}-------------------------------------------3
格式for(i<-0to|until5){循环体}for(i<-1to5){println(s"i=$i")}i:i是接收for循环次数的变量,不用声明是因为Scala能自动推断to:是[0,5],是前后都包含的意思until:是[0,5),是前包含后不包含的意思详解to和until到Range()控制循环步长1.to(5)-简写->1to50.until(5)-简写->0until5until和to的源码里都调用了一个Rang()的方法,所以for循环还能这样写for(i<-Range(0,5)){println(s"第$i次")}----------------------第0次第1次第2次第3次第4次Range()控制循环步长for(i<-Range(0,5,2)){println(s"第$i次")}----------------------第0次第2次第4次小案例一层循环打印九层妖塔for(i<-Range(1,18,2)){println(""*((18-i)/2)+"*"*i+""*((18-i)/2))}守卫循环循环守卫:所谓循环守卫就是加一个判断,成立执行循环体,不成立跳过本次循环跟Java和Python中的continue一样for(i<-1to6ifi%2==0){println(s"i=$i")}-------------------------------i=2i=4i=6其实也可以等价于for(i<-1to6){if(i%2==0){println(s"i=$i")}引入变量格式//原本格式,分号隔开for(i<-1to5;f=i%2){println(s"i=$i:f=$f")}//写一行;隔开逻辑,注意大括号for{i<-1to5;f=i%2}{println(s"i=$i:f=$f")}//不要分号换行隔开逻辑for{i<-1to5f=i%2}{println(s"i=$i:f=$f")}所以小案例变换//要分号for{i<-Range(1,18,2);j=((18-i)/2)}{println(""*j+"*"*i+""*j)}//不要分号代码块for{i<-Range(1,18,2)j=((18-i)/2)}{println(""*j+"*"*i+""*j)}for的返回值一般情况for都没有返回值//for的返回值一般情况for的返回值都是Unitvalres:Unit=for(i<-1to5){"abc"}yeild特殊情况它会把结果返回成一个集合valvalue=for(i<-1to5)yieldiprintln(value)-------------------------------------Vector(1,2,3,4,5)for跳出循环Scala是完全面向对象的语言,所以没有break。Scala使用的产生一个特定的异常,然后进行类似异常处理来保证后面代码的正常运行//产生异常,结束循环for(i<-1to5){if(i==3){Breaks.break()}println(s"s=$i")}----------------------s=1s=2Exceptioninthread"main"scala.util.control.BreakControl对异常进行特定处理,保证后面正常运行Breaks.breakable(//这对小括号可以换成大括号(表示包裹代码块)for(i<-1to5){if(i==3){Breaks.break()}println(s"s=$i")})println("跳出循环")---------------------------s=1s=2跳出循环
单分支结构式varfalg=trueif(falg){println("true")}双分支结构式varfalg=trueif(!falg){println("true")}else{println("false")}多分支结构式varname="a"if(name.equals("a")){println("a")}elseif(name.equals("b")){println("b")}else{println("未知")}小技巧当判断的代码块不写{}时,只对最近的一行代码有效//两种结果写法一样varfalg=trueif(falg)println("true")if(falg){println("true")}var&=trueif(!&)println("true")elseprintln("false")条件判断的返回值在Scala中,任何的表达式都有返回值条件判断的返回值就是每个代码块的最后一行的返回值返回值类型Any,AnyVal返回类型最方便是不写Any是返回值类型是String和Unit等等AnyVal是返回值类型是Int和Unit等等varmsg=truevalreg:Any=if(msg){"abc"//Scala可以这样单独写个值,Java不行}println(reg)定义返回值类型需要能确定全部返回类型varmsg=truevalreg:String=if(msg){"true"}else{"false"}println(reg)Scala中的“三元运算符”Scala中没有标准的三元运算符,也没有必要有,就省略了//Java中的三元运算符Stringnum=if(13==12)?"0":"1"//Scala中模拟的三元运算符varnum=if(13==12)"0"else"1"