4

ArrayListもSetも使用できないようです。

  • Set<>-セットを使用して重複を回避できますが、シャッフルオプションはありません//Collections.shuffle(List<?> list)

  • ArrayList<>-シャッフルを使用してリストをランダム化できますが、重複は許可されます。

重複を避けるために、を使用してこれを(またはその逆)にSet変換することができます。ArrayListまたは、セットをループしてアイテムをランダム化します。しかし、私はもっと効率的なものを探しています。

4

5 に答える 5

3

との2つの別個のコレクションを維持し、に存在するアイテムの挿入を拒否することがArrayListできHashSetますHashSet

カプセル化に関心がある場合は、を実装するメタオブジェクトで2つのコレクションをラップし、の一般的な契約で規定されていない場合でもList、重複する要素の挿入が拒否されることを注意深く文書化します。List

このソリューションのコストについて言えば、時間の観点から、プレーンと比較した場合、コストは絶対に無視できると思います。コストを償却ArrayListしたO(1)のほとんどの操作、つまりルックアップと挿入です。HashSet一方、メモリ使用量は2倍になります(HashSet負荷率によってはそれ以上になります)。

于 2013-02-15T10:58:33.597 に答える
1

私の知る限り、セットは注文されていないので、セットのアイテムをシャッフルすることはできません。リストから重複を削除するために私はこれを見つけました:ArrayListから繰り返される要素を削除するにはどうすればよいですか?

于 2013-02-15T10:57:35.027 に答える
0

TreeSetなどの「順序集合」を実際に使用できます。ランダムな順序を取得するには、実際のアイテムではなく、ランダムな重みを持つラッパーを挿入し、対応するコンパレータを使用します。ただし、再シャッフルするには、すべてのラッパーの重みを更新する必要があります。

于 2013-02-15T11:04:10.800 に答える
0

最小限のコードと最大限のエレガンスで、次のようなことができます。

 public void testFoo() {
    Set<Integer> s = new TreeSet<Integer>();

    s.add(2);
    s.add(1);
    s.add(3);

    Collections.shuffle(Arrays.asList(s.toArray()));
}

しかし、これはあまり効果的ではありません。配列とハッシュ関数を使用して、要素を配列の目的の場所に配置し、配置する前に要素がすでに存在することを確認できます。これはO(n)時間で機能します。非常に優れていますが、もう少しコードを追加し、ハッシュ関数に注意を払う必要があります。

于 2013-02-15T10:59:21.240 に答える
0
  • Mapを使用して重複を回避してから、Map.entrySet()を使用してArrayListをシャッフルできます。
于 2013-02-15T11:01:19.290 に答える