一、Java中集合
Java中集合類別是Java程式設計中使用最頻繁、最方便的類別。集合類別作為容器類別可以儲存任何類型的數據,當然也可以結合泛型儲存指定的類型(不過泛型僅在編譯期間有效,運行時是會被擦除的)。集合類別中儲存的僅是物件的引用,並不儲存物件本身。集合類別的容量可以在運作期間進行動態擴展,也提供許多很方便的方法,如求集合的並集、交集等。
二、集合類別結構
# Java中的集合包含多種資料結構,如鍊錶、佇列、哈希表等。從類別的繼承結構來說,可以分為兩大類,一類是繼承自Collection接口,這類集合包含List、Set和Queue等集合類別。另一類是繼承自Map接口,這主要包含了哈希表相關的集合類別。下面我們來看看這兩大類別的繼承結構圖:
1、List、Set和Queue
圖中的綠色的虛線代表實現,綠色實線代表介面之間的繼承,藍色實線代表類別之間的繼承。
(1)List:我們用比較多的List包含ArrayList和LinkedList,這兩者的差異也很明顯,從名稱上就可以看出。 ArrayList的底層的透過陣列實現,所以其隨機存取的速度比較快,但是對於需要頻繁的增刪的情況,效率就比較低了。而對於LinkedList,底層透過鍊錶來實現,所以增刪操作比較容易完成,但是對於隨機存取的效率比較低。
我們先看下兩者的插入效率:
package com.paddx.test.collection; import java.util.ArrayList; import java.util.LinkedList; public class ListTest { public static void main(String[] args) { for(int i=;i<;i++){ } long start = System.currentTimeMillis(); LinkedList<Integer> linkedList = new LinkedList<Integer>(); for(int i=;i<;i++){ linkedList.add(,i); } long end = System.currentTimeMillis(); System.out.println(end - start); ArrayList<Integer> arrayList = new ArrayList<Integer>(); for(int i=;i<;i++){ arrayList.add(,i); } System.out.println(System.currentTimeMillis() - end); } }
下面是本機執行的結果:
23
1227
可以看出,在這種情況下,LinkedList的插入效率遠高於ArrayList,當然這是一種比較極端的情況。我們再來比較一下兩者隨機存取的效率:
package com.paddx.test.collection; import java.util.ArrayList; import java.util.LinkedList; import java.util.Random; public class ListTest { public static void main(String[] args) { Random random = new Random(); for(int i=;i<;i++){ } LinkedList<Integer> linkedList = new LinkedList<Integer>(); for(int i=;i<;i++){ linkedList.add(i); } ArrayList<Integer> arrayList = new ArrayList<Integer>(); for(int i=;i<;i++){ arrayList.add(i); } long start = System.currentTimeMillis(); for(int i=;i<;i++){ int j = random.nextInt(i+); int k = linkedList.get(j); } long end = System.currentTimeMillis(); System.out.println(end - start); for(int i=;i<;i++){ int j = random.nextInt(i+); int k = arrayList.get(j); } System.out.println(System.currentTimeMillis() - end); } }
下面是我本機執行的結果:
5277
##6
package com.paddx.test.collection; import java.util.ArrayList; import java.util.HashSet; import java.util.Set; public class SetTest { public static void main(String[] args) { Person p1 = new Person("lxp",10); Person p2 = new Person("lxp",10); Person p3 = new Person("lxp",20); ArrayList<Person> list = new ArrayList<Person>(); list.add(p1); System.out.println("---------"); list.add(p2); System.out.println("---------"); list.add(p3); System.out.println("List size=" + list.size()); System.out.println("----分割线-----"); Set<Person> set = new HashSet<Person>(); set.add(p1); System.out.println("---------"); set.add(p2); System.out.println("---------"); set.add(p3); System.out.println("Set size="+set.size()); } static class Person{ private String name; private int age; public Person(String name, int age) { this.name = name; this.age = age; } @Override public boolean equals(Object o) { System.out.println("Call equals();name="+name); if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; Person person = (Person) o; return name.equals(person.name); } @Override public int hashCode() { System.out.println("Call hashCode(),age="+age); return age; } } }上述程式碼的執行結果如下:
--------- --------- List size=3 ----分割线----- Call hashCode(),age=10 --------- Call hashCode(),age=10 Call equals();name=lxp --------- Call hashCode(),age=20 Set size=2從結果看出,元素加入List的時候,不執行額外的操作,可以重複。而加入Set之前需要先執行hashCode方法,如果傳回的值在集合中已存在,要繼續執行equals方法,如果equals方法傳回的結果也為真,則證明該元素已經存在,會將新的元素覆寫老的元素,如果回傳hashCode值不同,則直接加入集合。這裡記住一點,對於集合中元素,hashCode值不同的元素一定不相等,但是不相等的元素,hashCode值可能相同。
public interface Iterator<E> { boolean hasNext(); E next(); void remove(); }
2、Map:
#
Map类型的集合最大的优点在于其查找效率比较高,理想情况下可以实现O(1)的时间复杂度。Map中最常用的是HashMap,LinkedHashMap与HashMap的区别在于前者能够保证插入集合的元素顺序与输出顺序一致。这两者与TreeMap的区别在于TreeMap是根据键值进行排序的,当然其底层的实现也有本质的区别,如HashMap底层是一个哈希表,而TreeMap的底层数据结构是一棵树。我们现在看下TreeMap与LinkedHashMap的区别:
package com.paddx.test.collection; import java.util.Iterator; import java.util.LinkedHashMap; import java.util.Map; import java.util.TreeMap; public class MapTest { public static void main(String[] args) { Map<String,String> treeMap = new TreeMap<String,String>(); Map<String,String> linkedMap = new LinkedHashMap<String, String>(); treeMap.put("b",null); treeMap.put("c",null); treeMap.put("a",null); for (Iterator<String> iter = treeMap.keySet().iterator();iter.hasNext();){ System.out.println("TreeMap="+iter.next()); } System.out.println("----------分割线---------"); linkedMap.put("b",null); linkedMap.put("c",null); linkedMap.put("a",null); for (Iterator<String> iter = linkedMap.keySet().iterator();iter.hasNext();){ System.out.println("LinkedHashMap="+iter.next()); } } }
运行上述代码,执行结果如下:
TreeMap=a TreeMap=b TreeMap=c ----------分割线--------- LinkedHashMap=b LinkedHashMap=c LinkedHashMap=a
从运行结果可以很明显的看出这TreeMap和LinkedHashMap的区别,前者是按字符串排序进行输出的,而后者是根据插入顺序进行输出的。细心的读者可以发现,HashMap与TreeMap的区别,与之前提到的HashSet与TreeSet的区别是一致的,在后续进行源码分析的时候,我们可以看到HashSet和TreeSet本质上分别是通过HashMap和TreeMap来实现的,所以它们的区别自然也是相同的。HashTable现在已经很少使用了,与HashMap的主要区别是HashTable是线程安全的,不过由于其效率比较低,所以通常使用HashMap,在多线程环境下,通常用CurrentHashMap来代替。
三、总结
本文只是从整体上介绍了Java集合框架及其继承关系。除了上述类,集合还提供Collections和Arrays两个工具类,此外,集合中排序跟Comparable和Comparator紧密相关。
以上是什麼是Java中集合類別?集合類別結構圖文實例講解的詳細內容。更多資訊請關注PHP中文網其他相關文章!