Почему не работает метод Collections.copy()?

import java.util.ArrayList;
import java.util.Collections;

public class GFG1 {

    private static ArrayList<Integer> integers = new ArrayList<>();

    public static void main(String[] args) throws Exception {
        Collections.addAll(integers, 1, 2, 3, 4, 5);
        System.out.printf("integers.size() = %d", integers.size());
        
        ArrayList<Integer> copyOfIntegers = new ArrayList<Integer>(integers.size());
        System.out.printf("copyOfIntegers.size() = %d", copyOfIntegers.size());

        Collections.copy(copyOfIntegers, integers);
    }
}

Я явно создаю список для копирования такого же размера, как и integers, однако ловлю исключение. Чего ради вообще тогда указывать в конструкторе этого класса размерность нового списка, если сразу после создания она равна нулю?) И я, соответственно, не могу скопировать нужный список в другой (который априори пустой) с помощью данного метода.


Ответы (1 шт):

Автор решения: Nowhere Man

Использование конструктора списка с указанием ёмкости ArrayList(int capacity) совершенно не означает, что новый список будет иметь размер (size), равный указанной ёмкости:

Collections.addAll(integers, 1, 2, 3, 4, 5);
System.out.printf("integers.size() = %d%n", integers.size()); 
// -> 5
        
ArrayList<Integer> copyOfIntegers = new ArrayList<Integer>(integers.size());
System.out.printf("copyOfIntegers.size() = %d%n", copyOfIntegers.size()); 
// -> 0

Документация для метода Collections::copy(List<? super T> dest, List<? extends T> src) совершенно чётко указывает, что размер списка-приёмника dest должен быть НЕ МЕНЬШЕ, чем размер списка-источника:

The destination list must be at least as long as the source list.
...
Throws:
IndexOutOfBoundsException - if the destination list is too small to contain the entire source List.

Если требуется получить копию списка, проще всего использовать конструктор:

List<Foo> src = ...; // источник
List<Foo> dst = new ArrayList<>(src); // поверхностная (shallow) копия
→ Ссылка