Синхронная перестановка элементов в двух ArrayList Java

Пройдите тест, узнайте какой профессии подходите

Я предпочитаю
0%
Работать самостоятельно и не зависеть от других
Работать в команде и рассчитывать на помощь коллег
Организовывать и контролировать процесс работы

Быстрый ответ

Java
Скопировать код
import java.util.Collections;
import java.util.List;
import java.util.Random;

List<String> list1 = // ...;
List<Integer> list2 = // ...;
long seed = System.nanoTime();
Collections.shuffle(list1, new Random(seed));
Collections.shuffle(list2, new Random(seed));

Для равномерного перемешивания двух списков достаточно сгенерировать общий seed и использовать его при создании экземпляра класса Random для каждого из списков.

Кинга Идем в IT: пошаговый план для смены профессии

Углубляемся: От основ к мелочам

Если вам необходимо освоить тонкости случайного распределения списков, при этом сохраняя связь между элементами, стоит обратить внимание на методы, позволяющие сохранять целостность данных в процессе перемешивания.

Сопоставление связанных элементов: Встречаем инкапсуляцию

Когда требуется создать связь между элементами, например, между именами файлов и изображениями или игроками и их баллами, оптимальным решением будет инкапсуляция данных в одном классе:

Java
Скопировать код
class DataPair {
    String file;
    String image;
    // Конструкторы, геттеры, сеттеры...
}

List<DataPair> dataList = new ArrayList<>();
...
long seed = System.nanoTime();
Collections.shuffle(dataList, new Random(seed));

Применим алгоритм Фишера — Йетса: Когда кружит в танце

Для массивов примитивных типов или когда нужен особенный контроль над процессом, можно применить алгоритм Фишера — Йетса:

Java
Скопировать код
void shuffleArray(Object[] array, long seed) {
    Random rnd = new Random(seed);
    for (int i = array.length – 1; i > 0; i--) {
        int index = rnd.nextInt(i + 1);
        Object a = array[index];
        array[index] = array[i];
        array[i] = a;
    }
}

Контроль корректности данных после перемешивания: Бдительность в деле

Необходимо обязательно проверять данные после их перемешивания:

Java
Скопировать код
assert list1.size() == list2.size();
for (int i = 0; i < list1.size(); i++) {
   assert list1.get(i).relatedId == list2.get(i).id;
}

Приветствуем Java Records: Минимализм в действии

Java Records (доступны, начиная с Java 16), облегчает работу со связанными данными:

Java
Скопировать код
record DataPair(String file, String image){}
...
List<DataPair> dataList = new ArrayList<>();
...

Визуализация

Придставим перед собой две колоды карт:

Markdown
Скопировать код
Колода A (ArrayList1): [Туз ♠️, Король ♣️, Дама ♥️]
Колода B (ArrayList2): [Яблоко 🍎, Банан 🍌, Вишня 🍒]

Используя общий идентификатор (seed) для перемешивания:

Java
Скопировать код
Collections.shuffle(Колода A, new Random(seed));
Collections.shuffle(Колода B, new Random(seed));

Колоды равномерно перемешаются:

Markdown
Скопировать код
Перемешанная Колода A: [Дама ♥️, Туз ♠️, Король ♣️]
Перемешанная Колода B: [Вишня 🍒, Яблоко 🍎, Банан 🍌]

Таким образом, каждому элементу из первой колоды будет соответствовать элемент из второй колоды.

Применение карт (maps): Объемные датасеты, широкие возможности

Для обработки больших объемов данных с сохранением взаимосвязей применяйте карты (maps):

Java
Скопировать код
Map<Integer, DataPair> map = new HashMap<>();
...
List<Integer> keys = new ArrayList<>(map.keySet());
Collections.shuffle(keys, new Random(seed));

Проверка данных: Никто не застрахован от ошибок

После перемешивания обязательно убедитесь, что взаимосвязи между данными сохранены:

Java
Скопировать код
for (int key : keys) {
    DataPair pair = map.get(key);
    // Проверка корректности связи
}

Полезные материалы

  1. Collections (Java Platform SE 8 )
  2. Random (Java Platform SE 8 )
  3. ArrayList в Java – GeeksforGeeks
  4. java – Случайное перетасовывание массива – Stack Overflow
  5. Вайлдкарды (Учебник по Java™: Изучение языка Java, общая информация по параметризованным типам)