Collection接口:單列數據,定義了存取-組對象的方法集合;html
說明:此時的存儲,主要指的是內存層面的存儲,不涉及到持久化的存儲;算法
2.1數組在存儲多個數據方面的特色;數組
a.數據一旦初始化後,長度就肯定了,安全
b.一旦定義好,其元素的類型也肯定,只能操做指定類型的元素;ide
2.2數組在存儲多個數據方面的缺點函數
a.數據一旦初始化後,長度就肯定了,不方便;源碼分析
b.數組中提供的方法很是有限,對添加、刪除、插入數據等操做,很是有限測試
c.獲取數組中實際元素的個數,數組沒有現成的屬性和方法ui
d.存儲數據的特色:有序、可重複。對於無線、不可重複的須要,不能知足;this
思惟導圖地址:https://www.cnblogs.com/lixiuming521125/p/14626222.html
注意:向Collection接口的實現類的對象中添加數據obj時,要求obj所在類要重寫equals方法;
Collection 15個方法;
測試方法代碼以下:
1 @Test 2 public void test1() { 3 Collection coll = new ArrayList(); 4 //1.add(Object e):將元素e添加到集合coll中; 5 coll.add("AA"); 6 coll.add("BB"); 7 coll.add(123); 8 coll.add(new Date()); 9 System.out.println("Collection中的add()方法:"+coll); 10 //size():獲取添加元素的個數 11 System.out.println("Collection中的size()方法:"+coll.size()); 12 //addAll(Collection c),將coll1集合中的元素添加到當前集合中 13 Collection coll1 = new ArrayList(); 14 coll1.add(1234); 15 coll1.add("abc"); 16 coll.addAll(coll1); 17 System.out.println(coll.size());//6 18 System.out.println("Collection中的addAll()方法:"+coll.toString()+",此時 coll元素個數:"+coll.size()); 19 20 //isEmpty():判斷當前元素是否爲空; 21 System.out.println("Collection中的isEmpty()方法:"+coll.isEmpty());//false,就是看size()是否爲0; 22 23 //clear():清空集合元素 24 coll.clear(); 25 System.out.println("Collection中的clear()方法,此時coll:"+coll.isEmpty());//true 26 27 coll.add(123); 28 coll.add(456); 29 coll.add(123); 30 coll.add(new String("tom")); 31 coll.add(false); 32 coll.add(new Person("joy",1)); 33 //contains(Object obj):判斷當前集合中是否包含obj 34 boolean contain = coll.contains(123); 35 System.out.println("Collection中的contains()方法,此時返回boolean:"+contain); 36 System.out.println(coll.add(new String("tom")));//判斷的是內容,調用的是equals方法; 37 System.out.println(coll.contains(new Person("joy",1)));//判斷的是內容 38 //2.containsAll(collection coll1) 39 //判斷新城coll1中全部元素是否都存在於當前集合中; 40 coll1.clear(); 41 coll1.add(123); 42 coll1.add(456); 43 boolean flag = coll.containsAll(coll1); 44 System.out.println(flag); 45 System.out.println("Collection中的containsAll()方法,此時返回boolean:"+flag); 46 47 //remove(Object obj)移除對象(從當前集合中),只移除一個對象; 48 boolean removeFlag = coll.remove(123); 49 System.out.println("Collection中的remove()方法,此時返回boolean:"+removeFlag); 50 System.out.println("Collection中的remove()方法,此時返回coll:"+coll.toString()); 51 //removeAll(Collection coll1),從當前集合中移除全部的coll1中存在的元素; 52 System.out.println(coll.removeAll(coll1)); 53 System.out.println("Collection中的removeAll()方法,此時返回coll:"+coll.toString()); 54 55 //retainAll(coll1) 取當前集合和coll1 的交集 ,交集給了當前集合; 56 //[123, 456, 123, tom, false, Person [name=joy, age=1], tom] 57 //[123, 456] 58 //交集就是[123, 456] 59 / 60 coll.retainAll(coll1); System.out.println(coll); 61 / 62 63 64 //equals(Object obj) obj也是集合,比較兩個集合是否同樣;集合中的各個元素順序必須同樣才能夠; 65 Collection coll6 = new ArrayList(); 66 Collection coll7 = new ArrayList(); 67 Collection coll8 = new ArrayList(); 68 coll6.add(123); 69 coll6.add(456); 70 coll6.add(789); 71 coll7.add(123); 72 coll7.add(456); 73 coll7.add(789); 74 coll8.add(789); 75 coll8.add(456); 76 coll8.add(123); 77 System.out.println("Collection中的equals()方法,equeal結果:"+coll6.equals(coll7)); 78 System.out.println("Collection中的equals()方法,equeal結果:"+coll6.equals(coll8)); 79 80 //hashCode();返回當前對象的哈希值 81 System.out.println("Collection中的hashCode()方法,當前hashcode值:"+coll8.hashCode()); 82 83 //toArray()集合轉數組 84 Object[] arr = coll.toArray(); 85 for(int i = 0;i<arr.length;i++) { 86 System.out.println("第"+(i+1)+"個元素:"+arr[i]); 87 } 88 //拓展:數組轉集合 89 List<String> asList = Arrays.asList(new String[] {"aa","bb","cc"}); 90 System.out.println(asList); 91 92 //iterator():返回接口的實例,擁有遍歷集合元素。 93 //內部方法: hasNext()和next()方法 94 //原理圖 95 Iterator iterator = coll.iterator(); 96 while(iterator.hasNext()) { 97 System.out.println("iterator遍歷:"+iterator.next()); 98 } 99 100 //iterator():移除當前集合中的某條數據數據 101 //內部的方法:hasNext()和next(); 102 //集合對象每次調用iterator()方法都獲得一個全新的迭代器對象 103 //默認遊標都在集合的第一個元素以前 104 //內部定義了remove()方法,能夠在遍歷的時候,刪除集合中的元素,此方法不一樣於集合直接調用remove(); 105 //若是還未調用next()或上一次調用next方法以後已經調用了remove方法,再調用remove都會報錯; 106 iterator = coll.iterator(); 107 while(iterator.hasNext()) { 108 Object obj = iterator.next(); 109 if(obj.equals("tom")) { 110 iterator.remove();//移除 111 } 112 } 113 iterator = coll.iterator(); 114 while(iterator.hasNext()) { 115 Object obj = iterator.next(); 116 System.out.println("iterator刪除後"+iterator.next()); 117 } 118 System.out.println("coll.toString()=>"+coll.toString()); 119 120 //補充:foreach循環,用於遍歷集合、數組(jdk1.5新增) 121 //for(集合元素的類型 局部遍歷:集合對象) 122 //此種方式不能更改值 123 for(Object obj:coll){ 124 System.out.println("foreach=》"+obj); 125 } 126 }
jdk7狀況下:
ArrayList list = new ArrayList();//底層建立了長度爲10的Object[]數組 Object[] elementData; list.add(123); ... list.add(111);//若是這次的添加致使底層elementData數組容量不夠,則擴容,相似StringBuilder;
關於擴容:默認狀況下,擴容爲原來的1.5倍,同時須要將原有數組種的數據複製到新的數組中;
結論:建議開發中使用帶參的構造器,ArrayList list = new ArrayList(int capacity);指定數組長度;
jdk8狀況下:
1 ArrayList list = new ArrayList();//底層Object[] elementData初始化爲{},並無建立長度爲10的數組; 2 3 list.add(123);//第一次調用add(),底層才建立長度爲10的數組,並把數據123添加到elementData; 後續與1.7一致;
小結:jdk1.7中的ArrayList的對象的建立相似於單例的餓漢式,1.8的相似於懶漢式,1.8延遲建立數組,節省內存;
LinkedList list = new LinkedList();//內部聲明瞭Node類型的first 和last屬性,默認值爲null; list.add(123);//將123封裝到Node中,建立了Node對象;
其中,Node定義爲:提現了LinkedList的雙向鏈表的說法;
1 private static class Node<E> { 2 E item; 3 Node<E> next; Node<E> prev; 4 5 Node(Node<E> prev, E element, Node<E> next) { 6 this.item = element; 7 this.next= next; this.prev = prev; 8 } 9 }
總結:經常使用方法
測試經常使用方法:
@Test public void test1() { ArrayList arrayList = new ArrayList(); arrayList.add(123); arrayList.add(456); arrayList.add("AA"); arrayList.add(new Person("Tom",1)); arrayList.add(456); System.out.println(arrayList.toString()); //void add(int inde,Object elemnet),在index位置插入element元素 arrayList.add(1, "BB"); System.out.println(arrayList.toString()); //void addAll(int inde,Collection elemnets),在index位置插入elements的全部功能元素元素 ArrayList arrayList2 = new ArrayList(); arrayList2.add("aa"); arrayList2.add("bb"); arrayList.addAll(1, arrayList2); System.out.println(arrayList.toString()); //查看元素個數 System.out.println(arrayList.size()); //訪問第一個元素 System.out.println(arrayList.get(0)); //int indexOf(Object obj);返回obj在集合中首次出現的位置,沒有返回-1; System.out.println(arrayList.indexOf("AA")); //int lastIndexOf(Object obj)回obj在集合中末次出現的位置 System.out.println(arrayList.lastIndexOf(456)); //Object remove(int index),移除指定index位置的元素返回刪除元素的對象 System.out.println(arrayList.remove(7)); //Object set(int index,Object ele):設置指定index位置的元素爲ele; System.out.println(arrayList.set(0, "set"));//設置指定index位置的元素爲ele; System.out.println(arrayList.toString()); //List subList(int fromIndex,int toIndex);返回從fromIndex到toIndex位置的集合; System.out.println(arrayList.subList(0, 4)); //遍歷List Iterator iterator = arrayList.iterator(); while(iterator.hasNext()) { System.out.println(iterator.next()); } for(Object obj : arrayList) { System.out.println(obj); } for(int i=0;i<arrayList.size();i++) { System.out.println(arrayList.get(i)); } }
1.無序性:可是不是隨機性;無序性是指,元素插入的位置不是按順序插入,而是隨機插入
2.不可重複性:保證添加的元素 ,按照equals()方法判斷時,不能返回true,即:相同的元素只能添加一個
咱們想HashSet中,添加元素a:
一、首先調用元素a所在類的hasCode()方法,計算元素a的哈希值,
此哈希值接着經過某種計算出在HashSet底層數組中的存放位置(即:索引位置);
二、判斷數組此位置上是否已經有元素;
若是此數組此位置上沒有其餘元素,則元素a添加成功;-----》狀況1
若是此位置上有其餘元素b(或以鏈表形式存在多個元素),則比較元素a與元素b的hash值,
若是hash值不相同,則元素a,添加成功;-----》狀況2
若是has值相同,進而須要調用元素a所在類的equals方法,比較
equals返回true,元素a添加失敗,不然元素a添加成功;---------》狀況3
對於添加成功的狀況2和狀況3而言,元素a 與已經存在指定位置上索引位置上數據以鏈表形式存儲;
補充:
1 @Test 2 public void test1() { 3 Set set = new HashSet(); 4 set.add(456); 5 set.add(123); 6 set.add("AA"); 7 set.add("AA"); 8 set.add("CC"); 9 set.add(new Person("Tom",12)); 10 set.add(new Person("Tom",12));//若是Person類沒有重寫 equals和hashCode,則仍是會出現兩個Tom, 11 set.add(129); 12 Iterator iterator = set.iterator(); 13 while(iterator.hasNext()) { 14 System.out.println(iterator.next()); 15 } 16 }
LinkedHashSet的使用:(按照插入順序輸出)
做爲hashset的子類,在添加數據的同時,還維護了每一個數據的 兩個引用,記錄了前一個數據和後一個數據
優勢:遍歷頻繁的操做,效率較高
1 /** 2 *linkedHashSet的使用: 3 *做爲hashset的子類,在添加數據的同時,還維護了每一個數據的 兩個引用,記錄了前一個數據和後一個數據 4 *優勢:遍歷頻繁的操做,效率較高; 5 * 6 */ 7 @Test 8 public void test2() { 9 LinkedHashSet set = new LinkedHashSet(); 10 set.add(456); 11 set.add(123); 12 set.add("AA"); 13 set.add("AA"); 14 set.add("CC"); 15 set.add(new Person("Tom",12)); 16 set.add(new Person("Tom",12));//若是Person類沒有重寫 equals和hashCode,則仍是會出現兩個Tom, 17 set.add(129); 18 Iterator iterator = set.iterator(); 19 while(iterator.hasNext()) { 20 System.out.println(iterator.next()); 21 } 22 }
TreeSet的使用:
1.向TreeSet中添加的數據,要求是相同類的對;
* TreeSet 的類的對象中,必須實現Compare接口orComparator接口(Compare接口orComparator接口的使用可點擊查看)
* 天然排序中,比較兩對象是否相同的標準爲;CompareTo()返回0,再也不是equals();
1 @Test 2 public void test3() { 3 TreeSet set = new TreeSet(); 4 set.add(new Person("Tom",12)); 5 set.add(new Person("Joy",14));//若是Person類沒有重寫 equals和hashCode,則仍是會出現兩個Tom, 6 set.add(new Person("Jay",14));// 7 Iterator iterator = set.iterator(); 8 while(iterator.hasNext()) { 9 System.out.println(iterator.next()); 10 } 11 } 12 //TreeSet Comparator接口實現方法 13 @Test 14 public void test4() { 15 Comparator com = new Comparator<Person>() { 16 @Override 17 public int compare(Person o1, Person o2) { 18 // TODO Auto-generated method stub 19 return o1.getName().compareTo(o2.getName()); 20 } 21 22 23 24 }; 25 TreeSet set = new TreeSet(com); 26 set.add(new Person("Tom",12)); 27 set.add(new Person("Joy",14));//若是Person類沒有重寫 equals和hashCode,則仍是會出現兩個Tom, 28 set.add(new Person("Jay",14));// 29 Iterator iterator = set.iterator(); 30 while(iterator.hasNext()) { 31 System.out.println(iterator.next()); 32 } 33 }
Person類:
1 package collection; 2 3 public class Person implements Comparable { 4 5 private String name; 6 private int age; 7 public String getName() { 8 return name; 9 } 10 public void setName(String name) { 11 this.name = name; 12 } 13 public int getAge() { 14 return age; 15 } 16 public void setAge(int age) { 17 this.age = age; 18 } 19 public Person(String name, int age) { 20 super(); 21 this.name = name; 22 this.age = age; 23 } 24 public Person() { 25 super(); 26 } 27 @Override 28 public String toString() { 29 return "Person [name=" + name + ", age=" + age + "]"; 30 } 31 @Override 32 public int hashCode() { 33 final int prime = 31;//這裏使用31爲了減小衝突、提升算法效率 34 int result = 1; 35 result = prime * result + age; 36 result = prime * result + ((name == null) ? 0 : name.hashCode()); 37 return result; 38 } 39 @Override 40 public boolean equals(Object obj) { 41 if (this == obj) 42 return true; 43 if (obj == null) 44 return false; 45 if (getClass() != obj.getClass()) 46 return false; 47 Person other = (Person) obj; 48 if (age != other.age) 49 return false; 50 if (name == null) { 51 if (other.name != null) 52 return false; 53 } else if (!name.equals(other.name)) 54 return false; 55 return true; 56 } 57 @Override 58 public int compareTo(Object o) { 59 Person person = (Person)o; 60 if(this.age>person.age) { 61 return -1; 62 }else { 63 return 1; 64 } 65 66 } 67 68 69 }
Set集合不容許包含相同的元素;若是試把兩個相同的元素加入同一個Set集合中,則添加操做失敗
Set判斷兩個對象是都相同不是使用 == 運算符,而是根據equals()方法;