Практика на кодиране за инициализиране на ArrayLists

Търся да подобря моето Java кодиране.

Може ли някой да предостави връзка или обяснение дали има код на практика за инициализиране на ArrayLists и избягване на следния проблем:

-Имам 6 ArrayList в един клас, някои са подмножества на други. Тъй като някои са подгрупи на други, разбирам, че споделят едни и същи препратки чрез методите "addAll()" и "add()".

В резултат на това, опитвайки се да променя елементите в подмножества, променям и оригиналните набори, защото отново - те споделят една и съща препратка. Кодът ми е толкова объркан, че няколко извиквания "get" водят до нулиране на 2 от моите ArrayLists.

Проучих този форум и Google и изглежда не мога да намеря съответната информация, която искам. Намирам само прости примери за ArrayLists. Забелязах, че в този форум има няколко въпроса, свързани с препратки към ArrayList, така че мисля, че отговорът на този въпрос ще бъде от полза за други в бъдеще.


person cworner1    schedule 28.11.2012    source източник
comment
Трябва да покажете кода си - изглежда, че известно преработване би било от полза...   -  person assylias    schedule 28.11.2012
comment
Моето кодиране е твърде дълго, но ще го включа, ако желаете това.   -  person cworner1    schedule 28.11.2012
comment
@cworner1: За да задавате полезни въпроси, създайте минимален, самостоятелен пример за това, за което говорите. Публикувайте това и задайте въпроса си за него.   -  person T.J. Crowder    schedule 28.11.2012
comment
може би Arrays.asList(T... a)   -  person user1121883    schedule 28.11.2012
comment
@ T.J.Crowder. Добре, но ще ми отнеме известно време, за да редактирам отново. Знам, че имам проблем с препратките и не съм изненадан от количеството споделяне на препратки, което се случва в моя клас. Но се боря да разбера къде - да мога да направя малък пример. Нека да видя дали мога да редактирам с минимален код.   -  person cworner1    schedule 28.11.2012
comment
@ T.J.Crowder Не, съжалявам. Мъча се да разбера защо имам проблем със справката. Просто знам, че имам един. Но като гледам отговорите по-долу, мисля, че отговорът е да се създадат нови обекти за всеки ArrayList, така че всеки ArrayList да се съхранява отделно от всеки един.   -  person cworner1    schedule 28.11.2012


Отговори (2)


Може ли някой да предостави връзка или обяснение дали има код на практика за инициализиране на ArrayLists и избягване на следния проблем:

Няма такъв кодекс на практика, или най-добра практика, или каквото и да е при инициализиране на ArrayLists.

Проблемът основно е, че трябва да разберете разликата в Java между използването на препратка към съществуващ обект и създаването на нов обект. След това трябва да изберете подходящия ... в зависимост от това, което се опитвате да направите.

(Да питате за „най-добра практика“ по тази тема е като да питате за „най-добра практика“ за това дали трябва да използвате оператори + или - ...)

Вместо да търсите в Гугъл „най-добра практика“ по този въпрос, предлагам ви да се върнете към вашия учебник / урок / бележки от лекции по Java и да прочетете:

  • какви са препратките към Java обекти
  • какво означава присвояването на обект и
  • какво прави операторът new.

И се уверете, че наистина ги разбирате. Когато ги разберете, ще можете да разберете кой да използвате, за да направите това, което се опитвате да направите във вашата програма.

person Stephen C    schedule 28.11.2012

addAll добавя препратки към обектите в ArrayList, а не копия от обекти. Ако искате копия, трябва да преминете през първия ArrayList и за всеки обект да извикате функцията "клониране", която ще създаде копие на обекта и ще го добави към новия ArrayList.

Пример:

public static void main(String[] args) {
    ArrayList<Foo> A = new ArrayList<Foo>();
    A.add(new Foo("foo1", 1));
    A.add(new Foo("foo2", 2));
    ArrayList<Foo> B = new ArrayList<Foo>();
    System.out.println("Before: ");
    System.out.println("A:");
    for(Foo foo:A){
        System.out.println(foo);
        try {
            B.add((Foo)foo.clone());
        } catch (CloneNotSupportedException ex) {
            //Never Gonna Happen
        }
    }
    System.out.println("B:");
    for(Foo foo:B){
        System.out.println(foo);
    }

    A.remove(0);

    System.out.println("After:");
    System.out.println("A:");
    for(Foo foo:A){
        System.out.println(foo);
    }
    System.out.println("B:");
    for(Foo foo:B){
        System.out.println(foo);
    }
}

public static class Foo{
    private String Name;
    private int Id;

    public Foo(String Name, int Id) {
        this.Name = Name;
        this.Id = Id;
    }

    @Override
    protected Object clone() throws CloneNotSupportedException {
        return new Foo(Name,Id);
    }

    @Override
    public String toString() {
        return "Name: "+Name+", Id: "+Id;
    }
}

Това разпечатва:

Before: 
A:
Name: foo1, Id: 1
Name: foo2, Id: 2
B:
Name: foo1, Id: 1
Name: foo2, Id: 2
After:
A:
Name: foo2, Id: 2
B:
Name: foo1, Id: 1
Name: foo2, Id: 2

Ако имате работа с ArrayLists на класове, които сте създали, уверете се, че всички те имат отменена функция "клониране". За класове, съдържащи класове, които също сте създали, използвайте функциите "клонинг", които сте създали за вътрешните класове в родителския клас "клонинг". И така нататък.

person Hazem Elraffiee    schedule 28.11.2012