?
?
【JAVA基礎】HashSet、LinkedHashSet、TreeSet使用區別
HashSet:哈希表是通過使用稱為散列法的機制來存儲信息的,元素并沒有以某種特定順序來存放;
LinkedHashSet:以元素插入的順序來維護集合的鏈接表,允許以插入的順序在集合中迭代; ?
TreeSet:提供一個使用樹結構存儲Set接口的實現,對象以升序順序存儲,訪問和遍歷的時間很快。
用例代碼:
package com.test;
import java.util.HashSet;
import java.util.LinkedHashSet;
import java.util.TreeSet;
/**
* @description 幾個set的比較
* HashSet:哈希表是通過使用稱為散列法的機制來存儲信息的,元素并沒有以某種特定順序來存放;
* LinkedHashSet:以元素插入的順序來維護集合的鏈接表,允許以插入的順序在集合中迭代;
* TreeSet:提供一個使用樹結構存儲Set接口的實現,對象以升序順序存儲,訪問和遍歷的時間很快。
* @author Zhou-Jingxian
*
*/
public class SetDemo {
public static void main(String[] args) {
HashSet<String> hs = new HashSet<String>();
hs.add("B");
hs.add("A");
hs.add("D");
hs.add("E");
hs.add("C");
hs.add("F");
System.out.println("HashSet 順序:\n"+hs);
LinkedHashSet<String> lhs = new LinkedHashSet<String>();
lhs.add("B");
lhs.add("A");
lhs.add("D");
lhs.add("E");
lhs.add("C");
lhs.add("F");
System.out.println("LinkedHashSet 順序:\n"+lhs);
TreeSet<String> ts = new TreeSet<String>();
ts.add("B");
ts.add("A");
ts.add("D");
ts.add("E");
ts.add("C");
ts.add("F");
System.out.println("TreeSet 順序:\n"+ts);
}
}
輸出效果:
HashSet 順序:
[D, E, F, A, B, C]
LinkedHashSet 順序:
[B, A, D, E, C, F]
TreeSet 順序:
[A, B, C, D, E, F]
JAVA程序??
?
HashSet的輸出結果分析:
?
基礎分為?hashset的實現,依據的是hashmap,
舉個hashset源碼的小例子:
?
public boolean add(E e) {return map.put(e, PRESENT)==null;}
的基礎。?所以我們分析hashmap的源碼:
?
?
public V put(K key, V value) {if (key == null)return putForNullKey(value);int hash = hash(key.hashCode());int i = indexFor(hash, table.length);for (Entry<K,V> e = table[i]; e != null; e = e.next) {Object k;if (e.hash == hash && ((k = e.key) == key || key.equals(k))) {V oldValue = e.value;e.value = value;e.recordAccess(this);return oldValue;}}modCount++;addEntry(hash, key, value, i);return null;}
java基礎編程題,?最為重要的就是:hash的生成算法和indexfor確定的table[i]的下標:
?
?
static int hash(int h) {// This function ensures that hashCodes that differ only by// constant multiples at each bit position have a bounded// number of collisions (approximately 8 at default load factor).h ^= (h >>> 20) ^ (h >>> 12);return h ^ (h >>> 7) ^ (h >>> 4);}/*** Returns index for hash code h.*/static int indexFor(int h, int length) {return h & (length-1);}
JAVA,?這樣,就解釋了為什么hashset的輸出如此不同,它是根據hash值的生成策略來存儲在散列表中的。
?
?
java從入門到精通、hashmap的源碼,是根據transient Entry[] table;以及生成entry內部類,來實現散列表的。
當然,我們在做應用時,也可以使用linkedList[],來實現散列表。
代碼如下:
hashset treeset區別,?
public class HashTest {static final int tablesize = 13;LinkedList<Integer>[] listTable;String[] s = new String[12];public void load(Iterator<Integer> it) {listTable = (LinkedList<Integer>[])new LinkedList[tablesize];while(it.hasNext()) {Integer temp = it.next();int n = hash(temp);if(listTable[n] == null) {listTable[n] = new LinkedList<Integer>();}listTable[n].add(temp);}}private int hash(Integer temp) {
// int v = temp.hashCode(); //比較對象(字符串)時,取得hash值int v = temp; return v % tablesize;}private boolean search(Integer v) {int h = hash(v);LinkedList<Integer> ll = listTable[h];if(ll == null) return false;return ll.contains(v);}public static void main(String[] args) {HashTest ht = new HashTest();List<Integer> li = new ArrayList<Integer>();for(int i=0;i<10000;i++) {li.add(i);}ht.load(li.iterator());int a = 10000;if(ht.search(a)) {System.out.println("yes");} else {System.out.println("no");}
// HashSet<String> hs = new HashSet<String>();
// hs.add("D");
// hs.add("B");
// hs.add("E");
// hs.add("A");
// hs.add("F");
// hs.add("C");
// System.out.println(hs);
//
// System.out.println(17 & 16);}}
?
?
?
?
?
?
?
?
?
?