Java: изменение элемента данных влияет на «несвязанную» структуру данных - PullRequest
0 голосов
/ 03 июля 2011

У меня проблема с извлечением элемента из списка (list1), изменением одного из параметров в элементе и добавлением его в другой список (list2).Когда я делаю это с последним элементом в list1, он иногда изменяет параметры элементов в list2.

Эта функция вызывается один раз за поколение, но только в 8-м поколении, когда я начинаюувидеть это произойдет.Он затрагивает от 2 до 16 элементов в списке 2.

Есть идеи, где мой провал?Вот блок кода, который я написал, чтобы проиллюстрировать проблему.Проблема возникает в разделе, где я проверяю count == 0.

    public void sampleCode (List list) {
    List differentList = new ArrayList();
    Individual element;
    Individual differentelement;
    int i = 0;
    int count = 0;
    for(i = 0; i < list.size(); i++) {

        element = (Individual) list.get(i)  ;


        // does some checking to see if this meets criteria
        // this is sorta pseudo code
        if(probability == true) { 
            element.setDoMutation(true);
            count++;
        }
        //always add this element to differentList
                    //even if no changes are made to the element
        differentList.add(i,element);
    }
        //need to make sure one elements has mutation=true;
    if(count == 0) { 
        differentelement = (Individual) list.get((list.size()-1));

        //setting this element field changes the contents of
        //different list.
        differentelement.setDoMutation(true);
        differentList.set((list.size()-1), differentelement);
    }   
}

Ответы [ 2 ]

2 голосов
/ 03 июля 2011

В Java переменная не содержит объект. Он содержит ссылку на объект (то есть указатель на объект). Получение объекта из списка и помещение его в другой список не создает копию объекта. Оба списка просто имеют указатель на один и тот же объект. Поэтому, конечно, если вы измените содержимое объекта, объект будет изменен в обоих списках.

Примечание: вы должны использовать параметризованные типы (т.е. List<Individual>, а не List) и избегать объявления переменных в начале ваших методов, как вы делали бы в C. Объявляйте переменную только тогда, когда вам это нужно. Это сделает код намного понятнее и сократит область видимости ваших переменных.

0 голосов
/ 03 июля 2011

Вы уверены, что блок

    //need to make sure one elements has mutation=true;
    if(count == 0) { 
        differentelement = (Individual) list.get((list.size()-1));

        //setting this element field changes the contents of
        //different list.
        differentelement.setDoMutation(true);
        differentList.set((list.size()-1), differentelement);
    }   

должен находиться внутри цикла

for(i = 0; i < list.size(); i++) {
    ...
}

Я подозреваю, что для правильной работы его необходимо переместить после цикла.

...