web-dev-qa-db-ja.com

2つのArrayListsを同じ方法でランダム化する方法

2つの配列リストfilelistimgListが互いに関連しています。 "e1.jpg"に関連する "H1.txt"。 imgListのランダム化に従ってfileListのリストを自動的にランダム化する方法Excelと同じように、特定の列を並べ替えると、他の列も自動的に続きます。

String [] file = {"H1.txt","H2.txt","H3.txt","M4.txt","M5.txt","M6.txt"};
ArrayList<String> fileList = new ArrayList<String>(Arrays.asList(file));

String [] img = {"e1.jpg","e2.jpg","e3.jpg","e4.jpg","e5.jpg","e6.jpg"};
ArrayList<String> imgList = new ArrayList<String>(Arrays.asList(img));

//randomized files
Collections.shuffle(fileList);

ランダム化後の出力例:

fileList = {"M4.txt","M6.txt","H3.txt","M5.txt","H2.txt","H1.txt"};

意図した出力:

 imgList = {"e4.jpg","e6.jpg","e3.jpg","e5.jpg","e2.jpg","e1.jpg"};
251
Jessy

Collections.shuffle() を2回使用し、2つのRandomオブジェクトを同じシードで初期化します。

long seed = System.nanoTime();
Collections.shuffle(fileList, new Random(seed));
Collections.shuffle(imgList, new Random(seed));

同じシードを持つ2つのRandomオブジェクトを使用すると、両方のリストがまったく同じ方法でシャッフルされます。これにより、2つの別々のコレクションが可能になります。

575

それらを別のクラスにラップして、単一の配列またはそれらのオブジェクトのListになることができるようにします。

public class Data {
    private String txtFileName;
    private String imgFileName;

    // Add/generate c'tor, getter/setter, equals, hashCode and other boilerplate.
}

使用例

List<Data> list = new ArrayList<Data>();
list.add(new Data("H1.txt", "e1.jpg"));
list.add(new Data("H2.txt", "e2.jpg"));
// ...

Collections.shuffle(list);
119
BalusC

最も簡単な方法は、2つの値を画像とファイルの両方を持つ型にカプセル化することです。それからというArrayList構築してシャッフルします。

これによりカプセル化も改善され、常にイメージと同じ数のファイルが自動的に保存されるようになります。

あなたが本当にその考えを好まない場合の代替策は、自分でシャッフルコードを書くことです(変更された例がたくさんあります 私は疑うスタックオーバーフロー上のいくつかを含め、Javaのフィッシャーイエーツシャッフル 、)とちょうど同じ時に両方のリストで動作します。しかし、私は「カプセル化の改善」アプローチを採用することを強くお勧めします。

22
Jon Skeet

あなたは地図でこれをすることができます:

Map<String, String> fileToImg:
List<String> fileList = new ArrayList(fileToImg.keySet());
Collections.shuffle(fileList);
for(String item: fileList) {
    fileToImf.get(item);
}

これは画像をランダムな順序で繰り返します。

9
jjnguy

これはシャッフル法を使って行うことができます。

private List<Integer> getJumbledList() {
     List<Integer> myArrayList2 = new ArrayList<Integer>();
        myArrayList2.add(8);
        myArrayList2.add(4);
        myArrayList2.add(9);
        Collections.shuffle(myArrayList2);
        return myArrayList2;
5
Rohit Goyal

2つの文字列の配列を持つ代わりに、2つの文字列を含む1つのカスタムクラスの配列を持ってください。

4
EboMike

0から5までの数字を含む配列を作成してそれらをシャッフルすることができます。次に、結果を "oldIndex - > newIndex"のマッピングとして使用し、このマッピングを元の両方の配列に適用します。

3
Mark Byers

あなたが「自動的に」と言っている意味が完全にはわからない - 両方のオブジェクトを保持するコンテナオブジェクトを作ることができる:

パブリッククラスFileImageHolder {String fileName;}文字列imageName。 // TODO:ここにものを挿入します}

そしてそれを配列リストに入れ、その配列リストをランダム化します。

それ以外の場合は、各要素が一方のリストのどこに移動したかを追跡し、もう一方のリストに移動する必要があります。

2
aperkins

それらがシャッフルされた後に要素の古いインデックスを取得する方法がない限り、私はそれを2つの方法のうちの1つをするでしょう:

A)もう一つのリストmulti_shuffler = [0、1、2、...、file.size()]を作り、それをシャッフルします。それをループして、シャッフルされたファイル/画像リストの順番を取得します。

ArrayList newFileList = new ArrayList(); ArrayList newImgList = new ArrayList(); (i = 0; iの場合

またはB)StringWrapperクラスを作成してファイル/画像の名前を保持し、すでに持っている2つのリストを1つにまとめます。

2
ajwood