集合與泛型
阿新 • • 發佈:2019-01-10
一、集合:就像是一種容器。用於儲存、獲取、操作物件的容器。
1. 陣列的弊端
①陣列的長度不可變 ②陣列沒有提供可以檢視有效元素個數的方法
2. 集合的特點
①集合的長度是可變的
②集合可以儲存任意型別的物件
③集合只能儲存物件
3. 集合框架
java.util.Collection : 集合層次的根介面
|--- java.util.List: 有序的,可以重複的。
|--- ArrayList: 採用陣列結構儲存元素。 查詢操作多時選擇
|--- LinkedList: 採用連結串列結構儲存元素。 增刪操作多時選擇
|--- Vector:
|--- java.util.Set: 無序的,不允許重複。
|--- HashSet : 是 Set 介面的典型實現類。
判斷元素是否存在的依據是:先比較 hashCode 值,若 hashCode 存在,再通過 equals() 比較內容
若 hashCode 值不存在,則直接儲存
注意:重寫 hashCode 和 equals 二者需要保持一致!
|--- LinkedHashSet: 相較於 HashSet 多了連結串列維護元素的順序。遍歷效率高於 HashSet , 增刪效率低於 HashSet
|--- TreeSet : 擁有自己排序方式
|-- 自然排序(Comparable):
①需要新增 TreeSet 集合中物件的類實現 Comparable 介面
②實現 compareTo(Object o) 方法
|-- 定製排序(Comparator)
①建立一個類實現 Comparator 介面
②實現 compare(Object o1, Object o2) 方法
③將該實現類的例項作為引數傳遞給 TreeSet 的構造器
4. 集合的遍歷
① 增強 for 迴圈
for(被遍歷集合中元素的資料型別 變數名 : 被遍歷的集合){
}
ArrayList al = new ArrayList();
al.add("AA");
al.add("BB");
for(Object obj : al){
System.out.println(obj);
}
② 使用 Iterator 迭代器
//1)獲取當前集合的迭代器
Iterator it = al.iterator();
while(it.hasNext()){
Object obj = it.next();
System.out.println(obj);
}
/*錯誤的做法:通常一個 hasNext() 配合一個 next() 使用
Iterator it = al.iterator();
while(it.hasNext()){
Object obj = it.next();
System.out.println(it.next());
}*/
③ ListIterator : 列表迭代器,是List特有的迭代器(瞭解)
ListIterator li = al.listIterator();
while(li.hasNext()){
Object obj = li.next();
if(obj.equals("BB")){
li.set("BBBBBBBBBBb");
}
}
二、Map系列集合
java.util.Map : 用於儲存成對物件的集合。具有 key(鍵)-value(值)對對映關係的集合。一個 key 對應著一個 value。 key不允許重複的。
|--- HashMap:是 Map介面的典型實現類。
|--- LinkedHashMap: 相較於 HashMap 多了連結串列維護元素的順序
|--- Hashtable: 是執行緒安全的,因此效率低
|--- Properties : 用於操作屬性檔案
|--- TreeMap : 根據 key 擁有自己的排序方式
|-- 自然排序(Comparable):
|-- 定製排序(Comparator):
//使用 Properties 操作屬性檔案
@Test
public void test1() throws FileNotFoundException, IOException{
//1. 建立 Properties 物件
Properties props = new Properties();
//2. 通過 load() 方法載入屬性檔案
props.load(new FileInputStream("hello.properties"));
//3. 通過 getProperty() 方法根據key獲取對應的value
String userName = props.getProperty("username");
String password = props.getProperty("password");
System.out.println(userName);
System.out.println(password);
}
1. Map的常用方法:
新增、刪除操作:
Object put(Object key,Object value)
Object remove(Object key)
void putAll(Map t)
void clear()
元素查詢的操作:
Object get(Object key)
boolean containsKey(Object key)
boolean containsValue(Object value)
int size()
boolean isEmpty()
boolean equals(Object obj)
2. Map 的遍歷:
Map map = new HashMap();
map.put("AA", 123);
map.put("BB", 456);
keySet();
//遍歷Map的方式一: 獲取 Map 中所有的 key
Set set = map.keySet();
values();
//遍歷Map的方式二:獲取 Map中所有的 value
Collection coll = map.values();
//遍歷Map的方式三: 獲取Map中所有的 Entry (是Map 的一個內部類,一個Entry對應著Map中的一個key和一個value)
Set entrySet = map.entrySet();
for(Object obj : entrySet){
Entry entry = (Entry)obj;
Object key = entry.getKey();
Object value = entry.getValue();
}
Iterator it = entrySet.iterator();
while(it.hasNext()){
Entry entry = (Entry)it.next();
Object key = entry.getKey();
Object value = entry.getValue();
}
三、
為什麼使用泛型:若集合中不使用泛型,意味著集合中可以新增任意型別的物件。若需要具體到某一個型別時,需要強制型別轉換
可能引發 ClassCastException
泛型: 在 Java 中以 "<>" 的形式呈現,<> 中寫引用資料型別
用於限制集合中存放元素的型別
1. 在集合中應用泛型
2. 自定義泛型類、介面、方法
class DAO<T>{ // T : Type E:Element K:Key V:Value
private List<T> list = new ArrayList<T>();
public void add(T t){
list.add(t);
}
public T get(int id){
return list.get(id);
}
//自定義泛型方法
public <E> E[] srot(E[] e){
}
}
3. 萬用字元 ?
雖然 Person 是 Student 的父類,但是 List<Person> 就不是 List<Student> 的父類
//需求:
//public void show(List<Student> list){}
//public void show1(List<Man> list){}
public void show(List<? extends Person> list){}
List<?> : 可以接收任意帶泛型型別的集合
List<? extends Person> : 可以接收 Person 本類型別及 Person子類型別帶泛型型別的集合
List<? super Person> : 可以接收 Person 本類型別及 Person父類型別帶泛型型別的集合