1、 private:java允许本类、内部类及外部类访问本类的私有变量
scala只允许本类和内部类访问本类的私有变量
2、 protected:java允许子类和同包的其他类访问
scala只允许子类访问
3、 public:一样
4、 函数传值调用和传名调用:
(1) 传值:参数(x:Int)
(2) 传名:参数(x: => Int)
5、 指定函数参数名:调用时参数(a=1,b=2)
6、 可变参数:调用时最后一个参数(args:String*)
7、 默认参数值:定义函数时,(x:Int=1,y:Int=2)
8、 递归函数:可以调用自身
9、 高阶函数:定义某个函数时,类似于deftest(x:Int =>Int,y:Int)=x(y),函数x以y为未知参数传递
10、 匿名函数:var mos=(x:Int)=>x=1
11、 偏应用函数:提前传入部分参数,其他参数以后传入,需要用到通配符_
柯里化:把多个参数的函数转变成只有一个参数的函数,在该函数中存在另一个函数,该函数中存在了其他参数,类似于:
var addEvent = (function(){
if (window.addEventListener) {
return function(el, sType, fn, capture){
el.addEventListener(sType,function(e) {
fn.call(el, e);
}, (capture));
};
} else if (window.attachEvent) {
return function(el, sType, fn, capture){
el.attachEvent("on" +sType, function(e) {
fn.call(el, e);
});
};
}
})();
12、 Val arr=ArrayBuffer[Int](5)
Val arr =ArrayBuffer[Int](1,2,3,4,5)
arr += 1(或者+)
arr +=(1,2)
arr:+1或者1+:list
arr ++=Array(1,2)
arr -=1(或者-)
arr.trimEnd(从后数的长度)
arr.insert(起始点,要插入的数值)
arr.remove(起始点,长度)
arr.sort
arr.sortedBy(_)
arr.sortedWith(_>_)
arr (5)
13、 Valmap=HashMap(“m1”->1,”m2”->2)
Val map=HashMap((“m1”,1),(”m2”,2))
map += (“m3”->3,”m4”->4)
map -= ”m3”
map(“m1”)
map.keySet
map.values
14、 列表List(不可变,所以操作后产生的都是新的List)
创建:List(1,2,3)
1 :: 2 :: Nil(或者新增也用此方法)
合并两个列表: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\
参考:https://blog.csdn.net/poison_h/article/details/50474092
ListBuffer是可变的list,可以用list.append(1)在后面新增数据(改变的是原数据)
15、 集Set(不可变,所以操作后产生的都是新的Set)
新增/删除:Set(1,2,3) + 5 / Set(1,2,3) –1 (是唯一一个不可变的容器中可以直接用+/-的)
新增/删除多个:Set(1,2)++ Set(3,4) / Set(1,2,3,4) -- Set(3,4)
LinkedSet记录插入顺序
SortedSet记录数值顺序
16、
17、 Val tuple=(1,2)
Val (first,second)=(1,2)
Tuple.toMao
Val tuple=arr1.zip(arr2)
18、 在定义Bean时,
(1) 成员变量为var name=”myname”自动生成getter和setter
(2) 成员变量为val name=”myname”只生成getter
(3) 覆盖自动生成的getter和setter的方法为:
Def name=name ——gettter
Def name_=(){ } ——setter
(4)@BeanPropertyvar name=”myname”会生成真正的getter和setter
(5)private修饰只能在本类中调用 ——类私有
(6)private[this]不能用 类名.属性名 的方式使用 ——对象私有
(7)private[类名]只能在该类中使用
19、 主构造器
定义在类的定义中,没有则为无参。
例如:classPeople(val name:String,var age:Int){}
注意:实例化时会执行主构造器中的所有语句
20、 辅助构造器
名称必须为this,且调用之前定义的主构造器或者辅助构造器的方法。
例如:def this(name:String){
this()
this.name=name
}
21、 单例对象
(1) 作为存放工具函数或常量的地方
(2) 高效的共享单个不可变实例
(3) 需要用单个实例来协调某个服务(参考单例模式)
(4) 只有在第一次被调用时才执行其构造器
22、 伴生对象
目的:实现scala中既可以有静态方法又有普通方法的目的。
特点:类和伴生对象可以互相访问其私有变量。
在类中访问伴生对象需调用:伴生对象名.方法。
程序的入口。
23、 Apply和unApply方法
在伴生对象中定义def apply()={}
如果是遇到Object(参数)时,即调用的是伴生对象中的def apply()={}方法
如果调用Object(对象)时,则调用的时unApply方法
24、 枚举类型
object ScalaMain {
object ColorEnum extends Enumeration { //要继承Enumeration
type ColorEnum1=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)来取得值
}
}
25、 类型检查和类型转换
(1) isInstanceOf 类型检查
(2) asInstanceOf 类型转换
(3) people.getClass==ClassOf[People]检查是否为本类而非子类
26、 抽象类、抽象方法和抽象变量
抽象类:Abstract修饰的类
抽象方法:没有方法体的方法
抽象变量:不初始化的变量(val的只生成getter)
27、 继承层级
所有对应java基础类型的类继承自AnyVal
其他类继承自AnyRef
AnyVal和AnyRef都继承自Any
28、 文件读取
def main(args: Array[String]): Unit = {
val source: BufferedSource = Source.fromFile("C:\\people","utf-8")
val strings: Iterator[String] = source.getLines() //获取文件的迭代器
val array: Array[Char] = source.toArray //将文件转换成数组或者Buffer(toBuffer)
val string: String = source.mkString //将文件转换成一串字符串
//将文字打印到文件中
val writer: PrintWriter = new PrintWriter("C:\\ppp.txt")
for(i <- 0 to 100) writer.print(i)
writer.close()
}
29、 特质
(1) 当做接口使用:在子类中实现其方法。
(2) 有具体实现方法:子类中可以覆盖也可以不覆盖。
(3) 带有特质的对象:可以用val people=new People with runnable实现其特质。
(4) 多重继承特质:其方法最终会实现最后继承的特质的方法
(5) 对于特质中的成员变量:已经初始化的会变为子类的成员变量,未初始化的要初始化其成员变量。
参考:https://blog.csdn.net/qiruiduni/article/details/46726809或者《快学scala》
30、 等于操作符
.eq() 是判断引用是否相等
.equal() 是判断对象是否相等
== 如果判断null,则调用.eq(),其他调用.equal()
28、函数(方法)类型推断
31、 闭包:定义在函数内部的另一个函数可以访问外层函数的局部变量
参考:http://www.jb51.net/article/85775.htm
32、 柯里化:传两个参数的函数,可以转换成只传一个参数的函数并返回一个参数的函数。
33、 return
采用return可以提前返回循环,但是一定要设置返回值的类型。
34、 模式匹配
Str match{
Case a =>1
Case _ =>2
}
(1) 匹配类型:变量a后面可以加:Int来匹配类型
(2) 变量赋值:把Str的值赋给了a
(3) 匹配数组元组:a可以改成Array(x,y),匹配两个值的Array
35、 copy方法
val person1=new Person(“chang”,24)
val person2=person1.copy(age=25)
36、 偏函数
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)
}
则logWithDateBound为偏函数
37、 泛型
(1) 泛型类:classPair[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]的子类型
参考:https://blog.csdn.net/snail_gesture/article/details/48156629
38、 隐式转换
(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
就是把不属于此类型的类转换成其他类型的,以便用其方法
在转换期间,编译器是自动转换的:编译器观察出他不能用此方法,就把类型开始转换,以便能用其方法。
(3) 隐式类
object Stringutils {
implicit class StringImprovement(val s : String){ //隐式类
def increment = s.map(x => (x +1).toChar)
}
}
object Main extends App{
import com.mobin.scala.implicitPackage.Stringutils._
println("mobin".increment)
}