《快学Scala》笔记

一、基础

1、数据类型:
Byte、Short、Int、Long、Flout、Double、Boolean七种数据类型,且不分基本类型和引用类型。

2、运算符:
相比java,没有++和–两种操作符。

3、方法调用:
如果没有参数,方法可以不带括号。

4、变量声明:

val a="不可变类型"  
var b="可变类型"

5、语句终止与返回:

  • 采用return可以提前返回循环,但是一定要设置返回值的类型。
  • 不用return,代码块的最后一个语句即为返回值,例如:
val a={val x=2-1
	val y=3-1
	sqrt(x+y)	//将最后一个返回
}

6、字符串格式化:
(1)类似于java的System.out.println(“my name is %s”,“tom”)
(2)新形势:

  • s插值器
val name="James"
println(s"Hello,$name")//Hello,James 此例中,$name嵌套在一个将被s字符串插值器处理的字符串中。插值器知道在这个字符串的这个地方应该插入这个name变量的值,以使输出字符串为Hello,James。使用s插值器,在这个字符串中可以使用任何在处理范围内的名字。
  • f插值器(变量类型要对应,否则会报错)
val height=1.9d
val name="James"
println(f"$name%s is $height%2.2f meters tall")//James is 1.90 meters tall
  • raw插值器
scala>s"a\nb"
res0:String=
a
b 这里,s 插值器用回车代替了\n。而raw插值器却不会如此处理。

scala>raw"a\nb"
res1:String=a\nb 当不想输入\n被转换为回车的时候,raw 插值器是非常实用的。

7、for循环:

  • scal的for循环没有for(int i=0;i<9;i++)形式。
  • for(i<-表达式),例如for(i<- 1 to/until 10 by 2)
  • 高级:for(表达式1;表达式2;表达式3 if守卫),例如for(i<- 1 to 10;i<- 10 to 1 if i != j)

8、函数:
(有些可以不指定返回类型,他会自己推测,但是递归的必须标明返回值,无返回值为Unit)

def test(a:Int,b:String):String{
	b + a.toString
}

9、变长参数:

def test(a:Int,b:String*) 

10、类型强转------转为该类的子类:

10.asInstanceOf

11、lazy修饰符:
该值的初始化将被推迟到第一次使用该值的时候。

二、数组、集合相关

1、数组

(1)定长数组(长度不可变,其内容可变)

val arr1: Array[Int] = new Array[Int](5)	//scala的[]一般存放类型,()相当于java的{}
val arr2: Array[String] = Array("2","3")
arr1(0)=10
val value=arr2(0)	//scala的()相当于java和python里的[]
val arrays: Array[Array[Nothing]] = Array.ofDim(3,4)	//定义多维数组

(2)变长数组

val arr3: ArrayBuffer[Int] = new ArrayBuffer[Int]()
arr3 += (1,2,3)  //在末尾添加元素
arr3 ++= arr1   //++=可以添加任何集合元素
arr3.trimEnd(5) //删除后面5个元素还有trimStart
arr3.insert(2,1,2,3)  //在下标2处添加1,2,3这三个元素
arr3.remove(4,2) //在下标4处删除长度为2的元素,长度可选
val array: Array[Int] = arr3.toArray  //转换成定长数组

(2)常用方法

array.max
array.sum
val filtered: Array[Int] = array.filter(_>10)
val mapd: Array[Int] = array.map(_+2)
val sorted = array.sorted   //不改变原数组
array.sortWith(_ > _)  //改变原数组

val str1: String = array.mkString(",")   //输出数组,以什么分割
val str2: String = array.mkString("[",",","]")   //输出数组,以什么开始、分割、结束

2、映射

val map1: Map[String, String] = Map("key1" -> "value1", "key2" -> "value2")   //不可变映射
val map2: mutable.Map[String, String] = scala.collection.mutable.Map("key1"->"value1","key2"->"value2") //可变映射

val value: String = map1("key1")
val str: String = map2.getOrElse("key2","defaultValue")
map2("key1")="keyvalue"
map2 += ("key3" -> "value3")      //在原数组的基础上添加
  val map4 = map1 + ("key3" -> "value3") //不可变的新增后生成一个新映射
map2 -= "key3"

3、元组(没有其他结构新增删除等操作)

val tuple: (Int, Int, Int) = (1,2,3)
val tupleValue: Int = tuple._1

val array1 = Array(1,2,3)
val array2 = Array(4,5,6)
val array3: Array[(Int, Int)] = array1.zip(array2) //拉链函数,如果两个数组长度不等,则按最小的长度算
val map: Map[Int, Int] = array1.zip(array2).toMap //转换成映射

4、列表
(1)创建列表

val list1: List[Int] = List(2,1)	//不可变数组,里面的元素不可以更改
val list2: List[Int] = 2 :: (1 :: Nil)  //注意::操作符是右结合的,Nil只能放在右边

