Как рандомизировать два ArrayList таким же образом? - PullRequest
251 голосов
/ 19 ноября 2010

У меня есть два архива filelist и imgList, которые связаны друг с другом, например, "H1.txt", связанный с "e1.jpg".Как автоматически рандомизировать список 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"};

Ответы [ 9 ]

575 голосов
/ 19 ноября 2010

Используйте Collections.shuffle() дважды, с двумя Random объектами, инициализированными одним и тем же семенем:

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

Использование двух Random объектов с одинаковым начальным числом гарантирует, что оба списка будут перетасовываться одинаково. Это позволяет две отдельные коллекции.

119 голосов
/ 19 ноября 2010

Оберните их в другой класс, чтобы вы могли получить один массив или 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);
22 голосов
/ 19 ноября 2010

Самый простой подход состоит в том, чтобы объединить два значения вместе в тип, который имеет и изображение, и файл. Затем создайте ArrayList из , который , и перетасуйте его.

Это также улучшает инкапсуляцию, предоставляя свойство, при котором у вас всегда будет такое же количество файлов, что и у изображений.

В качестве альтернативы, если вам действительно не понравится эта идея, было бы написать код в случайном порядке (существует множество примеров измененного преобразования Фишера-Йейтса в Java, я подозреваю, что в том числе несколько в переполнении стека) и работаю одновременно с обоими списками. Но я настоятельно рекомендую использовать подход «улучшения инкапсуляции».

9 голосов
/ 19 ноября 2010

Вы можете сделать это с картами:

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

Это будет перебирать изображения в случайном порядке.

5 голосов
/ 23 мая 2014

Это можно сделать, используя метод случайного воспроизведения:

private List<Integer> getJumbledList() {
     List<Integer> myArrayList2 = new ArrayList<Integer>();
        myArrayList2.add(8);
        myArrayList2.add(4);
        myArrayList2.add(9);
        Collections.shuffle(myArrayList2);
        return myArrayList2;
4 голосов
/ 19 ноября 2010

Вместо двух массивов строк, есть один массив пользовательского класса, который содержит две строки.

3 голосов
/ 19 ноября 2010

Вы можете создать массив, содержащий числа от 0 до 5 и перемешать их.Затем используйте результат как отображение «oldIndex -> newIndex» и примените это отображение к обоим исходным массивам.

2 голосов
/ 19 ноября 2010

Если нет способа извлечь старый индекс элементов после их перетасовки, я бы сделал это одним из двух способов:

A) Создать другой список multi_shuffler = [0, 1,2, ..., file.size ()] и перемешайте его.Зациклите его, чтобы получить порядок для ваших перемешанных списков файлов / изображений.

ArrayList newFileList = new ArrayList ();ArrayList newImgList = new ArrayList ();for (i = 0; i

или B) Создайте класс StringWrapper для хранения имен файлов / изображений и объедините два списка, которые вы уже получили, в один: ArrayList комбинированный список;

2 голосов
/ 19 ноября 2010

Не совсем уверен, что вы подразумеваете под «автоматически» - вы можете создать контейнерный объект, содержащий оба объекта:

открытый класс FileImageHolder { Строка fileName; String imageName; // TODO: вставьте сюда материал }

А затем поместите это в список массивов и рандомизируйте этот список массивов.

В противном случае вам нужно будет отследить, где каждый элемент перемещен в одном списке, а также переместить его в другой.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...