2017-02-15 18 views
-1

Edit:JAVA: Почему мне нужно создать новый объект списка в этой функции?

функция является частью ответа на вопрос "lintcode комбинационной суммы", если я использую второй вариант, выход «[[], ..., []], где все

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

Код:

private void helper(ArrayList<ArrayList<Integer>> result, ArrayList<Integer> list, int target, ...) { 
    if (target == 0) { 
     result.add(new ArrayList<Integer>(list)); 

     return; 
    } 

    ... 
} 

Вопрос:

Почему мне нужно создать новый объект ArrayList, а затем добавить его в результате?

Какая разница между этим методом и код ниже:

private void helper(ArrayList<ArrayList<Integer>> result, ArrayList<Integer> list, int target, ...) { 
    if (target == 0) { 
     result.add(list); 

     return; 
    } 

    ... 
} 

Может кто-нибудь объяснить мне это? Спасибо!

+5

Разница - это именно то, что вы указали. Либо вы создаете новый список, либо используете существующий список. Какова цель этой функции? – CollinD

+0

Цель состоит в том, чтобы добавить «список» к «результату», эта функция является частью ответа на вопрос с линией. Однако, когда я использую вторую версию, вывод [[], ..., []], в основном весь внутренний список пуст. Если я переключусь на первый, это сработает. Вот почему я немного смущен –

+0

Не могли бы вы представить свою реализацию решения проблемы суммарной суммы? – Brion

ответ

1

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

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

Разница становится очевидным при выполнении этого кода:

private static void helper1(ArrayList<ArrayList<Integer>> result, ArrayList<Integer> list) { 
    // add by duplicating the provided list 
    result.add(new ArrayList<Integer>(list)); 
} 

private static void helper2(ArrayList<ArrayList<Integer>> result, ArrayList<Integer> list) { 
    // add provided list as is 
    result.add(list); 
} 

public static void main(String[] args) { 
    ArrayList<ArrayList<Integer>> result = new ArrayList<>(); 

    ArrayList<Integer> list1 = new ArrayList<>(); 
    list1.add(10); 
    helper1(result, list1); 

    ArrayList<Integer> list2 = new ArrayList<>(); 
    list2.add(20); 
    helper2(result, list2); 

    System.out.println(result); // [[10], [20]] 

    list1.add(11); 
    list2.add(21); 

    System.out.println(result); // [[10], [20, 21]] 
} 

Здесь первые два списка добавляются в результате каждый из которых содержит одно целое число. Первый список добавляется с помощью helper1, а второй список добавляется с помощью helper2. После этого оба списка изменяются путем добавления другого Integer. Для списка 1 изменение не влияет на наш результат, но модификация list2 делает.

+0

Спасибо, это проблема. –

0

В конце концов, они делают одно и то же, однако единственное различие, которое я могу заметить, - это первое, что использует больше памяти, и нет необходимости фактически создавать новый ArrayList уже существующего.

0

В первом примере вы действительно не используете заданное значение, вместо этого вы создаете новый локальный список. Во втором примере вы работаете с заданным значением.

Например, если вы вызываете метод и указываете значение ArrayList<Integer>list[2,5,52,888], значит вы добавите это значение в существующий список.

0

Во втором примере, если список изменен вне метода, список в результате тоже изменился, так как он является одним и тем же экземпляром списка.

В первом примере вы создаете копию списка, изолируя ее от модификаций.

+0

Спасибо! Вы на месте. –

0

@CollinD поднял хороший вопрос, чтобы убедиться, что вы знаете истинное намерение вспомогательного метода.

Когда вы передаете объект в Java, вы передаете ссылку на объект. Любые изменения в ссылке будут отражены в исходном объекте, который вы создали.

public static void main(String[] args) { 
    ArrayList<ArrayList<Integer>> arrays = new ArrayList<>(); 
    ArrayList<Integer> list1 = new ArrayList<>(); 
    list1.add(1); 
    list1.add(2); 
    helper(arrays, list1); 
    arrays.get(0).add(3); 

    list1.forEach(e -> System.out.print(e)); 
    System.out.print("\n"); 
    arrays.get(0).forEach(e-> System.out.print(e)); 

} 

Попробуйте выполнить этот пример кода с помощью двух разных вспомогательных методов.

Вы заметите, что оригинальный метод предоставит вам два разных списка значений.

12 
123 

Хотя второй метод предоставляет вам с теми же значениями

123 
123 

Это происходит потому, что конструктор ArrayList (список) делает копию значений в списке на новый объект. Второй метод просто добавляет ссылочные списки к массиву, который будет использоваться позже, который в примере проекта, который я дал, теперь у вас есть два разных способа доступа к списку1.

+0

Большое вам спасибо за ответ. Это действительно полезно! –

 Смежные вопросы

  • Нет связанных вопросов^_^