私が取得したい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
ので、私はソースコードに見て、これを達成するための概念を、これらのものを見つけました:
- では
LinkedHashSet.java
、コンストラクタのルックスが好き:
143: public LinkedHashSet(Collection<? extends T> c) 144: { 145: super(c); 146: }
ここではソースです。
- だから、私はつまり、親クラスのコンストラクタを見て
HashSet
、私が見つかりました:
public HashSet(Collection<? extends E> c) { map = new HashMap<>(Math.max((int) (c.size()/.75f) + 1, 16)); addAll(c); }
- 次に、私が検索
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(); }
ここに。
私はこれを理解できませんでした。彼らは、このタスクに使用何をするアルゴリズム?
誰かのために全体的な話を探して
ソースコード上のベース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
の方法HashSet
IS
public boolean add(E e) {
return map.put(e, PRESENT)==null;
}
従って平均時間複雑度は、建設のためのO(N)です。アルゴリズムのために、私はあなたが詳細についてのLinkedHashMapのコードを読むことができると思います。また、読書はどのようにHashMapの実装からのLinkedHashMap異なるの内部実装のですか?、LinkedHashSetの対HashSetの