0、集合接口及其實現類之間的關係
- Collection接口
Collection的超級接口:Iterable接口。
1>Collection接口常用方法
操作 |
方法 |
增 |
add(E e)、addAll(Collection<? extends E> c)、 |
刪 |
clear()、remove(Object o)、removeAll(Collection<?> c)、retainAll(Collection<?> c)、 |
改 |
|
查 |
contains(Object o)、containsAll(Collection<?> c)、 equals(Object o)、isEmpty()、size() |
其他 |
hashCode()、 |
遍歷 |
iterator()、foreach |
2>Collection接口的方法使用舉例(PracticeCollection.java)
Collection<String> aList = new ArrayList<>(); Collection<String> aList1 = new ArrayList<>(); Collection<String> aList2 = new ArrayList<>(); // 1.add aList.add("Java Development"); aList1.add(" is very GOOD!"); aList2.add("Java Development"); // 2.addAll aList.addAll(aList1); // 3.clear // aList1.clear(); // 4.contains System.out.println(aList.contains("Java Development"));// true System.out.println(aList.contains("Java"));// false // 5.containsAll System.out.println(aList.containsAll(aList2));// ture // 6.equals System.out.println(aList.equals(aList2));// false // 7.hashCode int hCode = aList.hashCode(); System.out.println(hCode); // 8.isEmpty System.out.println(aList.isEmpty());// false // 9.iterator System.out.println("********9**********"); for (Iterator<String> it = aList.iterator(); it.hasNext();) { System.out.println(it.next()); } // 10.remove System.out.println("********10**********"); System.out.println(aList.remove("Java Development"));// true for (Iterator<String> it = aList.iterator(); it.hasNext();) { System.out.println(it.next()); } // 11.removeAll System.out.println(aList.removeAll(aList2));//ture // 12.retainAll System.out.println("********12**********"); System.out.println(aList.retainAll(aList2)); Iterator<String> it1 = aList.iterator(); while (it1.hasNext()) { System.out.println(it1.next()); } // 13.size System.out.println(aList.size());// 2 // 14.toArray Object[] string = aList.toArray(); System.out.println(Arrays.toString(string));// 注意使用Arrays.toString方法 // foreach遍歷 System.out.println("********foreach********** "); for (Object object : aList) { System.out.println(object); } System.out.println("********iterator**********"); Iterator<String> it2 = aList.iterator(); while (it2.hasNext()) { System.out.println(it2.next()); } |
3>Collection的遍歷
[1]、Foreach快速遍歷
System.out.println("********foreach********** "); for (Object object : aList) { System.out.println(object); } |
[2]、遍歷器(Iterator)遍歷
Iterator<String> it2 = aList.iterator(); while (it2.hasNext()) { System.out.println(it2.next()); } |
性能較高的for循環遍歷 |
for (Iterator<String> it = aList.iterator(); it.hasNext();) { System.out.println(it.next()); } |
1.2 List接口
List接口表示有序(插入順序)、不唯一的集合。此接口的用戶可以對列表中每個元素的插入位置進行精確地控制。
List 接口提供了 4 種對列表元素進行定位(索引)訪問方法。
List 接口提供了特殊的迭代器,稱爲 listIterator,除了允許 Iterator 接口提供的正常操作外,該迭代器還允許元素插入和替換,以及雙向訪問。還提供了一個方法來獲取從列表中指定位置開始的列表迭代器。
List的超級接口:Iterable、Collection
- List接口常用方法
操作 |
方法(與超級接口Collection相同的不再寫出) |
增 |
add(E e)、add(int index, E element)、 addAll(Collection<? extends E> c)、 addAll(int index, Collection<? extends E> c) |
刪 |
remove(int index) |
改 |
set(int index, E element) |
查 |
get(int index)、indexOf(Object o)、lastIndexOf、 lastIndexOf(Object o) |
其他 |
subList(int fromIndex, int toIndex) |
遍歷 |
listIterator()、listIterator(int index) |
- List接口的方法使用舉例(PracticeList.java)
List<Integer> list = new LinkedList<>(); List<Integer> list1 = new LinkedList<>(); list.add(20); list.add(30); list1.add(60); list1.add(80); //1.add(帶索引) list.add(0,10); //2.addAll(帶索引) list.addAll(0,list1); //3.remove(帶索引) //list.remove(2); //4.set list.set(0, 100);//60-->100 //5.get Integer integer1 = list.get(0);//100 //6.indexOf int a = list.indexOf(60);//-1 爲不存在該元素 int b = list.indexOf(30);//4 //7.lastIndexOf int c = list.lastIndexOf(20); //8.subList List<Integer> list2 = new LinkedList<>(); list2 = list.subList(2, 5);//取出2~5的元素 //9.listIterator System.out.println("**************listIterato順序遍歷r********"); ListIterator<Integer> it2 = list.listIterator(); while(it2.hasNext()) { System.out.println(it2.next()); } System.out.println("**************listIterator倒序遍歷********"); while (it2.hasPrevious()) { System.out.println(it2.previous()); } |
- List的遍歷
[1]、普通For循環利用index遍歷
System.out.println("*******普通For循環遍歷*********"); for (int i = 0; i < list.size(); i++) { System.out.println(list.get(i)); } |
[2]、foreach快速遍歷
System.out.println("*******快速遍歷***********"); for(Object o :list) { System.out.println(o); } |
[3]、iterator遍歷器遍歷
System.out.println("*******iterator遍歷器遍歷***********"); for(Iterator<Integer> it3 = list.iterator();it3.hasNext();) { System.out.println(it3.next()); } |
[4]、listIterator遍歷器遍歷
System.out.println("*******listIterator遍歷器遍歷***********"); for(ListIterator<Integer> it4 = list.listIterator();it4.hasNext();) { System.out.println(it4.next()); } |
1.2.1 實現類ArrayList
List 接口的大小可變數組的實現。
此類的 iterator 和 listIterator 方法返回的迭代器是快速失敗的:在創建迭代器之後,除非通過迭代器自身的 remove 或 add 方法從結構上對列表進行修改,否則在任何時間以任何方式對列表進行修改,迭代器都會拋出 ConcurrentModificationException。因此,面對併發的修改,迭代器很快就會完全失敗,而不是冒着在將來某個不確定時間發生任意不確定行爲的風險。
- ArrayList的數據結構
ArrayList是一種先行數據結構,底層數據接口是數組,數組不能擴容,而ArrayList可以通過Arrays.copyOf擴容。
- ArrayList常用方法
ArrayList常用方法與List基本一致。
特有:trimTosize();將此ArrayList實例的容量調整爲列表的當前大小。
- ArrayList的遍歷
ArrayList遍歷與List遍歷一樣有四種:for循環遍歷、foreach遍歷、iterator遍歷、listIterator遍歷。
1.2.2 實現類LinkedList
LinkedList與ArrayList一樣實現List接口,只是ArrayList是List接口的大小可變數組的實現,LinkedList是List接口鏈表的實現。基於鏈表實現的方式使得LinkedList在插入和刪除時更優於ArrayList,而隨機訪問則比ArrayList遜色些。
LinkedList實現了 Deque 接口,爲 add、poll 提供先進先出隊列操作,以及其他堆棧和雙端隊列操作。
1>LinkedList數據結構
底層數據結構是雙向鏈表。
2>LinkedList常用方法
|
JDK1.5 |
JDK1.6 |
指定元素插入 |
offer(E e)末尾 |
offerFirst(E e)、offerLast(E e) |
獲取並不移除 |
peek () |
peekFirst()、peekLast() |
獲取並移除 |
poll()首 |
pollFirst()、pollLast() |
3>LinkedList常用方法使用舉例
public class LinkedListTest01 { public static void main(String[] args) { LinkedList<Double> list = new LinkedList<>(); LinkedList<Double> list2 = new LinkedList<>(); list.add(3.14); list.add(0, 1.414); list2.add(0, 1.732); list2.add(1, 1.738); System.out.println(list); System.out.println(list2); System.out.println("***********************"); list.addAll(list2); System.out.println(list); // list.offer(1.732); // list.offerLast(1.732); // list.offerFirst(1.732); // System.out.println(list.peek()); // System.out.println(list.peekFirst()); // System.out.println(list.peekLast()); // System.out.println(list.poll()); // System.out.println(list.pollFirst()); // System.out.println(list.pollLast()); System.out.println(list); } } |
4>LinkedList的遍歷
LinkedList的遍歷有7種:迭代器遍歷、快速隨機遍歷、foreach遍歷、pollFirst()方法遍歷、pollLast()方法遍歷、removeFirst()方法遍歷、removeLast()方法遍歷。
其中效率最高的是foreach遍歷。
1.2.3 實現類Vector
Vector與ArrayList的區別:
1. Vector產生與JDK1.0,ArrayList產生與JDK1.2;
2. Vector線程安全,ArrayList線程不安全;
3. ArrayList耗能低,性能高,Vector耗能高,性能低。
1.3 Set接口
1>Set數據結構
set是一個不包含重複元素的 collection。
注:如果將可變對象用作 set 元素,那麼必須極其小心。如果對象是 set 中某個元素,以一種影響 equals 比較的方式改變對象的值,那麼 set 的行爲就是不確定的。此項禁止的一個特殊情況是不允許某個 set 包含其自身作爲元素。
2>Set常用方法
Set的常用方法與Collection相似,不做介紹
- Set的遍歷
Set的遍歷有兩種方式:foreach遍歷、iterator方法遍歷。
1.3.1 實現類HashSet
HashSet底層的數據結構是哈希表。
|
1> HashSet的遍歷
HashSet有兩種遍歷方式爲:foreach遍歷、iterator遍歷。
2>重寫hashCode及equals方法
由於Set集合要求數據無序並且無重複,就需要先判斷對象是否是同樣內容再去添加,這樣就導致要去重寫hashCode以及equals方法,已實現對比對象的信息是否一致。
@Override public int hashCode() { final int prime = 31; int result = 1; result = prime * result + ((Name == null) ? 0 : Name.hashCode()); result = prime * result + age; result = prime * result + ((sex == null) ? 0 : sex.hashCode()); long temp; temp = Double.doubleToLongBits(weight); result = prime * result + (int) (temp ^ (temp >>> 32)); return result; }
@Override public boolean equals(Object obj) { if (this == obj) return true; if (obj == null) return false; if (getClass() != obj.getClass()) return false; Person other = (Person) obj; if (Name == null) { if (other.Name != null) return false; } else if (!Name.equals(other.Name)) return false; if (age != other.age) return false; if (sex != other.sex) return false; if (Double.doubleToLongBits(weight) != Double.doubleToLongBits(other.weight)) return false; return true; }
|
1.3.2 實現類LinkedHashSet
1>LInkedHashSet數據結構
底層爲哈希表+鏈表,用於維持次序(插入次序),
其常用方法與HashSet一致。
優點:查找速度更快、缺點:數據結構複雜。
2>LinkedHashSet的遍歷
LInkedHashSet有兩種遍歷方法:foreach遍歷、Iterator遍歷器遍歷
1.3.3 實現類TreeSet
1>TressSet數據結構
TreeSet:二叉樹(紅黑樹)的存儲結構,存入數據以自然順序排列(內部排序)。
2>TreeSet常用方法
操作 |
方法 |
增 |
|
刪 |
|
改 |
|
查 |
ceiling(E e)、first()、floor(E e)、higher(E e)、last()、lower(E e)、 pollFirst()、pollLast()、 subSet(E fromElement, boolean fromInclusive, E toElement, boolean toInclusive)、 |
其他 |
|
遍歷 |
descendingIterator()、iterator() |
3>TreeSet的遍歷
TreeSet的遍歷有三種方式:foreach遍歷、Iterator遍歷器遍歷、descendingIterator方法降序遍歷。
[1]、foreach遍歷
System.out.println("************foreach******************"); for (Integer integer : ts) { System.out.println(integer); } |
[2]、Iterator遍歷器遍歷
System.out.println("****************Iterator***************"); for(Iterator<Integer> iterator = ts.iterator();iterator.hasNext();) { System.out.println(iterator.next()); } |
[3]、descendingIterator方法降序遍歷
System.out.println("***********descendingIterator*********"); for (Iterator<Integer> iterator = ts.descendingIterator(); iterator.hasNext();) { System.out.println(iterator.next()); } |
4>有關實現comparable接口並實現CompareTo接口
對於TreeSet中保存的自定義類型對象,此時就需要實現Comparable接口並實現CompareTo方法。
示例:
public class Person implements Comparable<Person> @Override public int compareTo(Person o) {
return this.Name.compareTo(o.Name); } |
示例2:外部比較器
TreeSet<Person1> ts = new TreeSet<>(new Comparator<Person1>() { @Override public int compare(Person1 o1, Person1 o2) { return o1.getAge()-o2.getAge(); } }); |
- Map<K,V>接口
類型參數:
K:-此映射所維護的鍵的模型
V:-映射值的類型
將鍵映射到值得對象。一個映射不能包含重複的鍵;每個鍵最多隻能映射到一個值。
Map接口提供三種collection視圖,允許以鍵集、值集、或鍵-值映射關係的形成查看某個映射的內容。映射順序定義爲迭代器在映射的collection視圖上返回其元素的順序。某些映射實現可以明確保證其順序,如TreeMap類;另一些映射實現則不保證順序,如HashMap類。
實現類:HashMap、Hashtable、LinkedHashMap、TreeMap。
key通過Set存儲;value通過Collection存儲。
1>Map接口常用方法
操作 |
方法 |
增 |
put(K key, V value)、 |
刪 |
clear()、remove(Object key)、 |
改 |
|
查 |
containsKey(Object key)、containsValue(Object value)、 get(Object key)、size() |
其他 |
|
遍歷 |
entrySet()、keySet() |
2>Map的遍歷
Map的遍歷有兩種方法,分別爲使用entrySet()方法、keySet()方法。
[1]、使用keySet()方法得到key值,並通過key值得到對應的value值
示例:
System.out.println("***iterator//keySet()方法->得到key->通過key遍歷***"); for(Iterator<Integer> iterator = hm.keySet().iterator();iterator.hasNext();) { int key = iterator.next();//得出鍵k System.out.println(key+":"+hm.get(key));//得出key對應的value } |
[2]、利用entrySet()方法實現遍歷
entrySet()方法會有一個Set<Map.Entry<K,V>>類型的返回值,通過該返回值讀取鍵值對,可以實現效率更高的遍歷。
示例1:
System.out.println("***iterator//Map.Entry接口+entrySet方法+foreach實現遍歷①***"); Set<java.util.Map.Entry<Integer, Integer>> entrySet= hm.entrySet(); for(java.util.Map.Entry<Integer, Integer> entry :entrySet) { System.out.println(entry.getKey()+":"+entry.getValue()); } |
示例2:
System.out.println("***iterator//Map.Entry接口+entrySet方法+for遍歷②***"); for(Iterator<java.util.Map.Entry<Integer, Integer>> iterator = entrySet.iterator();iterator.hasNext();) { System.out.println(iterator.next()); } |
示例3:
System.out.println("***iterator//Map.Entry接口+entrySet方法+for遍歷③***"); for(Iterator<java.util.Map.Entry<Integer, Integer>> iterator = entrySet.iterator();iterator.hasNext();) { java.util.Map.Entry<Integer, Integer> entry2 = iterator.next(); System.out.println(entry2.getKey()+":"+entry2.getValue()); } |
-
- 實現類HashMap
基於哈希表的Map接口的實現,此實現提供所有可選的映射操作,並允許使用null值和null鍵。(除了非同步和允許使用null之外,HashMap與Hashtable大致相同。)此類不保證映射的順序,特別是它不保證該順序恆久不變。
HashMap的實例有兩個參數影響其性能,初始容量和加載因子,容量是哈希表中桶的數量,初始容量只是哈希表在創建時的容量。加載因子是哈希表在其容量自動增加之前可以達到多慢的一種尺度,當哈希表中的條目數超出了加載因子與當前容量的乘積時,則要對哈希表進行rehash操作(重建內部數據結構),從而哈希表將具有大約兩倍的桶數。
此實現並不是同步的。
key通過HashSet存儲、value通過Collection存儲
2.2 實現類Hashtable
線程安全版的HashMap,性能遜於HashMap。
HashMap源於JDK1.2;Hashtable源於JDK1.0;
HashMap線程不安全,Hashtable線程安全;
HashMap耗能低,速度快,Hashtable耗能高,速度慢。
2.3 實現類LinkedHashMap
key通過LinkedHashSet存儲、value通過Collection存儲
2.4 實現類TreeMap
key通過TreeMap存儲、value通過Collection存儲
性能比較