Java_集合

定義:html

  是一種工具,就像是容器,能存儲任意數量的具備共同屬性的對象。java

與數組比較優勢:算法

  (1)數組定義後長度不可變,集合長度可變;數組

  (2)數組只能經過下標訪問,且下標類型只能是數字型,而有的集合(map)能夠經過任意類型查找所映射的具體對象。安全

集合框架體系結構:數據結構

  

List的重要實現:ArrayList,LinkedList多線程

  ArrayList:併發

  優勢:ArrayList以相似數組的形式進行存儲,故隨機訪問速度極快;框架

  缺點:不適用進行頻繁的插入或刪除操做,由於每次插入或刪除操做都會移動數組中的元素。工具

ArrayList就是基於數組的一個線性表,只不過長度能夠動態改變。

關於ArrayList的幾點注意:

(1)初始化ArrayList的時候若是沒有指定初始化長度,默認長度爲10

(2)ArrayList在增長新元素的時候若是超過了原始容量,會進行擴容,爲 原始容量*3/2 +1;

(3)ArrayList是線程不安全的,在多線程的狀況下不要使用。

但可使用Vector,由於Vector和ArrayList基本一致,區別在於Vector中的絕大部分方法都使用了同步關鍵字修飾,這樣在多線程的狀況下不會出現併發的錯誤。

Vector的擴容爲原始容量*2;

Vector是ArrayList多線程的替代品。

(4)ArrayList實現遍歷的幾種方法:

public class Test7 { public static void main(String[] args) { List<String> list = new ArrayList<String>(); list.add("hello"); list.add("world"); list.add("!!!"); //一、for循環遍歷 for(String str:list){ System.out.println(str); } for(int i=0;i<list.size();i++){ System.out.println(list.get(i)); } //二、把鏈表變成數組相關的內容進行遍歷 String[] stringArr = new String[list.size()]; list.toArray(stringArr); for(int j=0;j<stringArr.length;j++){ System.out.println(stringArr[j]); } //三、迭代器遍歷 Iterator<String> it = list.iterator(); while(it.hasNext()){ System.out.println(it.next()); } } }

LinkedList:

  優勢:適合於在鏈表中間進行頻繁的進行插入和刪除操做;

  缺點:隨機訪問速度較慢,查找元素須要從頭開始一個一個的找。

  LinkedList就是一種雙向循環鏈表的鏈式線性表,只不過存儲的結構使用的是鏈式表而已。

LinkedList的內部實現:【推薦看jdk源碼】

  LinkedList的內部是基於雙向循環鏈表的結構來實現的。在LinkedList中有一個相似於C語言中結構體的Entry內部類。

  在Entry的內部類中包含了前一個元素的地址引用和後一個元素的地址引用,相似於C語言中的指針。

LinkedList是線程不安全的,若是在多線程下面訪問能夠本身重寫LinkedList,而後在須要同步的方法上面加上同步關鍵字synchronized。

LinkedList的遍歷方法:

package javaEE; import java.util.Iterator; import java.util.LinkedList; import java.util.List; /** * @author 047493 * @version 2018年8月30日 * LinkedList遍歷 */ public class Test8 { public static void main(String[] args) { List<String> list = new LinkedList<String>(); list.add("hello"); list.add("world"); list.add("我是一顆銅豌豆!"); for(String str:list){ System.out.println(str); } /*for(int i=0;i<list.size();i++){ System.out.println(list); }*/ String[] strArr = new String[list.size()]; list.toArray(strArr); for(int j=0;j<strArr.length;j++){ System.out.println(strArr[j]); } Iterator<String> it = list.iterator(); while(it.hasNext()){ System.out.println(it.next()); } } }


因爲LinkedList實現了接口Dueue,因此LinkedList能夠被當作堆棧來使用。

 

Set接口:

Set接口與List接口的區別在於,Set中的元素實現了不重複,有點像集合的概念,無序,不容許有重複的元素,最多容許有一個null元素對象。

須要注意的是:雖然Set中的元素沒有順序,可是元素在Set中的位置是由該元素的hashCode決定的,其具體位置實際上是很固定的。

舉個例子:

對象A和對象B原本是兩個不一樣的對象,正常狀況下它們是能夠同時放到Set集合中去的,可是,若是對象A和對象B都重寫了hashcode和equals方法,而且重寫後的hashcode和equals值相同的話,

那麼A和B就不能同時放到Set集合中去了,也就是說Set集合中的去重和hashcode與equals方法相關。

package javaEE; import java.util.HashSet; import java.util.Set; /** * @author 047493 * @version 2018年8月30日 * 類說明 */ public class Test9 { public static void main(String[] args) { Set<String> set = new HashSet<String>(); set.add("hello"); set.add("world"); set.add("hello"); set.add(null); set.add(null); System.out.println("set的大小爲"+set.size()); System.out.println("set中的元素有"+set.toString()); } }

運行結果以下:

set的大小爲3 set中的元素有[null, hello, world]

因爲String類重寫了hashcode和equals方法,因此第二個hello和null是加不進去的。
遍歷HashSet的幾種方法:

package javaEE; import java.util.HashSet; import java.util.Iterator; import java.util.Set; /** * @author 047493 * @version 2018年8月30日 * 類說明 */ public class Test9 { public static void main(String[] args) { Set<String> set = new HashSet<String>(); set.add("hello"); set.add("world"); set.add("hello"); set.add("我是一顆銅豌豆"); set.add(null); for(String str:set){ System.out.println(str); } String[] arrSet = new String[set.size()]; set.toArray(arrSet); for(int i=0;i<arrSet.length;i++){ System.out.println(arrSet[i]); } Iterator<String> it = set.iterator(); while(it.hasNext()){ System.out.println(it.next()); } } }

LinkedHashSet:
LinkedHashSet不只是Set的子接口,仍是HashSet的子接口。

LinkedHashSet與HashSet的主要區別在於,LinkedHashSet中存儲的元素是在哈希算法的基礎上增長了鏈式表的結構。

TreeSet:

TreeSet是一種排序二叉樹。存入Set集合中的值,會按照值的大小進行相關的排序操做。底層算法是基於紅黑樹實現的;

TreeSet和HashSet的主要區別在於TreeSet中的元素會按照相關的值進行排序;

 

關於HashSet和TreeSet的區別和聯繫:

