一,基本概念
1,映射
Map与HashMap与TreeMap,SotredMap等区别:
1、HashMap键无序,它根据键的HashCode值存储数据,根据键可以直接获取它的值,具有很快的访问速度,在Map 中插入、删除和定位元素,HashMap 是最好的选择;
2、LinkedHashMap 是HashMap的一个子类,键保存了插入的顺序,使用Iterator遍历时,得到的也是插入顺序的记录;
3、TreeMap默认按键的升序排序,可以定制。
4、HashTable 线程安全,键不能为null,与HashMap类似,但效率较低,HashMap如果需要实现同步,可以使用Collections. synchronizedMap或ConcurrentHashMap 。
课后习题4.2
/*
编写一段程序,从文件中读取单词。用一个可变映射来清点每个单词出现的频率。读取这些单词的操作可以使用java.util.Scanner: */
//method1
val in=new java.util.Scanner(new java.io.File("/home/user/people.txt"))
val map=new HashMap[String,Int]
while (in.hasNext()){
map(in.next())=map.getOrElse(i,0)+1
}
map
//method2
val file=scala.io.Source.fromFile("/home/usr/people.txt").mkString
val tokens=file.split("\\s+") //\\s表示 空格,回车,换行等空白符,+号表示一个或多个的意思,
val map=scala.collection.mutable.HashMap[String,Int]
for (word <- tokens)
map[word]=map.getOrElse(word,0)+1
map
课后习题4.7
/*按格式打印出出所有Java系统属性的表格*/
import scala.collection.JavaConversions.propertiesAsScalaMap
val props:scala.collection.Map[String,String]=System.getProperties()
val keys=props.keySet
val keyLength=for (key <- keys) yield(key.length)
val maxKeyLength=keyLength.max
for ((k,v) <- props){
print(k)
print(" "*(maxKeyLength-k.length))
print("|")
println(v)
}
二,类与对象
1,针对方法,带()多指改变了对象状态方法,而不带只是简单的读取
2,类构造方法@BeanProperty var name:String=_: 内部类和 外部类可以调用getName()和setName()方法 加private时,只有内部类可以
2.2 主构造函数法:class People(val name:String,private var age:Int) name能被内部类和外部对象读取,age 能在内部类中读写,但不被外部访问
1,class Peo(private val name:String)
val p=new Peo("z")
p.<tab>
asInstanceOf isInstanceOf toString (无name不可读和写) ,2,class Peo(val name:String)
val p=new Peo("z")
p.<tab>
asInstanceOf isInstanceOf name toString (name属性可读) 3,class Peo( var name:String)
val p=new Peo("z")
p.<tab>
asInstanceOf isInstanceOf name name_= toString (name,可读和可写) 4,class Peo( private var name:String)
val p=new Peo("z")
p.<tab>
asInstanceOf isInstanceOf toString (无name不可读和写)
2,静态方法和非静态方法区别:
首先,两者本质上的区别是:静态方法是在类中使用staitc修饰的方法,在类定义的时候已经被装载和分配。而非静态方法是不加static关键字的方法,在类定义时没有占用内存,只有在类被实例化成对象时,对象调用该方法才被分配内存。
其次,静态方法中只能调用静态成员或者方法,不能直接调用非静态方法或者非静态成员(可以声明对象来调用),而非静态方法既可以调用静态成员或者方法又可以调用其他的非静态成员或者方法。
3,多维组使用:val arr=Array.ofDim(3) 出错,必须为多维数组指定类型 val arr=Array.ofDim[String](3) arr=Array(3) 和arr=new Array(3)有区别
4,枚举类型:在Scala中并没有枚举类型,但在标准类库中提供了Enumeration类来产出枚举。扩展Enumeration类后,调用Value方法来初始化枚举中的可能值 (黏贴用:paste, 对象时object)
object ExecutorState extends Enumeration{
type ExecutorState = Value
val LAUNCHING, LOADING, RUNNING, KILLED, FAILED, LOST, EXITED = Value
def isFinished(state:ExecutorState):Boolean = {
Seq(KILLED, FAILED, LOST, EXITED).contains(state)
}
}
5,包
package com.hostname.impatient :子类不能引用父类的类
package com{
class T1{}
package hostname{
class T2(t1:T1){}
package impatient{
class T3(t1:T1,t2:T2){}
}
}
}
5.1 private[com] def giveRaise(rate:Double) 表示除com外其它都不可访问
5.2 scalac 编译文件生class scala class 将文件解析为机器可执行文件
5.3 object test extends App{ } 可以用以测试
6,继承
6.1 重写与重载()
重载的时候,方法名要一样,但是参数类型和个数不一样,返回值类型可以相同也可以不相同。无法以返回型别作为重载函数的区分标准
1,(override)重写方法不能比被重写方法限制有更严格的访问级别,即父类的访问权限(private)低于子类的访问权限(public)
2,参数列表必须与被重写方法的相同;返回类型必须与被重写方法的返回类型相同;如果一个方法不能被继承,则不能重写它;不能重写被标识为final的方法。
3,重写方法不能抛出新的异常或者比被重写方法声明的检查异常更广的检查异常。但是可以抛出更少,更有限或者不抛出异常。
4,重写抽象类的方法,就不用使用override,直接使用def ...
6.2 类型检查 a.asInstanceOf[Employee]
6.3 抽象类的特征
1、抽象类不能被实例化,实例化的工作应该交由它的子类来完成,它只需要有一个引用即可。
2、抽象方法必须由子类来进行重写。
3、只要包含一个抽象方法的类,该类必须要定义成抽象类,不管是否还包含有其他方法。
4、抽象类中可以包含具体的方法,当然也可以不包含抽象方法。
5、子类中的抽象方法不能与父类的抽象方法同名。
6、abstract不能与final并列修饰同一个类。
7、abstract 不能与private、static、final或native并列修饰同一个方法。
8, scala中如果抽象类中的字段没被初始化,则认为是抽象字段(不用override),反之普通字段,需要。