val list3 = ListBuffer(0,1)	//可变数组,里面的元素可以更改

(2)常用方法

val list1 = List(0,1,2,3,4)
val list2: List[Int] = list1:+3   //往后新增
val list3: List[Int] = 3 +: list1 //往前新增
val i: Int = list1(0)   //获取值
val list4: List[Int] = list1.drop(1) //删除第几个值,不是下标
val tail: List[Int] = list1.tail //返回除去第一个值的列表,类似的还有init
val take: List[Int] = list1.take(2) //返回从开头到第几个下标的列表,类似的有takeRight()
val head: Int = list1.head    //返回第一个值,类似的还有last

总结:
合并两个列表:list1 ::: list2(或者list1 ++ list2)
新增: list(1,2):+3或者3+: list(1,2)
获取值:list(0)	list.head和list.last		list.take(2)和list.takeRigt(2)
删除:list.drop(0)	list.init和list.tail		list.distinct
排序:sum\max\min\sort\sortedWith\reverse
判断:isEmpty\startWith\endWith\

5、集
(1)创建Set

val set1: Set[Int] = Set(1,2,3)   //不可重复的结构
val set2: scala.collection.mutable.SortedSet[Int] = scala.collection.mutable.SortedSet(1,2,3)  //排序的Set
val set3: scala.collection.mutable.LinkedHashSet[Int] = scala.collection.mutable.LinkedHashSet(1,2,3) //记录插入顺序

(2)常用方法

val set1: Set[Int] = Set(1,2,3)   //不可重复的结构
val set2: Set[Int] = set1 + 1       //添加/删除一个
val set3: Set[Int] = set1 ++ set2   //添加/删除多个

6、易混的新增操作

  • 变长数组为+=和++=
  • 可变映射为+=
  • 不可变映射为+
  • 集为+
    7、方法总结


    8、懒视图
    对集合类型.view或者.view(start,until)可对集合懒操作,与变量的lazy相似。

三、类、对象、特质

(一)类

1、定义Bean

(1)	成员变量为var name=”myname”自动生成getter和setter
(2)	成员变量为val name=”myname”只生成getter
(3)	覆盖自动生成的getter和setter的方法为:
		Def name=name	——gettter
		Def name_=(){	}	——setter
(4)@BeanProperty var name=”myname”会生成真正的getter和setter
(5)private修饰只能在本类中调用				———————类私有
(6)private[this]不能用 类名.属性名 的方式使用		———————对象私有
(7)private[类名]只能在该类中使用

2、主构造器

  • 主构造器执行期间会执行类内的所有语句。
class People(val name:String,var age:Int){}	//自动生成val和var的两个字段
class People(name:String,age:Int){}		//在使用着两个字段的时候升级为字段,没使用则不升级为字段

3、辅助构造器

  • 每一个辅助构造器都以前面定义的(主/辅助)构造器开始,且每一个辅助构造器都叫this。
def this(name:String,age:Int){
	this()
	this.name=name
	this.age=age
}

4、内部类

Outter.Inner inner=new Outter.Inner			//scala

Outter outter=new Outter()		//java
Outter.Inneroutter.new Inner()

(二)对象

5、单例对象(类似于java的静态类)

  • 作为存放工具函数或常量的地方
  • 高效的共享单个不可变实例
  • 需要用单个实例来协调某个服务(参考单例模式)
  • 只有在第一次被使用时才执行其构造器

6、伴生对象

  • 目的:实现scala中既可以有静态方法又有普通方法的目的。

  • 特点:类和伴生对象可以互相访问其私有变量。
    在类中访问伴生对象需调用:伴生对象名.方法。
    另:程序的入口。
    7、Apply和unApply方法

  • 方式:在伴生对象中定义def apply()={}

  • 如果是遇到Object(参数)时,即调用的是伴生对象中的def apply()={}方法

  • 如果调用Object(对象)时,则调用的时unApply方法

8、枚举类型

object ScalaMain {
  object ColorEnum extends Enumeration {     //要继承Enumeration
    type ColorEnum=Value   //声明枚举类型对外暴露的变量类型
    val red=Value("red")    //声明枚举类型的名称,ID从0开始依次增加
    val yellow=Value(1,"yellow")  //声明枚举类型的ID和名称,后面的ID从此开始依次增加
    val green=Value   //声明枚举类型,ID从0开始依次增加,名称为val后面的默认名称
  }
  def main(args: Array[String]): Unit = {
    for (i <- 0 until ColorEnum.maxId) print(ColorEnum(i))  //通过调用ColorEnum(i)来取得值
  }
}

(三)特质

9、类型检查和类型转换

  • isInstanceOf 类型检查
  • asInstanceOf 类型转换
  • people.getClass==ClassOf[People] 检查是否为本类而非子类

