JREの<T>にA LinkedHashSetの<T>のArrayListを変換するために使用されるものアルゴリズム

アミットUpadhyay:

私が取得したいlistからユニークな要素のlist重複要素とリストで発生した要素の順序では維持されるべきです。

これを達成するために、私のようなアルゴリズムを記述することができ:

private ArrayList<T> getUnique(ArrayList<T> list)
{
    // maintain a hashmap of numbers and a uniqueList to be returned(ArrayList<T>)
    // Add element in result list and the hashmap if the element isn't already present in the hashmap, else just add in the hashmap

    HashMap<T, Boolean> map = new HashMap<>();
    ArrayList<T> uniqueList = new ArrayList<>();

    for (T t: list)
    {
        if (map.get(t) == null)
        {
            // t wasn't present so, adding them in map as well as in the list
            map.put(t, true);
            uniqueList.add(t);
        }
    }
    return uniqueList;
}

このアルゴリズムはかかるO(n)との時間をO(n)(HashMapのための)余分なスペース。

それとも単に、私は以下の構文を使用している可能性が:

Set<T> set = new LinkedHashSet<>(list);

Javaで上記の構文を取得するために使用されているsetからユニークな要素のをlistと同じ要素の出現順序とlistそして、このセットがリストに変換します。ArrayList<T> uniqueList = new ArrayList<>(set);

私はここで、複雑でもあり、時間を想定していますO(n)私は、アルゴリズムのJavaがそれを使用するかを知りたかったです。

私はクラスがLinkedHashSetの命名された参照ので、私は、彼らはいくつか使用しているかもしれないと思ったLinkedListので、私はソースコードに見て、これを達成するための概念を、これらのものを見つけました:

  1. ではLinkedHashSet.java、コンストラクタのルックスが好き:

143: public LinkedHashSet(Collection<? extends T> c) 144: { 145: super(c); 146: } ここではソースです。

  1. だから、私はつまり、親クラスのコンストラクタを見てHashSet、私が見つかりました:

public HashSet(Collection<? extends E> c) { map = new HashMap<>(Math.max((int) (c.size()/.75f) + 1, 16)); addAll(c); }

  1. 次に、私が検索addAll方法、私はそれを発見したAbstractCollection(の祖父母であるクラスHashSetのクラス)、関数の定義は次のとおりです。

public boolean addAll(Collection<? extends E> c) { boolean modified = false; for (E e : c) if (add(e)) modified = true; return modified; }

これは、呼び出し元であるaddようなものです:

public boolean add(E e) { throw new UnsupportedOperationException(); } ここに

私はこれを理解できませんでした。彼らは、このタスクに使用何をするアルゴリズム?

Smbchde:

誰かのために全体的な話を探して

ソースコード上のベースLinkedHashSetのHashSetののLinkedHashMap構築するときにLinkedHashSet延びているHashSet他のコレクション(LinkedHashSet.javaライン143)と、

public LinkedHashSet(Collection<? extends T> c)  
{  
  super(c);  
}

これは(HashSet.javaライン136)を呼び出します:

public HashSet(Collection<? extends T> c)
{
  this(Math.max(2 * c.size(), HashMap.DEFAULT_CAPACITY));
  addAll(c);
}

そして次に(HashSet.javaライン122)を呼び出します。

public HashSet(int initialCapacity, float loadFactor)
{
  map = init(initialCapacity, loadFactor);
}

ためinitの方法がでオーバーライドされますLinkedHashSet

HashMap<T, String> init(int capacity, float load)
{
 return new LinkedHashMap<T, String>(capacity, load);
}

バッキングはmapありますLinkedHashMap

Javaのドキュメントによると、のLinkedHashMap

このクラスは、オプションのマップオペレーションをすべて提供し、null要素を許可します。HashMapのように、それが提供する一定時間のパフォーマンスバケットのうち適切にハッシュ関数ばらつく要素を仮定し、基本的な操作のために(ADDが、含まれており、削除します)。かかわらず、その容量の、のLinkedHashMapのコレクションビュー上で反復マップのサイズに比例した時間が必要です:パフォーマンスは、おそらくのHashMapの、一つの例外を除いて、リンクリストを維持することの追加費用によるものであることわずかに下回ることがあります。HashMapのオーバー反復がその容量に時間比例を必要とする、より高価である可能性が高いです。

そして、addの方法HashSetIS

public boolean add(E e) {
   return map.put(e, PRESENT)==null;
}

従って平均時間複雑度は、建設のためのO(N)です。アルゴリズムのために、私はあなたが詳細についてのLinkedHashMapのコードを読むことができると思います。また、読書はどのようにHashMapの実装からのLinkedHashMap異なるの内部実装のですか?LinkedHashSetの対HashSetの

おすすめ

転載: http://43.154.161.224:23101/article/api/json?id=222888&siteId=1