Scala部分
在Scala中一切皆对象,一个数字也是一个对象,后面的加号就是方法。
在Scala语言中object是一个单例对象,定义在单例对象里面的所有的方法都是一个静态方法,不需要实例化就可以执行,不需要像Java一样先new一下,然后再去执行。
变量分为两种,一种是不可变的变量对应于函数式编程。另外一种是可变的变量对应于面向对象编程。比如Java和C就是面向对象编程,而Scala则是两种都有。
scala> val st="hello"
val s: String = hello
scala> println(s"$st") //s插值字符串
hello
scala> val i= 10
val i: Int = 10
scala> println(f"$st:i=$i%-4d字符串") //f插值字符串,可以让打印的结果格式化输出
hello:i=10 字符串
循环控制结构
if条件表达式
scala> val x=3
val x: Int = 3
scala> if(x>0){
| println(“"this is a positive number")
| }else if(x==0){
| println("this is zero")
| }else{
| println("negative")
| }
this is a positive number
scala> val a=if(x>0) 1 else -1
val a: Int = 1
scala> a
val res14: Int = 1
while表达式
for表达式
格式为:
for (变量 <-表达式){语句块}
例如:
scala> for(i<-1 to 5 by 2){println(i)} //指定步长为2
1
3
5
守卫表达式,格式为:
for (变量 <- 表达式 if 条件表达式)语句块
scala> for (i <- 1 to 5 if i%2==0)println(i)
2
4
//支持多个生成器
scala> for (i <- 1 to 2; j<- 1 to 2)println(i*10+j)
11
12
21
22
//for推导式,将yield的值赋值给变量r
scala> val r=for(i<-Array(1,2,3,4,5) if i%2==0)yield{println(i);i}
2
4
val r: Array[Int] = Array(2, 4)
scala> r
val res21: Array[Int] = Array(2, 4)
数据结构
1、数组Array
数组中每个元素的类型都一样,数组元素在赋值的时候,使用的是圆括号,而不是方括号
scala> val intValArr = new Array[Int](3) //声明一个长度为3的整型数组
val intValArr: Array[Int] = Array(0, 0, 0)
scala> val intValArr=Array(12,13,15) //声明整型数组,里面的数据类型可以让Scala自动推断
val intValArr: Array[Int] = Array(12, 13, 15)
2、元组Tuple
元组中每个元素的类型可以不同
scala> val tup = ("BIGDATA",2020,1.0)
val tup: (String, Int, Double) = (BIGDATA,2020,1.0)
scala> println(tup._1) //打印出第一个元素
BIGDATA
3、容器Collection
Seq使用0,1,2来进行索引,Map使用键进行索引,Set是无序的。
List是继承自LinearSeq,Vector和ArrayBuffer继承自IndexedSeq,因此List是一个具体实现的容器类了,而不是一个特质。
3.1、Seq
3.1.1、列表List
共享相同类型的不可变的对象序列,因此它被定义在immutable里面
scala> var strList=List("bigdata","hadoop") //声明一个List列表
var strList: List[String] = List(bigdata, hadoop)
scala> strList.head //使用head方法访问第一个元素
val res35: String = bigdata
scala> strList.tail //tail返回的是后面的一个列表
val res36: List[String] = List(hadoop)
3.1.2向量Vector
scala> val vec1=Vector(1,2)
val vec1: scala.collection.immutable.Vector[Int] = Vector(1, 2)
Range是一种特殊的带索引的不可变数字等差序列
scala> val r=Range(1,5,2)
val r: scala.collection.immutable.Range.Exclusive = Range 1 until 5 by 2
3.2集合Set
Set集合有两种不同的形式,可变与不可变的,默认使用不可变集合,对于不可变的集合,当使用val定义的时候,仍然可以使用+=方法进行赋值
scala> var myImmutableSet=Set("data","hadoop")
var myImmutableSet: scala.collection.immutable.Set[String] = Set(data, hadoop)
//对于不可变的为什么可以进行赋值,而且结果还是成功赋值了呢?
//原因是变量的声明是可变的,这样的赋值只不过是又在内存当中开辟了一块内存空间,这个myImmutableSet指向的地址发生了变化,
//当使用mutable里面的Set的时候,也可以这样去做,只不过那时候直接改变的是该地址的值,而不是从新开辟空间
scala> myImmutableSet+="scala"
scala> myImmutableSet.foreach(println)
data
hadoop
scala
3.3映射Map
这个是一系列键值对,就是相当于python中的字典类型,键是唯一的,同样的,这个也是有可变与不可变两种不同的包,默认是不可变的,要想使用可变的需要导入包,与Set是一样的
import scala.collection.mutable.Map
scala> val xinxi = Map("xiaoming"->18)
val xinxi: scala.collection.mutable.Map[String,Int] = HashMap(xiaoming -> 18)
面向对象编程基础
类的定义
方法定义:def 方法名(参数列表):返回结果类型={方法体}
对象
1.1、单例对象
所有定义在单例对象的字段,还有方法都是静态的,不用实例化就可以使用里面的方法,用object关键字去定义单例对象。
单例对象有两种:一种是伴生对象,一种是孤立对象。
伴生对象是在该单例对象所在的文件中有一个与object名称相同的class修饰的类
1.2、apply方法
用括号传递给类实例或单例对象名一个或者多个参数时,Scala会在相应的类或者对象中查找方法名为apply的方法,当参数与传入参数一致的时候,就会调用该apply方法。
1.3、继承
抽象类:需要使用关键字abstract
定义抽象类的抽象方法:不需要使用关键字abstract
Option类中的Some子类,当返回值不为none的时候返回的时Some对象,当没有返回值的时候,会返回none。
1.4、特质trait
与Java中的接口有点相似,但又与接口不同,特质中的方法可以是抽象的,也可以是具体的,一个类可以一个特质使用extends,但是一个类也可以继承一个类并且混入多个特质,继承一个类的时候使用关键词extends,混入多个特质使用with关键词
1.5、模式匹配
函数的定义与使用
scala> val add = (_:Int)+(_:Int) \\等价于(a:Int,b:Int)=>a+b
val add: (Int, Int) => Int = $Lambda$1295/1475295794@4f788167
scala> add(2,3)
val res57: Int = 5
Map的遍历
scala> xinxi.foreach{kv=>println(kv._1,kv._2)}
(xiaoming,18) //因为kv用到了两次,所以这里应该不能直接使用_
//等价于
scala> xinxi.foreach{x=>x match {case (k,v)=>println(k+":"+v)}}
xiaoming:18
//等价于
scala> xinxi.foreach{_ match {case (k,v)=>println(k+":"+v)}}
xiaoming:18
flatMap的使用