十一(一)、集合之Collection

1、Collection

Collection接口:單列數據,定義了存取-組對象的方法集合;html

1.集合、數組都是對多個數據進行存儲操做的結構,簡稱Java容器;

  說明:此時的存儲,主要指的是內存層面的存儲,不涉及到持久化的存儲;算法

2.  數組在存儲多個數據方特色

 2.1數組在存儲多個數據方面的特色;數組

  a.數據一旦初始化後,長度就肯定了,安全

  b.一旦定義好,其元素的類型也肯定,只能操做指定類型的元素;ide

 2.2數組在存儲多個數據方面的缺點函數

  a.數據一旦初始化後,長度就肯定了,不方便;源碼分析

  b.數組中提供的方法很是有限,對添加、刪除、插入數據等操做,很是有限測試

  c.獲取數組中實際元素的個數,數組沒有現成的屬性和方法ui

  d.存儲數據的特色:有序、可重複。對於無線、不可重複的須要,不能知足;this

  

2、Java集合能夠分爲Collection 和 Map體系;

  •   Collection接口:單列數據,定義了存取-組對象的方法集合;
  1. List:元素有序、可重複的集合(動態數組):ArrayList/LinkedList/Vector
  2. Set:無序、不可重複的集合;(高中的集合):HashSet/LinkedHashSet/TreeSet

     

  •   Map接口:雙列數據;保存具備映射關係 「key-value」的集合;(高中函數)
  1. HashMap/LinkedHashMap/TreeMap/HashTable/Properties

思惟導圖地址:https://www.cnblogs.com/lixiuming521125/p/14626222.html

3、Collection中的方法;

  注意:向Collection接口的實現類的對象中添加數據obj時,要求obj所在類要重寫equals方法;

  Collection 15個方法;

  1.  boolean add(E e) 向集合中添加元素  
  2.  void clear()  清空集合    
  3.  boolean contains(Object o) 若是此 collection 包含指定的元素,則返回 true。 
  4.  boolean containsAll(Collection<?> c) 若是此 collection 包含指定 collection 中的全部元素,則返回 true。 
  5.  boolean equals(Object o) :比較此 collection 與指定對象是否相等。 
  6.  int hashCode() :返回此 collection 的哈希碼值。 
  7.  boolean isEmpty() :若是此 collection 不包含元素,則返回 true(查看size()是否爲0)。 
  8.  Iterator<E> iterator() :返回在此 collection 的元素上進行迭代的迭代器。 
  9.  boolean remove(Object o) :今後 collection 中移除指定元素的單個實例,若是存在的話(可選操做)。 
  10.  boolean removeAll(Collection<?> c) :移除此 collection 中那些也包含在指定 collection 中的全部元素(可選操做)。 
  11.  boolean retainAll(Collection<?> c) :僅保留此 collection 中那些也包含在指定 collection 的元素(可選操做)。 
  12.  int size() :返回此 collection 中的元素數。 
  13.  Object[] toArray() :返回包含此 collection 中全部元素的數組。 
  14.  <T> T[] 
  15.  toArray(T[] a) 

測試方法代碼以下:

  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     }

4、List

一、ArrayList源碼分析:

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的源碼分析

 

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 }

三、vector的源碼分析

 

  • jdk7和jdk8中經過Vector()構造器建立對象時,底層都建立了長度爲10的數組
  • 在擴容方面,默認擴容爲原來數組長度的2倍

四、List經常使用方法

  1.    void add(int index,Object ele);在index位置插入ele元素
  2.    boolean addAll(int index,Collection eles),在index位置插入eles中的全部元素添加進來
  3.    Object get(int index)獲取指定index位置的元素;
  4.    int indexOf(Object obj);返回obj在集合中首次出現的位置
  5.    int lastIndexOf(Object obj)回obj在集合中末次出現的位置
  6.    Object remove(int index),移除指定index位置的元素,返回刪除元素的對象
  7.    Object set(int index,Object ele):設置指定index位置的元素爲ele;
  8.    List subList(int fromIndex,int toIndex);返回從fromIndex到toIndex位置的集合;

 總結:經常使用方法

  1.   增:add(Object obj);
  2.   刪:remove(int index)
  3.   改:set(int index,Object ele);
  4.   查:get(int index)
  5.   插;void add(int index,Object ele)
  6.  長度:size()
  7.  遍歷:
  •   Iteraror
  •   for
  •   加強for循環

測試經常使用方法:

@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));
        }
    }

5、Set

一、Set:無序、不可重複的集合;(高中的集合)

  •   HashSet:做爲Set接口的主要實現類,線程不安全,能夠存儲null值;
  •   LinkedHashSet:是HashSet的子類;遍歷內部數據,能夠按照添加的順序遍歷;
  •   TreeSet:使用紅黑樹存儲數據;要求數據是同一個對象new的;能夠按照添加對象的指定屬性排序
  •  關於無序的說明

    1.無序性:可是不是隨機性;無序性是指,元素插入的位置不是按順序插入,而是隨機插入

    2.不可重複性:保證添加的元素 ,按照equals()方法判斷時,不能返回true,即:相同的元素只能添加一個

  • 添加元素的過程(以HashSet爲例):

    咱們想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. jdk7. 元素a放到數組中,指向原來的元素;
  2. jdk8. 原來的元素放到數組中,指向a元素;
  3. hashset底層:數組+鏈表結構存放;

 

  補充:

    1.   Object類中的hashCode方法計算的哈希值是隨機的,因此,須要重寫hashCode方法;
    2.   同理 Object類中的equals方法,默認是==運算符,因此類須要判斷equals,則須要重寫equals方法
    3. HashSet的使用:輸出就是無序的;
 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 }
View Code

 

三、Set接口中沒有定義額外的方法;使用的都是Collectio中聲明過的方法;

  •     要求:向Set中添加的數據,其所在的類必定要重寫hasCode()和equals();
  •     要求:重寫的hashCode()和equals()儘量保持一致,相等的對象必須具備相等的散列碼;
  •     通常重寫的hashCode()就能夠保證一致性;

四、其餘

 Set集合不容許包含相同的元素;若是試把兩個相同的元素加入同一個Set集合中,則添加操做失敗

 Set判斷兩個對象是都相同不是使用 == 運算符,而是根據equals()方法;

相關文章
相關標籤/搜索