10、抽象类、抽象方法和抽象变量

  • 抽象类:Abstract修饰的类
  • 抽象方法:没有方法体的方法
  • 抽象变量:不初始化的变量(val的只生成getter)

11、继承层级

  • 所有对应java基础类型的类继承自AnyVal
  • 其他类继承自AnyRef
  • AnyVal和AnyRef都继承自Any

12、 特质(用with继承)

(1)用法:

  • 当做接口使用:在子类中实现其方法。
  • 有具体实现方法的特质(与java不同):子类中可以覆盖也可以不覆盖。
  • 特质中的成员变量:已经初始化的会变为子类的成员变量,未初始化的要初始化其成员变量。

(2)带有特质的对象:可以用val people=new People with runnable实现其特质。
(3)多重继承特质:其方法最终会实现最后继承的特质的方法。
参考:https://blog.csdn.net/qiruiduni/article/details/46726809或者《快学scala》

13、等于操作符的判断

  • .eq() 是判断引用是否相等
  • .equal() 是判断对象是否相等
  • == 如果判断null,则调用.eq(),其他调用.equal()

14、copy方法

val person1=new Person(“chang”,24)
val person2=person1.copy(age=25)

15、样例类(即用case修饰的类)
当一个类被定义成为case类后,Scala      支持模式匹配       并会自动帮你 创建一个伴生对象并帮你实现了一系列方法。

  1. 实现了apply方法,意味着你不需要使用new关键字就能创建该类对象。
  2. 实现了unapply方法,可以通过模式匹配来获取类属性,是Scala中抽取器的实现和模式匹配的关键方法。
  3. 实现了类构造参数的getter方法(构造参数默认被声明为val),但是当你构造参数是声明为var类型的,它将帮你实现setter和getter方法(不建议将构造参数声明为var)。

四、高阶函数和用法

1、函数(方法)类型推断

2、闭包
定义在函数内部的另一个函数可以访问外层函数的局部变量。

function a(){ 
  var i=0; 
  function b(){ 
     alert(++i); 
  } 
  return b; 
} 
var c = a(); 
c();
即,闭包的作用就是在a执行完并返回后,闭包使得Javascript的垃圾回收机制GC不会收回a所占用的资源,  
因为a的内部函数b的执行需要依赖a中的变量。
由于闭包的存在使得函数a返回后,a中的i始终存在,这样每次执行c(),i都是自加1后alert出i的值。

参考:http://www.jb51.net/article/85775.htm

3、柯里化
传两个参数的函数,可以转换成只传一个参数的函数并返回一个参数的函数。
这里讲得不错:http://www.mamicode.com/info-detail-1076478.html

4、模式匹配

Str match{
	Case a if XXX => 1		//if是守卫,和for循环中的一样
	Case _ => 2
}
用法:
(1)匹配类型:变量a后面可以加:Int来匹配类型
(2)变量赋值:把Str的值赋给了a
(3)匹配数组元组:a可以改成Array(x,y),匹配两个值的Array

5、偏函数
就是把多个参数的函数,固定几个变量,只传递其中几个参数构成的函数。

def main(args: Array[String]) {
  val date = new Date
  val logWithDateBound = log(date, _ : String)
  logWithDateBound("message1" )
  Thread.sleep(1000)
  logWithDateBound("message2" )
  Thread.sleep(1000)
  logWithDateBound("message3" )
}
def log(date: Date, message: String)  = {
  println(date + "----" + message)
}

6、隐式值和隐式转换

  • 就是把不属于此类型的类转换成其他类型的,以便用其方法。
  • 在转换期间,编译器是自动转换的:编译器观察出他不能用此方法,就把类型开始转换,以便能用其方法。

(1)隐式值

scala> def person(implicit name : String) = name   //name为隐式参数
	person: (implicit name: String)String
scala> implicit val p = "mobin"   //p被称为隐式值
	p: String = mobin
scala> person
	res1: String = mobin

(2)隐式转换

scala> def foo(msg : String) = println(msg)
	foo: (msg: String)Unit
scala> implicit def intToString(x : Int) = x.toString
	intToString: (x: Int)String
scala> foo(10)
	10

7、泛型

(1)泛型类:class Pair[T,S](val first : T, val second : S) 
(2)泛型函数:def getMiddle[T](a : Array[T]) = a(a.length / 2)       //观察以上两个的不同。
(3)类型变量界定:class Pair[T<:Comparable[T]](val first:T)	    //T是Comparable[T]的子类型
(4)上下文界定:class Pair[T<%Comparable[T]](val first:T)	      //T经过隐式转换的类型是Comparable[T]的子类型

猜你喜欢

转载自blog.csdn.net/yancychas/article/details/84721566
今日推荐