Добавление нескольких «случайно сгенерированных» объектов в ArrayList приводит к добавлению одного и того же объекта несколько раз

#java #arraylist #shuffle #random

#java #arraylist #перемешивание #Случайный

Вопрос:

У меня есть класс, Ttp который имеет ArrayList<City> загруженный из файла. В конструкторе Ttp я случайным образом перетасовываю список, прочитанный из файла, и присваиваю его объекту.

 public class Ttp {
    private ArrayList<City> cities;

    public Ttp() {
        cities = Utils.shuffleArray(Loader.getCities());
    }
}
  

Таким образом, я получаю 10 объектов с красиво перетасованными массивами:

 public static void main(String args[]) {
    Loader.readFile("easy_0.ttp");
    for(int i=0; i<10; i  ){
        System.out.println(new Ttp());
    }
}
  

Но в этом сценарии, когда я пытаюсь создать, ArrayList<Ttp> я получаю коллекцию, полную одинаковых объектов (экземпляров Ttp с одинаковыми массивами городов)

 public static void main(String args[]) {
    Loader.readFile("easy_0.ttp");
    ArrayList<Ttp> arrayList = new ArrayList<>();
    for(int i=0; i<10; i  ){
        arrayList.add(new Ttp());
    }
    arrayList.forEach(System.out::println);
}
  

Функция перемешивания:

 public static <T> ArrayList<T> shuffleArray(ArrayList<T> arrayList) {
    if (arrayList != null amp;amp; arrayList.size() > 0) {
        int numberOfRolls = Random.getGenerator().nextInt((arrayList.size() - arrayList.size() / 3)   1)   arrayList.size() / 3;
        int indexA;
        int indexB;
        T objectA;
        for (int i = 0; i < numberOfRolls; i  ) {
            indexA = Random.getGenerator().nextInt(arrayList.size());
            indexB = Random.getGenerator().nextInt(arrayList.size());
            objectA = arrayList.get(indexA);
            arrayList.set(indexA, arrayList.get(indexB));
            arrayList.set(indexB, objectA);
        }
    }
    return arrayList;
}
  

Для выбора случайных индексов в функции shuffle я использую java.util.Random :

 public class Random {
    private static final java.util.Random generator = new java.util.Random();

    public static java.util.Random getGenerator() {
        return generator;
    }
}
  

Ответ №1:

Если Loader.getCities() каждый раз возвращается один и тот же список, это означает, что shuffleArray() один и тот же список перетасовывается снова и снова, и у каждого Ttp.cities есть ссылка на один и тот же единый список.

Исправление заключается в создании копии где-нибудь. Это может быть в getCities() , это может быть в shuffleArray() или это может быть в Ttp конструкторе:

 cities = Utils.shuffleArray(new ArrayList<>(Loader.getCities()));