1、裝箱和拆箱
2、封裝類的使用1,是作爲泛型的類型參數傳入
- ArrayList類型的聲明是正確的。ArrayList聲明是錯誤的。因爲泛型的規則是你只能指定類和接口類型。後面那種聲明方法無法通過編譯
3、集合
- ArrayList:
- LinkedList:針對經常插入或者刪除中獎元素所涉及的高效率集合
- HashMap:存取較高效,是用成對的key/value的形式來保存和取出
- LinkedHashMap:類似HashMap。但可記住元素插入的順序,也可以設定成依照元素上次存取的先後來排序
- TreeSet:以有序狀態保持並可放在重複,當往集合中存儲元素的時候,會花一定的時間去找合適的 位置(即是排序),如果是對順序沒有要求的,用ArrayList集合更高效
- HashSet:防止重複的集合,可快速查找相符的元素
4、泛型,泛型接口:list、map、set等
- 泛型意味着更好的類型安全性。運用泛型,你可以創建類型安全更好的集合,讓問題儘可能的在編譯階段就能抓到,而不會是在執行期間才被發現;若不是泛型的集合,則編譯器會很樂意接受你不同類型的對象放在同一個集合中。
- 泛型的使用1:創建被泛型化類的實例
new ArrayList<Song>()
- 泛型的使用2:聲明與指定泛型類型的變量
List<Song> songList = new ArrayList<Song>()
- 泛型的使用3:聲明或調用取用泛型類型的方法
void foo(List<Song> list)、x.foo(songList)
- 泛型接口:List、Map、Set
4.1、泛型的好處
泛型的好處是在編譯的時候檢查類型安全,並且所有的強制轉換都是自動和隱式的,提高代碼的重用率。
- 類型安全,主要目標是提高 Java 程序的類型安全。
- 消除強制類型轉換。
5、一些常用說法
- ArrayList也可以通過指定位置的方式在集合中添加元素。但是這種會比較慢。
- Collections.sort(stringList)會把stringList中的String依照字母排序。但是若Collections.sort(songList),songList是一個對象類型的集合,此時是不允許編譯通過的。Collections的sort方法定義爲
public static <T extends Comparable<? super T.> void sort(List<T> list),
這個說明sort只能接口Comparable對象的list,而Song不是Comparable的子型,所以無法進行排序,編譯不通過。
6、comparable與comparator
- 調用單一參數的sort(List o)方法代表有list元素的compareTo()方法來決定順序,因此元素必須實現Comparable的接口
- 調用sort(List o, Comparator c)方法代表不會調用list元素的compareTo()的方法,而會調用Comparaotr的compare()方法,這意味着list元素不需要實現Comparable接口
注意:不是所有的類都需要實現Comparable接口的,會讓人誤解。
7、對象的等價
7.1、set將兩個對象視爲重複:
- x.equals(y)返回true
- x的hashCode與y的hashCode相等;滿足這兩個條件,視爲重複對象
7.2、相等性
- 引用相等性,使用==來比較變量的字節組合。如果引用到相同的對象,字節組合會一樣
- 對象相等性:(x.equals(y)) && (x.hashCode() == y.hashCode())(對象必須覆蓋過object的hashCode方法,不然因爲大部分的java版本是依據內存位置來計算hashCode方法返回的序號值,一般都會不一樣。所以需要重寫,,才能確保兩個對象有相同的hashCode);
- x.equals(y)返回true,則x.hashCode()==y.hashCode()等值
- x.hashCode()==y.hashCode()等值,但是 x.equals(y)不一定會返回true;由於hash算法有可能會發生碰撞,不同的值可能會返回相同的hashCode值。
8、TreeSet的元素是有序列表,必須有方法來排序。
- 集合中的元素必須是有實現Comparable的類型,通過實現它的compareTo的方法進行排序
- 使用重載,調用Comparator參數的構造器來創建TreeSet。通過compator的實現類的compare方法進行排序
9、參數化類型
- 普通的參數化類型,可以支持參數化的向上轉型,即父類引用指向子類的實例對象
public void go5(){
Animal animal = new Animal();
Dog dog = new Dog();
takeAnimals5(dog);//向上轉型,把子類的對象直接賦給父類的引用,成功的
takeAnimals6(animal);//會報錯,編譯不通過
takeAnimals6((Dog) animal);
}
public void takeAnimals5(Animal animal){
}
public void takeAnimals6(Dog dog){
}
- 數組類型的參數化傳遞
數組類型校驗是在允許階段,編譯會通過
public void go(){
Animal[] animals = {new Dog(),new Cat(),new Dog()};
Dog[] dogs = {new Dog(),new Dog(),new Dog()};
takeAnimals(animals);
takeAnimals(dogs);
}
public void takeAnimals(Animal[] animals){
for (Animal a:animals){
a.eat();
}
}
public void go3(){
Dog[] dogs = {new Dog(),new Dog(),new Dog()};
takeAnimals3(dogs);
}
public void takeAnimals3(Animal[] animals){
//編譯通過,但是執行會報錯,因爲數組的類型校驗是運行期間,不允許往dog類型的數組裏添加Cat類型的對象
animals[0] = new Cat();
}
- 集合參數類型的傳遞,只能是一一對應的關係
集合類型的參數校驗是在編譯階段就進行校驗
public void go2(){
ArrayList<Animal> animals = new ArrayList<Animal>();
animals.add(new Dog());
animals.add(new Cat());
animals.add(new Dog());
ArrayList<Dog> dogs = new ArrayList<Dog>();
dogs.add(new Dog());
dogs.add(new Dog());
takeAnimals2(animals);
//編譯報錯,由於集合的類型校驗,是在編譯期間。集合參數化,只能是一一對應的關係。
takeAnimals2(dogs);//編譯不通過
takeAnimals4(animals);//編譯不通過
takeAnimals4(dogs);
takeAnimals7(animals);
takeAnimals7(dogs);
}
public void takeAnimals2(ArrayList<Animal> animals){
for (Animal a:animals){
a.eat();
}
}
public void takeAnimals4(ArrayList<Dog> dogs){
for (Dog a:dogs){
a.eat();
}
}
//採用萬能字符實現多態化集合參數類型的校驗
public void takeAnimals7(ArrayList<? extends Animal> animals){
for (Animal a:animals){
a.eat();
}
}