scala的下载地址
https://www.scala-lang.org/download/2.11.7.html
1.确保你本地已经安装了 JDK 1.5 以上版本,并且设置了 JAVA_HOME 环境变量及 JDK 的 bin 目录。
2.安装scala环境变量
最后:cmd,scala指令验证
1.下载scala插件
2.创建项目:
1.scala的变量和常量
变量:var(variable的缩写),变量赋值后可以修改的
常量:val(value的缩写),常量一经赋值,不允许修改
2.scala是以换行符为一条语句的结束标识,所以不需要加;
3.如果要在一行中写多条语句,则需要用;隔开 比如:val v1 =“hello”;val v2=150
4.scala不需要显示指定对象的类型,可以根据结果自动推断出类型
5.scala也可以显示指定对象的类型,比如: val v3:Int=100
6.变量var赋值后可以修改,但是需要和初始类型保持一致
7.scala中没有基本类型。即Int,Char,Double,Float,Boolean,等在scala中都是一个类。(和java有所不同)比如:val v1 =“hello”;val v2=150的v1和v2都是类。所以scala的面向对象要比java更彻底
8.scala中的顶级父类是Any,可类比与Java的Object
10.scala中用于对象、类、方法的名称成为标识符。标识符分带小写,关键字不能作为标识符,命名规则:
①类名首字母大写
②方法名首字母小写
③可以由字母、数字、下划线和$组成。但建议:最好不要用下划线_和 $ 。因为在scala底层有特殊作用
④不能由数字开头
11.scala中一共由39个关键字
val var true false null try catch finally throw class object this super private protected extends with override import package abstract trait new type lazy if else do while for yield match case def return implict forsome final
12.scala中通过下标 *** 作集合类型时,是通过(index),不同于java[index]
1.scala的运算符包含以下几种类型:
①算数运算符:+ - * / %
②关系运算符:== != > < >= <=
③逻辑运算符:&& || !
④位运算符:! ^ << >>
⑤赋值运算符:= += -= *= /= %=
注意:scala中没有三目(三元)运算符,也没有++ -- *** 作符
2.scala的算数运算符优先级同java。但注意:也可以通过方法的形式来 *** 作,则此时按方法的调用顺序执行
3.如果想通过scala的手册去查方法,可以在scala安装目录\api\scala-library\iindex.html
object Demo1 {
def main(args: Array[String]): Unit = {
val s1 = "hello"
//结果:hellohello
print(s1.*(2))
//取出前n个元素
println(s1.take(2))
//取出后n个元素
println(s1.takeRight(2))
//去掉前n个元素,并返回剩余元素
println(s1.drop(2))
//去掉后n个元素,并返回剩余元素
println(s1.dropRight(2))
//处理s2,获取文件名file01
val s2 = "G_data_file01.txt";
println(s2.takeRight(10).take(6))
println(s2.takeRight(10).dropRight(4))
println(s2.drop(7).take(6))
println(s2.drop(7).dropRight(4))
println(s2.split("_").last.dropRight(4))
//scala中通过下标 *** 作集合类型时,是通过(index),不同于java[index]
//s2字符串切割返回字符串数组用(2)访问
println(s2.split("_")(2).dropRight(4))
}
}
上面代码结果依次为下图:
4.scala的类型转换,形式固定:to指定类型。比如:toInt toString toLong toArray toList(toArray toList后面介绍)
object Demo2 {
def main(args: Array[String]): Unit = {
val s3 = "100"
println(s3.toInt)
println(s3.toDouble)
println(100.toString)
val num = 1
//to方法用于生成指定的一个区间。常用于for循环遍历的次数区间
//因为1是对象所以可以点出to方法
println(num.to(5))
println(1.to(5))
//生成一个区间,并指定步长为2
println(1.to(5,2))
//同to方法,生成区间。但是不包含尾元素
println(1.until(5))
println(1.until(5,2))
}
}
上面代码结果依次为下图:
1.scala中的if else作用同java。不同的在于:scala的if els有返回值可以接
2.scala中的Unit类相当于void空类型
3.scala中通用规则:会将方法体{}中最后的那一行代码作为返回值返回,不需要加return关键字
4.scala中print或者println的返回值为Unit,打印到控制台为{}
5.scala中通用的化简规则:如果方法体{}中只有一行代码,则方法体{}可以省略
object Demo3 {
def main(args: Array[String]): Unit = {
val num = 5
//scala中的Unit类相当于void空类型
//scala中print或者println的返回值为Unit,打印到控制台为{}
val result1 = if(num>5){
println("if分支内部result1 = "+"big")
}else{
println("if分支内部result1 = "+"small")
}
println("result1 = "+result1)
//scala中通用规则:会将方法体{}中最后的那一行代码作为返回值返回,不需要加return关键字
val result2 = if(num>5){
println("if分支内部result2 = "+"big")
"big"
}else{
println("if分支内部result2 = "+"small")
"small"
}
println("result2 = "+result2)
//scala中通用的化简规则:如果方法体{}中只有一行代码,则方法体{}可以省略,
// 其实这个结构和java的三元运算符感觉差不多,所以scala没有三元运算符
val result3 = if(num>5) "big" else "small"
println("result3 = "+result3)
if(num>5){
println("result4 = "+"big")
}else if(num==5){
println("result4 = "+"equal")
}else{
println("result4 = "+"small")
}
}
}
上面代码结果依次为下图:
6.scala中while用法同java。
7.for循环的各种使用和讲解
object Demo4 {
def main(args: Array[String]): Unit = {
val a1 = Array(1,2,3,4)
//这里固定写法,与java不同,scala比较简便
for (i<-a1){
println(i)
}
//练习1:通过scala的for打印从1到10的数字
//这里用的1.to()写法也比java简便,如一行代码也可以省略方法体
for (i<-1.to(10)) println(i)
//练习2:打印9*9乘法表。分隔符统一用制表符
for (a<-1.to(9)){
for(b<-1.to(a)){
print(b+"*"+a+"="+a*b+"\t")
}
println()
}
//练习3:通过for遍历1~10,只打印大于6的偶数数字
for(i<-1.to(10)){
if(i%2==0 && i>6){
println(i)
}
}
//可以将判断语句写道for()里,称为for的守卫式。多个条件之间用;隔开
//改造练习3
for(i<-1.to(10);if i%2==0;if i>6) println(i)
//也可以如下
for(i<-1.to(10);if i%2==0&& i>6) println(i)
//练习2也可以用守卫式改造
//在使用for守卫式赋值时,必须用常量(val)来接,也可以把(val)省略
for(a<-1.to(9);b<-1.to(a);val sep=if(a==b)"\r\n" else "\t"){
print(b+"*"+a+"="+b*a+sep)
//上面一行也可以改成如下形式
//scala在 *** 作String时,可以通过s函数配合$来进行取值 *** 作
// print(s"$b*$a=${b*a}$sep")
}
val a2 = Array(1,2,3,4)
//for yield表达式:遍历一个集合,并将 *** 作的数据返回到一个新的集合中
//scala的集合是大的概念,包含Array,List,Set,Range,Iterator,Map
//for yield遍历的是什么集合类型,则返回对应类型的新集合。
val a3 = for(i<-a2)yield(i*2)
val l1 = List(1,2,3,4)
for (i<-l1)yield {i*2}
val m1 = Map("tom"->23,"rose"->18,"jarry"->30)
//遍历map的k,v对
for (i<-m1){
println(i)
}
//通过二元元组形式来遍历map
for ((k,v)<-m1){
println(v)
}
}
}
8.scala中没有switch case.取代的是match case
9.scala的match case有返回值。可以接
10.注意:match case只要发现有一个匹配,则剩下的case不会继续匹配
object Demo5 {
def main(args: Array[String]): Unit = {
val num = 6
val result = num match {
case 5=>{
println("result1="+"555")
"555"
}
case 6=>{
println("result1="+"666")
"666"
}
case 7=>{
println("result1="+"777")
"777"
}
}
println(result)
val s2 = 8
s2 match {
case x if x>5=>{println("result2="+"555")}
case x if x>5=>{println("result2="+"666")}
case x if x>5=>{println("result2="+"777")}
}
}
}
上面代码结果依次为下图:
11.scala通过import关键字导包。比如import a._ 表示导入a包下所有类
12.scala可以在任意位置导包。但注意作用域问题
13.scala实现break的continue的方式:(个人觉得这种设计有点麻烦,还不如java)
①导包:import util.control.Breaks._
②要实现break:breakable(for(){break跳出循环效果})
③要实现continue:for(){breakable(break->continue效果)}
object Demo6 {
def main(args: Array[String]): Unit = {
breakable(
for(i<-1.to(5)){
if(i==3){
break
}else{
println(i)
}
}
)
println("====================")
for(i<-1.to(5)){
breakable(
if(i==3){
break
}else{
println(i)
}
)
}
}
}
上面代码结果依次为下图:
1.scala的异常处理机制同java。只不过形式上有区别。在catch中是通过case来匹配异常然后进行处理
object Demo7 {
def main(args: Array[String]): Unit = {
try {
throw new RuntimeException
}catch {
case t:NullPointerException =>{
println("null error")
}
case t:Exception=>{
println("other error")
}
}finally {
println("end")
}
}
}
上面代码结果依次为下图:
1.scala定义一个函数的形式:访问修饰符def函数名(形参名:类型,型参数名:类型,…):返回值类型={方法体}
2.访问修饰符可以是private或protected。如果没有访问修饰符,则是public
3.scala的通用规则:会将函数方法体的最后一行代码做为结果返回。不需要加return关键字
4.scala会根据函数的返回值自动推断出函数的返回值类型
5.注意:如果定义函数时,{}前没有=,则函数的返回值一律为Unit。比如该方法就一个println()
所以,建议在定义函数时,都带有=
6.scala的函数支持默认参数机制。形式:def 函数名(型参名:类型=默认值){}
7.scala的函数支持变长参数机制。可类比于java的可变参数机制。注意:可变参数必须位于参数列表的最后。
object Demo8 {
def main(args: Array[String]): Unit = {
//scala定义一个函数的形式:访问修饰符def函数名(形参名:类型,型参数名:类型,...):返回值类型={方法体}
def f1(a:Int,b:Int):Int = {
a+b
}
println(f1(2,3))
//scala会根据函数的返回值自动推断出函数的返回值类型
def f2(a:String,b:Int) = {
a*b
}
println(f2("hello",2))
//scala的函数支持变长参数机制。可类比于java的可变参数机制。注意:可变参数必须位于参数列表的最后。
def f3(a:String*)={
for(i<-a){
println(i)
}
}
f3("hello","world","scala")
}
}
四种函数类型
1.scala的函数可分为如下4种:
①成员函数,定义在类(class或object)内部的函数,做为类的成员,称为成员函数
②本地函数,定义在函数内的函数,称为本地函数
③匿名函数,最直观的特点:①没有函数名②方法体{}的连接符=>,关键匿名函数的作用:①把匿名函数作为参数进行赋值②把匿名函数做为参数进行传递
④高阶函数:把函数当作参数传递的函数称为高阶函数
object Demo9 {
def main(args: Array[String]): Unit = {
//匿名函数
//(a:Int,b:Int) =>{a+b}
//把函数当作参数进行赋值
val f2 = (a:Int,b:Int)=>{a+b}
println(f2(2,3))
//把匿名函数当做参数进行传递
//本例中,f3是一个高阶函数
//匿名函数一般和高阶函数一起出现
def f3(a:Int,b:Int,f:(Int,Int)=>Int) = {
f(a,b)
}
println(f3(2,3,(a:Int,b:Int) =>{a+b}))
println(f3(2,3,(a:Int,b:Int) =>{a-b}))
println(f3(2,3,(a:Int,b:Int) =>{a*b}))
}
}
scala通用的简化规则
object Demo10 {
def main(args: Array[String]): Unit = {
//1.如果方法体{}只有一行代码,则方法体可以省略
//2.如果在调用scala一个方法时,方法的参数只有一个,则方法的.()可以省略
val s1="hello world"
s1.take(2)
s1 take 2
1.to(5)
1 to 5
//生成区间并指定步长,可以这样表达
1 to 5 by 2
1.until(2)
1 until 2
1 until 5 by 2
//3.匿名函数也可以简化。简化匿名函数的规则:
//①如果匿名函数参数类型可以推断,则参数类型可以省略
//②如果匿名函数参数只有一个,则参数列表的()可以省略
//③最终极的化简规则:可以通过_来代替参数进行化简
def f2(a:Int,b:Int,f:(Int,Int)=>Int)={
f(a,b)
}
f2(2,3,(a:Int,b:Int)=>{a+b})
//省略了匿名函数的参数类型(满足:①如果匿名函数参数类型可以推断,则参数类型可以省略)
f2(2,3,(a,b)=>a+b)
f2(2,3,(a,b)=>a*b)
//按道理你就是做相加相乘,可以简洁一下
f2(2,3,_+_)
f2(2,3,_*_)
def f3(a:String,f:(String)=>String)={
f(a)
}
f3("hello",(a:String)=>{a*2})
//②如果匿名函数参数只有一个,则参数列表的()可以省略
f3("hello",a=>a*2)
}
}
柯里化Currying技术
/**
1.scala底层支持柯里化技术,可以将接受多个参数的函数,转变为接受单一参数的函数(这些概念都来自于函数编程,函数编程都有这些东西)
2.通过柯里化技术,可以自建流程控制结构。很多方法调用时都是这种结构
**/
object Demo11 {
def main(args: Array[String]): Unit = {
def f1(a:Int,b:Int)={a+b}
f1(2,3)
//柯里化的表达方式
def f11(a:Int)(b:Int)={a+b}
f11(2)(3)
def f2(a:Int,b:Int,f:(Int,Int)=>Int)={f(a,b)}
//如上柯里化到下面这种形式
//留意这种形式,一部分都是普通参数,另一部分时匿名函数
//这种形式称为自建的控制结构。调用结构层次更加清晰
def f22(a:Int,b:Int)(f:(Int,Int)=>Int)={f(a,b)}
f22(2,3)((a:Int,b:Int)=>{a+b})
//以下简化写法
f22(2,3)((a,b)=>a+b)
f22(2,3)(_+_)
}
}
类(class)
1.scala同java。通过class来定义一个类
2.scala的类可以拥有成员变量和成员方法
3.成员变量和成员方法默认的访问权限是public。此外,可以通过private或protected来修饰
4.定义成员变量时,必须赋初始值
5.scala同Java。通过new来创建类对象
6.scala的类可以定义一个主构造器和多个辅助构造器
7.主构造器只能由一个,在类上声名的。比如class Person(n:String,a:Int)
8.辅助构造器可以定义多个,在类里声名的。
注意:辅助构造器中需要调用本类的其他构造器。一般是调用主构造器
9.scala的class中不能定义静态成员或静态方法,此外也没有static关键字。
静态成员或者静态方法需要在object(单例对象)中定义
10.object可以单独存在,也可以和某个class绑定。
注意:绑定时,object和class必须同一个文件中,并且名字一致。
通过这种方式,相当为class添加了静态成员和静态方法
11当object和class绑定时,就会产生一个绑定关系。此时。object时class的半生对象;class是object的伴生类
12.object不能new。直接用类名。方法名或类名,成员来调用
13.main方法是程序的执行入口方法,是静态方法。所以main方法必须写在object中才能执行
14.scala也支持重写和重载。概念同java
15.scala也支持类的继承。概念同java,通过extends关键字来继承
16.在重写时,如果一个普通方法,则需要加override关键字,如果是一个抽象方法,则不需要override
17.scala也支持定义抽象类,概念同java,通过abstact关键字来定义,
在scala的抽象类中,可以定义普通方法和抽象方法
18.抽象方法没有方法体
19.scala也有
package cd.sc
/**
1.scala同java。通过class来定义一个类
2.scala的类可以拥有成员变量和成员方法
3.成员变量和成员方法默认的访问权限是public。此外,可以通过private或protected来修饰
4.定义成员变量时,必须赋初始值
5.scala同Java。通过new来创建类对象
6.scala的类可以定义一个主构造器和多个辅助构造器
7.主构造器只能由一个,在类上声名的。比如class Person(n:String,a:Int)
8.辅助构造器可以定义多个,在类里声名的。
注意:辅助构造器中需要调用本类的其他构造器。一般是调用主构造器
9.scala的class中不能定义静态成员或静态方法,此外也没有static关键字。
静态成员或者静态方法需要在object(单例对象)中定义
10.object可以单独存在,也可以和某个class绑定。
注意:绑定时,object和class必须同一个文件中,并且名字一致。
通过这种方式,相当为class添加了静态成员和静态方法
11当object和class绑定时,就会产生一个绑定关系。此时。object时class的半生对象;class是object的伴生类
12.object不能new。直接用类名。方法名或类名,成员来调用
*/
**/
class Person(n:String,a:Int) {
private var name = n
private var age = a
//定义一个辅助构造器。只接受姓名
def this(n:String){
this(n,0)
}
//定义一个辅助空构造器
def this(){
this("",0)
}
def setName(name:String)={
this.name=name
}
def getName()={
this.name
}
def setAge(age:Int)={
this.age=age
}
def getAge() ={
this.age
}
def say() = {
println("hello world")
}
}
object Person{
def speak(): Unit ={
println("say world")
}
}
package cd.sc
/**
12.object不能new。直接用类名。方法名或类名,成员来调用
13.main方法是程序的执行入口方法,是静态方法。所以main方法必须写在object中才能执行
*/
object Util {
var food = "";
def cook()= {
println("cook food")
}
def main(args: Array[String]): Unit = {
Util.cook()
}
}
package cd.sc
/**
* 14.scala也支持重写和重载。概念同java
* 15.scala也支持类的继承。概念同java,通过extends关键字来继承
*
* */
class Student extends Person {
override def say(): Unit = {
println("say hello")
}
}
package cd.sc
/**
* 16.在重写时,如果一个普通方法,则需要加override关键字,如果是一个抽象方法,则不需要override
*/
//快捷键:ctrl+i
class ZhangTeacher extends Teacher {
def makeNode(info: String): String = {
???
}
def taach(): Unit = {
???
}
override def say()= {
println("world")
}
}
package cd.sc
/**
*16.在重写时,如果一个普通方法,则需要加override关键字,如果是一个抽象方法,则不需要override
* 17.scala也支持定义抽象类,概念同java,通过abstact关键字来定义,
在scala的抽象类中,可以定义普通方法和抽象方法
18.抽象方法没有方法体
*/
abstract class Teacher {
//抽象方法
def makeNode(info:String):String
//抽象方法
def taach():Unit
//普通方法
def say()= {
}
}
特质(trait)
1.sala也有接口,在scala中被称为特质(trait)。即可以将trait类比于java的接口,可以在trail中定义抽象方法
2.类可以混入特质。而且可以混入多个特质
即scala的class满足:单继承,多混入
用with关键字来混入
3.scala的trait和java接口不同的在于:
scala的trait中既可以定义抽象方法,也可以定义普通方法。
这样设计,实际上实现了多继承效果了。
4.在混入特质时,可以使用with混入。此外,如果extends没有被占用,则也可以使用extends关键字来混入特质,但注意:extends只能用一次
5.scala支持泛型,使用[泛型类型]不同于java的<泛型类型>,用的符号不一样
package cd.sc
/**
* 1.sala也有接口,在scala中被称为特质(trait)。即可以将trait类比于java的接口,可以在trail中定义抽象方法
*/
trait Dance {
def baLei():String
def tiTa(n:Int):Int
}
/**
* 3.scala的trait中既可以定义抽象方法,也可以定义普通方法。
*/
package cd.sc
trait Drive {
def piaoyi():Unit
def shache():String
def start()={
}
}
package cd.sc
/**
*2.类可以混入特质。而且可以混入多个特质即scala的class满足:单继承,多混入用with关键字来混入
* 3.在混入特质时,可以使用with混入。此外,如果extends没有被占用,则也可以使用extends关键字来混入特质,但注意:extends只能用一次
*/
//快捷键:ctrl+i
//class ZhangTeacher extends Dance with Drive {删除继承,这样就可以用extend实现接口了
class ZhangTeacher extends Teacher with Dance with Drive {
def makeNode(info: String): String = {
???
}
def taach(): Unit = {
???
}
override def say()= {
println("world")
}
override def baLei(): String = {
???
}
override def tiTa(n: Int): Int = {
???
}
override def piaoyi(): Unit = ???
override def shache(): String = ???
}
样例类
1.scala提供了一种样例类。通过case关键字来定义
2.case class必须显示的声明一个主构造器
3.case class底层会自动构造一个空的辅助构造器
4.case class会自动混入序列化特质,相当于省略了extends Serializable
5.case class会默认重写类的toString方法,便于打印测试
6.case class不需要new,就可以创建类对象
后续开发spark程序时,封装bean习惯上使用case class来封装
package scalacase
case class Item(title:String,Price:Double){
}
package scalacase
object Demo {
def main(args: Array[String]): Unit = {
val item = Item("huawei", 2999.9)
println(item)
}
}
上面代码结果依次为下图:
1.scala支持机制,通过lazy关键字来定义。即声明并不是马上赋值,而是正真被调用时才会赋值
2.lazy只能修饰常量val。不能修饰变量var
3.scala的Option类有两个子类,分别是Some和None
4.通过getOrElse(默认值)来 *** 作Option。如果是Some,则获取Some里的结果。
如果是None,则返回值的默认值
package scalacase
object Demo {
def main(args: Array[String]): Unit = {
// val item = Item("huawei", 2999.9)
// println(item)
lazy val v1 = 100
def f1(a:Int,b:Int) ={
if(b!=0){
Some(a/b)
}else{
None
}
}
println(f1(4,2))
//有值返回值,2
println(f1(4,2).getOrElse(1000))
println(f1(4,0))
//为None就返回默认值1000
println(f1(4,0).getOrElse(1000))
}
}
上面代码结果依次为下图:
1.隐式方法
2.隐式类
3.隐式参数(隐式对象)
package scalacase
/**
* 1.scala implicit关键字用于定义隐式方法、隐式类、隐式对象
* 2.隐式转换的意义和作用在于:当一个转换不合法时,在当前的作用域能够找到对应的隐式转换,使得转换变得合法,
* 3.需要注意的事项:定义隐式方法时,并不关注方法名,关键的是在于将参数转换成什么类型。
* ①所以隐式方法的参数只能有一个
* ②在同一个作用域中,不能存在多个相同的类型转换的隐式方法
* 4.scala支持定义隐式类,形式:implicit class 方法名( *** 作类型:String){
* def 方法1()={}
* def 方法2()={}
* }
*/
object Demo02 {
def main(args: Array[String]): Unit = {
val v1 =100
//一、隐式方法
//一种方式:做显示的类型转换。形成国定,to指定类型
val v2:String=v1.toString()
//另一种方式:做隐式转换函数
//可以定义一个隐式转换方法,完成隐式的类型转换
//implicit 关键字 用于定义隐式方法,以及隐式类和隐式参数
implicit def f1(x:Int)={x.toString()}
val v3:String=v1
//二、隐式类
implicit class AuthMethod(x:String){
def suffix()={
x.split("\.").last
}
def prefix()={
x.split("\.").head
}
}
//想实现 *** 作字符串,调用suffix()提取后缀
println("hello.zip".suffix())
println("1.txt".prefix())
//三、隐式参数(隐式对象)
trait Adder[T]{
def add(x:T,y:T):T
}
//该注释部分使用使用下面未注释部分隐式转换实现
// def f2(x:Int,y:Int)(adder:Adder[Int])={
// adder.add(x,y)
// }
//
// println(f2(2,3)(new Adder[Int]{
// override def add(x:Int,y:Int)={x+y}
// }))
//
// val a=new Adder[Int]{
// override def add(x:Int,y:Int)={x+y}
// }
// println(f2(2,3)(a))
//这两种隐式方式相同,都能得到隐式参数
def f2(x:Int,y:Int)(implicit adder:Adder[Int])={
adder.add(x,y)
}
implicit val a=new Adder[Int]{
override def add(x:Int,y:Int)={x+y}
}
//println(f2(2,3)(a))省略(a)参数
f2(2,3)
}
}
集合类型以及重要的函数
scala的集合类型包含:Array,List,Set,Map,Tuple,Range,Iterator
Array
package scalacase
/**
* Array
* 1.scala的Array分为定长和变长
* 2.定长:immutable
* 3.变长:mutable
* 4.通过下标 *** 作Array,下标从0开始
*/
object Demo03 {
def main(args: Array[String]): Unit = {
//创建了一个定长数组,并赋初始值
val a1=Array(1,2,3,4)
//创建了一个定长数组,并指定长度
val a2=new Array[Int](3)
//创建了一个变长数组(可以追加新元素),并赋初始值
val a3=scala.collection.mutable.ArrayBuffer(1,2,3,4)
//apply方法可以省略
//通过下标取值
println(a1.apply(0))
println(a1)
//通过下标赋值
a1(0)=10
println(a1(0))
//对变长数组
a3.append(5)
println(a3)
val a4=Array(2,1,5,3,6)
println(a4.max)
println(a4.min)
println(a4.sum)
println(a4.length)
println(a4.reverse)
//取出前n项,返回到新的集合里
val r1=a4.take(2)
//取出后n项,返回到新的集合里
val r2=a4.takeRight(2)
//取掉前n项,返回到新的集合里
val r3=a4.drop(2)
//取掉后n项,返回到新的集合里
val r4=a4.dropRight(2)
//返回集合的头元素,有别于take(1)
val r5=a4.head //2
val r6=a4.take(1)//Array(2)
//返回集合的尾元素
val r7=a4.last
val r8=a4.takeRight(1)
val a6=Array(1,2,3)
val a7=Array(3,4,5)
//取交集
val r9=a6.intersect(a7)
//取并集
val r10=a6.union(a7)
//去重
val r11=a6.distinct
//取差集,注意有方向
//交集和差集经常用在比较文件数据之间的异同场景
val r22=a6.diff(a7)
}
}
List
package scalacase
/**
* List
* 1.scala的List分为定长和变长。都是通过下标来 *** 作。下标从0开始
* 2.Array和List通用而且重要的方法:
* max、min、 sum、take、takeRight、head、last、mkString、intersect、union、diff、
* distinct、filter、exists、map、reduce、sortBy、reverse、foreach,groupBy,mapValue(对Map的value做映射)
*
* 重点掌握:1.map 2.filter 3.sortBy 4.reduce 5.groupby 6.mapValue
*/
object Demo04 {
def main(args: Array[String]): Unit = {
//创建了一个定长List,并赋值
val l1 = List(1, 2, 3, 4)
val l2 = scala.collection.mutable.ListBuffer(1, 2, 3, 4)
val l3 = List(1, 2, 3, 4, 5, 6, 7, 8)
//filter方法根据指定的匿名函数实现过滤
//将过滤出的元素返回到一个新的集合中
l3.filter { num => num > 4 } //l3.filter{num:Int=>{num>4}}简化而来
//练习:过滤出l4中的男性数据
val l4 = List("tom M 23", "rose F 18", "jary M 30", "jim F 35")
val r4 = l4.filter { line => line.split(" ")(1).equals("M") }
//exists方法是根据指定的匿名函数规则判断是否存在。
//如果元素存在返回True,不存在返回False
val l5 = List(1, 2, 3, 4, 5)
val r5 = l5.exists { num => num > 4 }
//map方法,映射方法。作用是:根据匿名函数规则,将集合中的元素从一个形式映射(转变)到另一个形式
//并将映射后的元素返回到新的集合中,元素个数不变,形式改变
val r6 = l5.map(num => num * 2)
val l6 = List("hello world", "hello scala")
val r7 = l6.map(line => line.split(" "))
//reduce方法归约方法。底层的处理机制
//第一次:a=1 b=2 a+b=3
//第二次:a=3 b=3 a+b=6
//第三次:a=6 b=4 a+b=10
//..
val r8 = l5.reduce { (a, b) => a + b }
//练习:通过reduce方法返回l9的最大数字
val l9 = List(3, 1, 5, 2, 4)
//reduce方法归约方法。底层的处理机制
//第一次:a=3 b=1 返回3
//第二次:a=3 b=5 返回5
//第三次:a=5 b=2 返回5
//第四次:a=5 b=4 返回5
val max = l9.reduce { (a, b) => if (b > a) b else a}
println(max)
//sortBy方法是根据指定的匿名函数规则排序,实现升序或降序
//将排序后的结果返回到新的集合中
//通过resverse到达降序的效果。也可以通过负号来实现降序排序,主要:负号前有空格
val r10=l9.sortBy{num=>num}.reverse
val r11=l9.sortBy{num=> -num}
//练习: *** 作l10,按数字做升序
val l10=List("b 3","a 4","c 2","d 1")
var r12=l10.sortBy{line => -line.split(" ")(1).toInt}
//按字母做降序排序。注意:负号只能用于数值类型的排序条件
var r13=l10.sortBy{line => line.split(" ")(0)}.reverse
r13.foreach{x => println(x)}
//Array和List相互转换
val a1=l10.toArray
val l11=a1.toList
//l5是一个定长list
//.::基于一个定长List拼接新元素,并返回一个新的List
val l12 = l5.::(6)
}
}
Set、Map
package scalacase
/**
* Set、Map
* 1.scala的Set作用和概念同java
* 2.scala的Set分为定长和变长
*/
object Demo05 {
def main(args: Array[String]): Unit = {
//创建了一个定长Set,里面自动去重
val s1=Set(1,1,2,2,3,3)
//创建了一个变长Set
val s2=scala.collection.mutable.Set(1,2,3,4)
//创建了一个定长Map
val m1=Map("tom"->23,"rose"->10,"jim"->25)
//创建了一个变长Map
val m2=scala.collection.mutable.Map("tom"->23,"rose"->20)
m2+=("jim"->25,"jary"->30)
//通过key *** 作map
println(m1.apply("tom"))
m1("tom")
//如果想避免报错抛异常,可以通过get(key)来取值
//返回值类型Option。如果key存在,则返回Some(value)
//如果key不存在,则返回None
println(m1.get("tom"))
println(m1.get("werewrw"))
println(m1.get("werewrw").getOrElse(0))
//获取Map的所有key
m1.keys.toList
//基于m3,过滤年龄大于20的kv对
val m3=Map("tom"->23,"rose"->18,"jim"->25)
val r1=m3.filter{case(k,v)=>v>20}
val r2=m3.map{case(k,v)=>(k,v+10)}
//mapValues方法,用于对Map类型的value做映射
val r3=m3.mapValues{v => v+10}
}
}
Tuple
package scalacase
/**
* Tuple 元组类型
*/
object Demo06 {
def main(args: Array[String]): Unit = {
//创建了一个元组
val t1=(1,2,"hello",3.5)
//通过元组位置下标 *** 作。元组的下标从1开始
println(t1._3)
//练习:取出t2中的4
val t2=(1,2,(3,4))
println(t2._3._2)
//练习:取出t3中数字5
val t3=(1,(2,3),(4,Array(5,6)))
println(t3._3._2(0))
val m1=Map("tom"->23,"rose"->18)
m1.filter{case(k,v)=>v>20}
m1.filter{x=>x._2>20}
m1.map{case(k,v)=>(k,v+10)}
m1.map{x=>(x._1,x._2+10)}
val l1=List(("bj",12000),("sh",8000),("bj",9200),("sh",13000))
//groupby按照指定的匿名函数分组,返回是一个Map结构
val r1=l1.groupBy(x=>x._1)
println(r1)
}
}
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)