程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> JAVA編程 >> 關於JAVA >> 多用多學之Java中的Set,List,Map詳解

多用多學之Java中的Set,List,Map詳解

編輯:關於JAVA

多用多學之Java中的Set,List,Map詳解。本站提示廣大學習愛好者:(多用多學之Java中的Set,List,Map詳解)文章只能為提供參考,不一定能成為您想要的結果。以下是多用多學之Java中的Set,List,Map詳解正文


很長時光以來一向代碼頂用的比擬多的數據列表重要是List,並且都是ArrayList,感到有這個玩意就夠了。ArrayList是用於完成靜態數組的包裝對象類,如許寫代碼的時刻便可以拉進拉出,迭代遍歷,蠻便利的。

也不曉得從甚麼時刻開端漸漸的代碼中就常常會湧現HashMap和HashSet之類的對象類。應當說HashMap比擬多一些,並且照樣面試經典題,日常平凡也會多看看。開端用的時刻簡略懂得就是個鍵值對應表,應用鍵來找數據比擬便利。隨後深刻懂得後發明

這玩意還有點小奧妙,特殊是新版本的JDK對HashMap的改成樹後,代碼都有點小龐雜咯。

Set開端用的較少,只是有意中在一個代碼中發明一個TreeSet,發明這個類可以自帶順遂,感到蠻有點意思,才漸漸的發明這也是個好對象啊。

代碼寫的多了就感到到基本的主要性,所以在此寫一篇小文簡略的整頓一下對聚集的一些常識。

好了,簡略的整頓一下:

•List:等於列表,支撐數組、鏈表的功效,普通都是線性的
•Map:等於映照表,存儲的是鍵與值的對應關系
•Set:等於聚集的意思,重要是用於排重數據及排序

先來看看List

List是用於寄存線性數據的一種窗口,好比:用於數組的ArrayList和用於鏈表的LinkedList。

ArrayList

這是一個數組列表,不外供給了主動擴容的功效,完成List接口,內部操作都是經由過程接口聲名的辦法拜訪,如許即平安又便利。

ArrayList的症結就是主動擴容,在對象初始化時可以設定初始容量,也能夠按默許的容量。假如對數組年夜小沒有特殊明白可以不指定初始年夜小,假如明白的話可以指定一個年夜小,如許削減靜態擴容時發生的卡頓。說到這就要說一下擴容是怎樣完成的了,看上面的代碼:

private void grow(int minCapacity) {

    // overflow-conscious code

    int oldCapacity = elementData.length;

    int newCapacity = oldCapacity + (oldCapacity >> 1);

    if (newCapacity - minCapacity < 0)

      newCapacity = minCapacity;

    if (newCapacity - MAX_ARRAY_SIZE > 0)

      newCapacity = hugeCapacity(minCapacity);

    // minCapacity is usually close to size, so this is a win:

    elementData = Arrays.copyOf(elementData, newCapacity);

  }

grow是在ArrayList在添加元素或許一些輕易檢討時會觸發的一個辦法。重要進程:

1、獲得數組的長度,並對其停止右移,如許就相當於oldCapacity/2,獲得新的長度

2、假如這個長度小於最小容量那末直接就用最小輕易

3、假如年夜於了最年夜輕易則取一個最年夜值,這裡會挪用一個hugeCapacity辦法,重要是比擬minCapacity與MAX_ARRAY_SIZE的,假如minCapacity年夜於MAX_ARRAY_SIZE則取Integer.MAX_VALUE,不然就取MAX_ARRAY_SIZE,成心思的是MAX_ARRAY_SIZE取的是Integer.MAX_VALUE - 8;其實不曉得如許做的意義是甚麼

4、最初就是挪用一個復制辦法將現稀有復制到一個新的數組中。

由於有這個復制進程,假如數組比擬年夜,那末總是觸發擴容固然就會湧現卡頓的情形。所以假如一開端就曉得最年夜值並且很輕易增加到這個值,那末開端初始化時就指定年夜小會有必定的感化。

LinkedList

這是針對鏈表的對象類,鏈表的優良是添加刪除啥的比擬快,然則查找會慢一些。

至於代碼似乎也沒甚麼特殊的,就是一串指針鏈接起來,固然Java中就應用對象來取代,樹立一個Node的對象,Node自己指向了前一個Node和後一個Node,這就是鏈表的構造:

 private static class Node<E> {

    E item;

    Node<E> next;

    Node<E> prev;

 

    Node(Node<E> prev, E element, Node<E> next) {

      this.item = element;

      this.next = next;

      this.prev = prev;

    }

  }

然後用兩個Node指向頭和尾就完成了,上面的代碼:

/**

   * Pointer to first node.

   * Invariant: (first == null && last == null) ||

   *      (first.prev == null && first.item != null)

   */

  transient Node<E> first;

 

  /**

   * Pointer to last node.

   * Invariant: (first == null && last == null) ||

   *      (last.next == null && last.item != null)

   */

  transient Node<E> last;

看一個add操作:

/**

   * Links e as last element.

   */

  void linkLast(E e) {

    final Node<E> l = last;

    final Node<E> newNode = new Node<>(l, e, null);

    last = newNode;

    if (l == null)

      first = newNode;

    else

      l.next = newNode;

    size++;

    modCount++;

  }

