2016-04-09 5 views
6

コレクションに順序のない繰り返し可能なアイテムが含まれています。 Javaでは、Setは反復不可能です。リストは順序付けされていますが、これは私が望んでいないものです。Javaで順序付けられていない繰り返し可能なCollectionクラスはありますか?

Poolは適切なコレクションですが、Javaには存在しません。 インタフェースは、次のようにする必要があります:

public interface Pool<T> { 
    void set(T item); 
    T get(); 
} 

は、それがどこかに存在しますか?


補完:

私は私が間違って私の考えを表明することを実現しています。

public interface Pool<T> { 
    void put(T item); 
    T randomRemove(); 
} 

私はramdomly毎回アイテムを取得したい、と言うことです:Infactは、私はこのようなインターフェイスを持っていると思います。どうすれば達成できますか?

+1

guavaライブラリを試してみてください。 – piyush121

+1

そのインタフェースは本当にベアボーンです。 'set'と' get'とは何ですか? 'set'は' 'T'を' 'と' 'get''を入れて' 'T''を取り出して返しますか?もしそうなら、順序付けされたコレクションの大部分は、 'add'と' remove'や 'pop'のバリエーションでちょうど良いものをサポートします。 – user2357112

+2

明示的に順序付けられていないコレクションを探している特別な理由はありますか?ほとんど注文されないことは障害のように思える。 – Dolda2000

答えて

4

あなたはList<T>をラップすることにより、あなたのPool<T>機能を実装することができます。 removeは標準List実装にO(N)あるため、特に効率的ではないであろう

public class ListPool<T> implements Pool<T> { 
    private List<T> list = ArrayList<>(); 

    public void put(T t) { 
     list.append(t); 
    } 

    public T randomRemove() { 
     return list.remove(rand.nextInt(list.size())); 
    } 
} 

。しかし、もう少し複雑なArrayListを使用する代わりの実装がありますが、というrandomRemoveがあります。アイデアは、リストを動的配列として扱い、自分自身で "サイズ"を管理することです。このような

何か:

public class FasterPool<T> implements Pool<T> { 
    private List<T> list = new ArrayList<>(); 
    private int size = 0; 
    Random rand = new Random(); 

    public void put(T t) { 
     if (size == list.size()) { 
      list.append(t); 
     } else { 
      list.set(size, t); 
     size++; 
    } 

    public T randomRemove() { 
     int pos = rand.nextInt(size); 
     T result = list.get(pos); 
     if (pos < size - 1) { 
      list.set(pos, list.get(size - 1)); 
     } 
     list.set(size - 1, null); // avoid memory leak ... 
     size--; 
     return result; 
    } 
} 

NB:どちらのバージョンを使用すると、要素を削除しようとすると、プールが空である場合を扱います。どちらもコンパイルもテストもされていません。それに応じてコードを処理してください。

最後に、順序付けられていないコレクション型を使用して実装しようとすると、ランダム要素を効率的に削除することはできません。ヒント:コレクションのイテレータによって返された最初のものを削除することは、実用的なコレクションデータ構造にとって本当にランダムではありません。これは、(仮想の)Bagの実装にも当てはまります。

+2

'FasterPool'スニペットでは、要素をランダムな位置で最後の要素と入れ替え、最後の要素を取り除くと、独自の' size'を管理せずにできませんでしたか? –

+0

偉大な答え。しかし、私は突然、あなたがそれらのいくつかとポジションを交換するとき、常にアイテムごとに一様な確率を持っているという質問を考えましたか? – jinge

+0

@JaeHeonLee - はい。それはうまくいくでしょう。 –

5

あなたはGuava Multiset、より具体的にはHashMultisetを記述しているようです。

Java SEにはこのようなコレクションはありませんが、必要な機能の量に応じて、自分で作成することは簡単です。基本的にはHashMap<T, Integer>などがあります。

ただ、例えば:あなたがランダムな順序付けが必要な場合

class MultiSet<T> { 
    Map<T, Integer> map = new HashMap<>(); 

    void add(T obj) { 
     Integer count = map.get(obj); 
     if (count == null) { 
      map.put(obj, 1); 
     } else { 
      map.put(obj, count + 1); 
     } 
    } 

    void remove(T obj) { 
     Integer count = map.get(obj); 
     if (count != null) { 
      if (count > 1) { 
       map.put(obj, count - 1); 
      } else { 
       map.remove(obj); 
      } 
     } 
    } 

    boolean contains(Object obj) { 
     return map.containsKey(obj); 
    } 
} 
+0

' Multiset'ソースのリンク[[link](https://github.com/google/guava/blob/master/guava/src/com/google/common/) collect/Multiset.java)] –

+0

おそらく 'Iterable 'や 'Collection 'を実装するべきです。そして、Java 8が登場したので、コードをきちんと整理できます。 –

+0

@BoristheSpiderどのようなJava 8は、整頓に役立つことができますか? – jinge

1

一つのアプローチは、コレクトシャッフルする必要があります。

List<String> list = new ArrayList<String>(); 
list.add("A"); 
list.add("B"); 
list.add("C"); 
Collections.shuffle(list); 

System.out.println(list); 

出力:

[B, A, C] 
関連する問題