Почему в Java изменился объект, которым я не управлял?

Когда я пытался применить алгоритм GA, я обнаружил проблему: я копирую значение из списка A в другой B и манипулирую B. Но когда я запускал модульный тест. Я просто обнаружил, что оба значения A и B изменились. И я понятия не имею, что случилось. Ниже мой код:

public class GA_bags {
    private Population population;
    private int fittest;
    private List<Individual> offsprings;

public GA_bags(int n,int sumBags,int maxWeight,Bag[] bags){
    this.population=new Population(n,sumBags,maxWeight,bags);
}


//Crossover Function
public void crossover(){
    Random random=new Random();
    List<Individual> individuals=population.getIndividuals();
    offsprings=new ArrayList<>(individuals);    //Intialize the offsprings, simply copy first
    int pos=random.nextInt(offsprings.get(0).getGenes().length);    //decide the position of genes to crossover
    for(int i=0;i<offsprings.size()-1;i+=2){         //1st fittest pair with 2nd fittest,3nd with the 4th...
        for(int j=0;j<=pos;j++){
            int tem=offsprings.get(i).getGenes()[j];
            offsprings.get(i).getGenes()[j]=offsprings.get(i+1).getGenes()[j];
            offsprings.get(i+1).getGenes()[j]=tem;
        }
    }
}

После того, как я реализовал метод кроссовера, изменились как отдельные лица, так и потомки List, но я управлял только потомками List.

public class Individual {
//each individual is a solution of KnapsackProblem
private int[] genes;      //"1" stands for the bag is chosen, while "0" stands for the bag is not
private Bag[] bags;       //each digit of gene is responsible for a specific Bag object
private int fitness;     //the fitness of an individual
private int curWeight;   //the weight of this individual
private int maxWeight;   //once the total weight of bags of this individual over maxWeight, then fitness is 0

public Individual(int sumBags,int maxWeight,Bag[] bags){
     this.genes=new int[sumBags];
     this.maxWeight=maxWeight;
     this.bags=bags;
     Random random=new Random();
     for(int i=0;i<sumBags;i++){
         genes[i]=random.nextInt(2);       //genetic code: random generate genes,"0" or "1"
     }
 }
}
offsprings=new ArrayList<>(individuals); не собирается создавать объекты newIndividual - они указывают на одни и те же объекты
Scary Wombat 13.04.2018 07:50

Так как мне это изменить?

Hanwen Guo 13.04.2018 07:53
клон
Scary Wombat 13.04.2018 07:55

Большое спасибо!

Hanwen Guo 13.04.2018 08:06
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
0
4
44
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Речь идет о глубоком копировании, и здесь является примером.

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

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

Я опередил тебя на секунду (как комментарий, как и должно быть)

Scary Wombat 13.04.2018 07:56

Хороший ответ был бы более содержательным и самодостаточным.

rustyx 13.04.2018 08:00

Большое спасибо!

Hanwen Guo 13.04.2018 08:06

Привет, ScaryWombat, rustyx, я понял свою точку зрения и добавил некоторые пояснения.

Bejond 13.04.2018 08:11

Другие вопросы по теме