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

Я хочу улучшить свое кодирование Java.

Может ли кто-нибудь предоставить ссылку или объяснение того, существует ли практический код для инициализации ArrayLists и предотвращения следующей проблемы:

-У меня есть 6 ArrayList в одном классе, некоторые из них являются подмножествами других. Поскольку некоторые из них являются подмножествами других, я понимаю, что они используют одни и те же ссылки через методы «addAll()» и «add()».

В результате, пытаясь изменить элементы в подмножествах, я также изменяю исходные наборы, потому что, опять же, они имеют одну и ту же ссылку. Мой код настолько беспорядочный, что несколько вызовов «get» приводят к сбросу 2 моих ArrayList.

Я исследовал этот форум и 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
@ ТиДжей Краудер. Хорошо, но мне потребуется некоторое время, чтобы отредактировать. Я знаю, что у меня есть проблемы со ссылками, и я не удивлен тем количеством ссылок, которое происходит в моем классе. Но я изо всех сил пытаюсь понять, где - чтобы иметь возможность сделать небольшой пример. Позвольте мне посмотреть, смогу ли я редактировать с минимальным кодом.   -  person cworner1    schedule 28.11.2012
comment
@ T.J.Crowder Нет, извините. Я изо всех сил пытаюсь понять, почему у меня проблема со ссылкой. Я просто знаю, что у меня есть один. Но, глядя на ответы ниже, я думаю, что ответ заключается в создании новых объектов для каждого ArrayList, чтобы каждый ArrayList хранился отдельно от каждого.   -  person cworner1    schedule 28.11.2012


Ответы (2)


Может ли кто-нибудь предоставить ссылку или объяснение того, существует ли практический код для инициализации ArrayLists и предотвращения следующей проблемы:

Не существует такого кодекса практики, или передовой практики, или чего-либо еще при инициализации ArrayLists.

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

(Спрашивать о «наилучшей практике» по этой теме все равно, что спрашивать «наилучшую практику» в отношении того, следует ли вам использовать операторы + или -...)

Вместо того, чтобы искать в Google «лучшую практику» по этому вопросу, я предлагаю вам вернуться к своему учебнику по Java / учебнику / конспектам лекций и прочитать:

  • что такое ссылки на объекты Java
  • что означает назначение объекта, и
  • что делает оператор new.

И убедитесь, что вы действительно их понимаете. Когда вы поймете их, вы сможете понять, какие из них использовать, чтобы делать то, что вы пытаетесь сделать в своей программе.

person Stephen C    schedule 28.11.2012

addAll добавляет ссылки на объекты в ArrayList, а не копии из объектов. Если вам нужны копии, вы должны выполнить итерацию по 1-му 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