  1. HashSet是經過HashMap實現的,TreeSet是經過TreeMap實現的,只不過Set用的是Map中的key;
  2. Map的key和Set都有一個共同的特性就是集合的惟一性,TreeMap更是多了一個排序的功能;
  3. hashCde和equals()是hashMap用的,由於無需排序,因此只需關注定位和惟一性便可;

    hashCode是用來計算hash值的,hash值是用來肯定hash表索引的;

    hash表中的一個索引處存放的是一張鏈表,因此還要經過equals()循環比較鏈上的每個對象才能夠真正定位到鍵值對應的Entry;

    put時若是hash表中沒有定位到,就在鏈表前加一個Entry,若是定位到了,則更換Entry中的value,並返回舊的value。

  4.  因爲TreeMap須要排序,因此須要一個Comparator爲鍵值進行大小比較,固然也是用Comparator進行定位的;

    Comparator能夠在建立TreeMap時指定;

    若是建立時沒有指定,那麼就會使用key.compareTo()方法,這就要求key必須實現Comparable接口;

    TreeMap是使用Tree數據結構實現的,因此使用compare接口就能夠完成定位了。

package javaEE; import java.util.Iterator; import java.util.TreeSet; /** * @author 047493 * @version 2018年8月30日 * 類說明 */ public class Test10 { public static void main(String[] args) { TreeSet<String> treeSet = new TreeSet<String>(); treeSet.add("a"); treeSet.add("c"); treeSet.add("d"); treeSet.add("b"); Iterator<String> it = treeSet.iterator(); while(it.hasNext()){ System.out.println(it.next()); } } }

運行結果:

a b c d


Map:

  • Map提供了一種映射關係,其中元素是以鍵值對(key-value)的形式存儲的,可以實現根據key快速查找value;
  • Map中的鍵值對以Entry類型的對象實例形式存在;
  • key不可重複,value值可重複,每一個鍵最多隻能映射到一個值;
  • Map支持泛型,形如:Map<K,V>;
  • Map中使用put<key,value>方法添加。

HashMap:

  • HashMap是Map的一個重要實現類,基於哈希表實現;
  • HashMap中的Entry對象是無序排列的;
  • key值和value值均可覺得null,但一個hashMap只能有一個key值爲null的映射

https://www.cnblogs.com/jpwz/p/5680494.html

 

 

Hash算法:http://www.cnblogs.com/xiohao/p/4389672.html

 

map的幾種遍歷方法:

package javaEE; import java.util.HashMap; import java.util.Iterator; import java.util.Map; import java.util.Map.Entry; /** * @author 047493 * @version 2018年8月30日 * Map的遍歷 */ public class Test11 { public static void main(String[] args) { String[] str = {"i love xiaomei","xiaomei love me","zhaoxin love xiaoli","xiaoli love zhaoxin"}; Map<Integer,String> map = new HashMap<>(); for(int i=0;i<str.length;i++){ map.put(i, str[i]); } //迭代 經過Map.entrySet使用迭代器遍歷key和value Iterator<Entry<Integer, String>> it = map.entrySet().iterator(); while(it.hasNext()){ Map.Entry<Integer, String> entry = (Entry<Integer, String>) it.next(); Integer key = entry.getKey(); String value = entry.getValue(); System.out.println("key:"+key+",value:"+value); } //推薦使用,尤爲容量大時 經過map.entrySet遍歷key和value for(Map.Entry<Integer, String> entry:map.entrySet()){ int key = entry.getKey(); String value = entry.getValue(); System.out.println("key:"+key+",value:"+value); } //只能遍歷出value的值,沒法遍歷key的值 for(String strVal:map.values()){ System.out.println("value:"+strVal); } //廣泛使用,二次取值 經過Map.KeySet遍歷key和value for(int keys:map.keySet()){ System.out.println("key:"+keys+",value"+map.get(keys)); } } }

 

 參考:https://www.cnblogs.com/xiohao/p/4309462.html

相關文章
相關標籤/搜索