集合概述
Java集合類是一種類似於數組的,存儲對象引用(而非對象本身)的容器。集合石存儲對象最常用的一種方式。集合中可以存儲任意類型的對象,且長度可變,這就是說它類似於數組卻又不同於數組的原因,集合比數組更加適用。集合可以使用對象的增、刪、改、查等操作。
集合框架圖
圖中,實現邊框的是實現類,如ArrayList、LinkedList、HashMap等;短線邊框的是抽象類,如AbstractCollection、AbstractList、AbstractMap等;點線邊框的是接口,如Iterator、Collection、Map等。
由框架圖可知,存在多種集合容器,每一種集合容器對數據的存儲方式都各不相同。基本的特點如下所示:
---|Collection: 單列集合
---|List: 有存儲順序, 可重複
---|ArrayList: 數組實現, 查找快, 增刪慢
由於是數組實現, 在增和刪的時候會牽扯到數組
增容, 以及拷貝元素. 所以慢。數組是可以直接
按索引查找, 所以查找時較快
---|LinkedList: 鏈表實現, 增刪快, 查找慢
由於鏈表實現, 增加時只要讓前一個元素記住自
己就可以, 刪除時讓前一個元素記住後一個元
素, 後一個元素記住前一個元素. 這樣的增刪效
率較高但查詢時需要一個一個的遍歷, 所以效率
較低
---|Vector: 和ArrayList原理相同, 但線程安全, 效率略低
和ArrayList實現方式相同, 但考慮了線程安全問
題, 所以效率略低
---|Set: 無存儲順序, 不可重複
---|HashSet
---|TreeSet
---|LinkedHashSet
---| Map: 鍵值對
---|HashMap
---|TreeMap
---|HashTable
---|LinkedHashMap
對於不同的需求,我們可以選擇適當的集合容器,來獲取最大的效益。
集合類Collection
查看Collection類的API文檔可以發現,其存在多個子接口,常用的有List和Set兩種。
——-| Collection 單例集合的跟接口。
———-| List 如果是實現了List接口的集合類,具備的特點: 有序,可重複。
———-| Set 如果是實現了Set接口的集合類,具備特點: 無序,不可重複。
Collection接口中實現的方法主要有一下5種:
- 1.增加
add(E e) 添加成功返回true,添加 失敗返回false.
addAll(Collection c) 把一個集合 的元素添加到另外一個集合中去。
- 2.刪除
clear() 清空集合
remove(Object o) 移除集合中指定的元素
removeAll(Collection c)
retainAll(Collection c)
- 3.查看
size() 返回集合元素的個數
- 4.判斷
isEmpty() 判斷集合是否爲空
contains(Object o) 判斷集合中是否包含指定元素
containsAll(Collection
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
public class demo1 {
public static void main(String[] args) {
// 創建集合對象
Collection coll = new ArrayList();
// 創建Person對象
Person p1 = new Person("jack", 25);
Person p2 = new Person("rose", 22);
Person p3 = new Person("lucy", 20);
Person p4 = new Person("jack", 25);
// 集合中添加一些Perosn
coll.add(p1);
coll.add(p2);
// 刪除指定Person
//coll.remove(p1);
System.out.println("coll "+coll);
// 刪除所有Person
coll.removeAll(coll);
// 判斷容器中是否還有Person
//System.out.println("coll "+coll);
// 判斷容器中是否包含指定Person
coll.add(p4);
coll.add(p3);
//contains方法內部默認調用的是equals方法比較(equals默認比較的是對象的內存地址),此處必然會
//返回false
System.out.println("contains "+coll.contains(new Person("jack",25)));
// 獲取容器中Person的個數
System.out.println("collection has "+coll.size()+" person");
Object[] a = null;
// 將容器變爲數組,遍歷除所有Person
a = coll.toArray();
System.out.println(Arrays.toString(a));
}
}
class Person {
private String name;
private int age;
public Person() {
}
public Person(String name, int age) {
this.name = name;
this.age = age;
}
@Override
public int hashCode() {
return this.name.hashCode() + age;
}
@Override
public boolean equals(Object obj) {
// TODO Auto-generated method stub
Person pp = (Person) obj;
return this.name == pp.name;
}
/*
@Override
public boolean equals(Object obj) {
if (!(obj instanceof Person)) {
return false;
}
Person p = (Person) obj;
return this.name.equals(p.name) && this.age == p.age;
}*/
@Override
public String toString() {
return "Person :name=" + name + ", age=" + age;
}
}
java規範中指定重寫equals()方法後,也要重寫hashcode()方法。
toString方法
public String toString()
返回該對象的字符串表示。通常,toString 方法會返回一個“以文本方式表示”此對象的字符串。結果應是一個簡明但易於讀懂的信息表達式。建議所有子類都重寫此方法。
Object 類的 toString 方法返回一個字符串,該字符串由類名(對象是該類的一個實例)、at 標記符“@”和此對象哈希碼的無符號十六進制表示組成。換句話說,該方法返回一個字符串,它的值等於:
getClass().getName() + '@' + Integer.toHexString(hashCode())
返回:
該對象的字符串表示形式。
迭代器的使用
迭代器可以實現對collection進行迭代,即就是可以便利集合中的所有元素。
迭代器的實現的方法有下邊三種:
- 1.hasNext() 問是否有元素可遍歷。如果有元素可以遍歷,返回true,否則返回false 。
- 2.next() 獲取元素
- 3.remove() 移除迭代器最後一次返回的元素。
如果事先沒有使用hasNext()方法進行判斷是否有元素可遍歷,可能會出現NoSuchElementException異常,原因是沒有元素可以被迭代了。
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
public class demo1 {
public static void main(String[] args) {
Collection aa = new ArrayList();
aa.add("張三");
aa.add("李四");
aa.add("王五");
aa.add("馬六");
Iterator it = aa.iterator(); //返回一個迭代器,爲一個接口類型
while(it.hasNext()) {
System.out.println(it.next());
}
it.remove(); //從迭代器指向的 collection 中移除迭代器返回的最後一個元素
System.out.println(aa);
}
}
Iterator it = aa.iterator(),iterator()方法返回的是一個接口類型,爲什麼接口又可以調用方法可以使用呢? 實際上這塊使用了多態,iterator 上返回的是iterator接口的實現類對象。
多態的實例
interface Money{
public void makeMoney();
}
class Worker implements Money{
@Override
public void makeMoney() {
// TODO Auto-generated method stub
System.out.println("工人在賺錢。。。");
}
}
public class demo {
public static void main(String[] args) {
Money mon = test(); //此處test()方法返回值爲Money接口類型,但是這個方法的具體實現實實在在return返回的是其實現類的對象
mon.makeMoney();
}
//此處使用了多態,若直接將test方法的返回值寫死(即Worker類型)也可以,
//但是這樣會造成代碼的不靈活,若還有一個Student類實現了Money接口,寫死就不能返回Student類了
public static Money test(){
return new Worker();
}
}