0

調べLinkedHashSetHashSet コレクションしています。

私は小さなプログラムを書きました:

public class LHSTest {
    public static void main(String[] args){
        output(test(new LinkedHashSet()));
        System.out.println("=========");
        output(test(new HashSet()));

    }
    public static HashSet<MyClass> test(HashSet hashSet){
        hashSet.add(new MyClass(1));
        hashSet.add(new MyClass(2));
        hashSet.add(new MyClass(3));
        hashSet.add(new MyClass(4));
        hashSet.add(new MyClass(5));
         return  hashSet;
    }
    public static void output(HashSet hashSet){
        for(Iterator iterator = hashSet.iterator();iterator.hasNext();){
            System.out.println(iterator.next());
        }
    }
}

class MyClass{
    int a;
    MyClass(int a){
        this.a =a;
    }
    public int hashCode(){
        return 15-a;
    }
    public String toString()   {
        return  a+"";
    }
}

出力:

1
2
3
4
5
=========
5
4
3
2
1

この動作を見て、コレクションのソース コードの調査を開始しました。

LinkedHashSet と HashSet の両方が使用されていることに気付きました

共通toString() 認識 - からAbstractCollection

iterator()から一般的なHashSet

LinkedHashSet私のコードの出力とコード内の出力が異なる理由は何HashSetですか?

Ivan Babaninの回答後に更新

さまざまなコンストラクターの場合LinkedHashSetHashSet呼び出し:

のために LinkedHashSet-

HashSet(int initialCapacity, float loadFactor, boolean dummy) {
    map = new LinkedHashMap<E,Object>(initialCapacity, loadFactor);
}

のために HashSet-

 public HashSet() {
    map = new HashMap<E,Object>();
 }

HashMapと -の両方のイテレータLinkedHasMap(からHashSet)

public Iterator<E> iterator() {
    return map.keySet().iterator();
 }

調査keySet()方法:

HashMap:

public Set<K> keySet() {
        Set<K> ks = keySet;
        return (ks != null ? ks : (keySet = new KeySet()));
}

LinkedHashMapkeySetメソッドの特別な実現はできず、実現を使用しHashMapます。

map.keySet().iterator() is:

public class HashMap<K,V>    extends AbstractMap<K,V>    implements Map<K,V>, Cloneable,      Serializable{
     ...
    private final class EntrySet extends AbstractSet<Map.Entry<K,V>> {
          public Iterator<Map.Entry<K,V>> iterator() {
               return newEntryIterator();
          }
            ...
    }
     ...
}

map.keySet()同じ型を返すためHashMap、同じメソッドLinkedHashMapを呼び出します。newEntryIterator()

間違った発言ですか?

EJP更新用

私はに移動しHashSet#iteratorます:

ここに画像の説明を入力

ここに画像の説明を入力

ここに画像の説明を入力

4

2 に答える 2

0

あなたはあまり深く掘り下げていません。

  • HashSet.iterator()戻り値map.keySet().iterator()
  • map.keySet()を返しますHashMap.KeySet
  • HashMap.KeySet.iterator()通話[HashMap.this.]newKeyIterator()
  • LinkedHashMapオーバーライドnewKeyIterator().
于 2014-04-18T07:38:01.193 に答える
0

LinkedHashSetは挿入順序を維持しますが、HashSetは維持しません。LinkedHashSetの javadocからの引用:

Set インターフェイスのハッシュ テーブルとリンク リストの実装。反復順序は予測可能です。この実装が HashSet と異なる点は、そのすべてのエントリを実行する二重リンク リストを維持することです。このリンクされたリストは、要素がセットに挿入された順序 (挿入順序) である反復順序を定義します。

LinkedHashSetの任意のコンストラクターは、 HashSetのスーパー コンストラクターを呼び出します。

HashSet(int initialCapacity, float loadFactor, boolean dummy) {
    map = new LinkedHashMap<>(initialCapacity, loadFactor);
}

また、LinkedHashMapMapインターフェースのハッシュ テーブルとリンク リストの実装であり、反復順序は予測可能です。

于 2014-04-18T05:54:58.683 に答える