過往就是:

1、獲得到最初的Node並放在l中

2、創立一個新的Node,將數據取到這個Node中,創立進程會將新Node的prev指向l,如許就接上了鏈

3、然後將last指向這個新Node

4、然斷定l能否null,假如是null解釋是空鏈表,新node就是第一個元素,如許first也要指向newNode

5、假如不為空則將l的next指向newNode

6、累加計數器

刪除操作也是這類Node的前後Node指向挪動操作。

再來看看Map

Map是鍵與值做一個映照表的運用,重要的完成類:HashMap,HashTable,TreeMap

HashMap和HashTable

應用hash算法停止鍵值映照的就是HashMap啦,HashTable是帶有同步的線程平安的類,它們兩重要的差別就是這個。道理也相似,都是經由過程桶+鏈來組合完成。桶是用來存Key的,而因為Hash碰撞的緣由值須要用一個鏈表來存儲。

•桶的意義在於高效,經由過程Hash盤算可以一步定位
•鏈表的意義在於存取反復hash的數據

詳細的道理之前寫過一篇《進修筆記:Hashtable和HashMap》

只不外看JDK1.8的HashMap換了存儲構造,采取紅黑樹的構造,如許能夠是處理鏈表查找效力成績吧?詳細沒有細研討。

TreeMap

看過TreeMap的代碼後發明照樣應用的樹構造,紅黑樹。因為紅黑樹是有序的,所以天然帶排序功效。固然也可經由過程comparator來指定比擬辦法來完成特定的排序。

由於采取了樹構造存儲那末添加和刪除數據時會費事一些,看一下put的代碼:

public V put(K key, V value) {

    Entry<K,V> t = root;

    if (t == null) {

      compare(key, key); // type (and possibly null) check

 

      root = new Entry<>(key, value, null);

      size = 1;

      modCount++;

      return null;

    }

    int cmp;

    Entry<K,V> parent;

    // split comparator and comparable paths

    Comparator<? super K> cpr = comparator;

    if (cpr != null) {

      do {

        parent = t;

        cmp = cpr.compare(key, t.key);

        if (cmp < 0)

          t = t.left;

        else if (cmp > 0)

          t = t.right;

        else

          return t.setValue(value);

      } while (t != null);

    }

    else {

      if (key == null)

        throw new NullPointerException();

      @SuppressWarnings("unchecked")

        Comparable<? super K> k = (Comparable<? super K>) key;

      do {

        parent = t;

        cmp = k.compareTo(t.key);

        if (cmp < 0)

          t = t.left;

        else if (cmp > 0)

          t = t.right;

        else

          return t.setValue(value);

      } while (t != null);

    }

    Entry<K,V> e = new Entry<>(key, value, parent);

    if (cmp < 0)

      parent.left = e;

    else

      parent.right = e;

    fixAfterInsertion(e);

    size++;

    modCount++;

    return null;

  }

1、先是檢討根節點能否存在,不存在解釋是第一條數據,直接作為樹的根

2、斷定能否存在比擬器,假如存在則應用比擬器停止查找數據的寄存地位,假如比擬器前往成果小於0取左,年夜於0取右,不然直代替換以後節點的值

3、假如不存在比擬器則key直接與節點的key比擬,比擬和後面辦法一樣

4、接上去就是在找到的parent上創立一個子節點,並放入左或許右子節點中

5、fixAfterInsertion是對節點停止著色

6、累加器處置

在remove操作時也會有點費事,除刪除數據外,還要從新均衡一下紅黑樹。

別的,TreeMap完成了NavigableMap<K,V>接口,所以也供給了對數據聚集的一些前往操作。

最初看看Set

Set重要是兩類運用:HashSet和TreeSet。

HashSet

字面意思很明白,應用了Hash的聚集。這類聚集的特色就是應用Hash算法存數據,所以數據不反復,存取都絕對較快。怎樣做到的呢?

public boolean add(E e) {

    return map.put(e, PRESENT)==null;

  }

本來是存在一個map對象中,再看map是個啥?

private transient HashMap<E,Object> map;

是個HashMap,懂得HashMap的就明確,如許的數據是不會反復的。由於存入時是鼗對象自己作為Key來存的,所以在HashMap中只會存在一份。

懂得了這點其他的器械就異常明確了。

TreeSet

這個聚集是用於對聚集停止排序的,也就是除帶有排重的才能外,還可以自帶排序功效。只不外看了TreeSet的代碼發明,其就是在TreeMap的基本完成的。更精確的說應當是NavigableMap的派生類。默許不指定map情形下TreeSet是以TreeMap為基本的。

public TreeSet() {

    this(new TreeMap<E,Object>());

  }

所以,這裡能夠更存眷的是TreeSet是若何排重呢?看一下add的辦法吧:

public boolean add(E e) {

    return m.put(e, PRESENT)==null;

  }

和HashSet有點相似,都是基於Map的特征來完成排重。確切簡略並且有用。

以上就是小編為年夜家帶來的多用多學之Java中的Set,List,Map詳解全體內容了,願望年夜家多多支撐~

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved