Комментарии (1)
🐱
claude-haiku-4.5PrepBro AI22 мар. 2026 г.(ред.)
Ответ сгенерирован нейросетью и может содержать ошибки
Копирование коллекций в Java
В Java существует несколько способов создать копию коллекции, каждый из которых имеет свои особенности и уровень глубины копирования.
1. Поверхностное копирование (Shallow Copy)
а) Через конструктор коллекции
List<String> original = new ArrayList<>(Arrays.asList("A", "B", "C"));
List<String> copy = new ArrayList<>(original); // Копирует ссылки на элементы
copy.add("D");
System.out.println(original); // [A, B, C]
System.out.println(copy); // [A, B, C, D]
Это самый быстрый способ, создаёт новый список, но элементы остаются одни и те же (ссылки копируются).
б) Через addAll()
List<String> original = new ArrayList<>(Arrays.asList("A", "B", "C"));
List<String> copy = new ArrayList<>();
copy.addAll(original);
в) Через ArrayList.clone()
ArrayList<String> original = new ArrayList<>(Arrays.asList("A", "B", "C"));
ArrayList<String> copy = (ArrayList<String>) original.clone();
2. Копирование через Stream API (Java 8+)
List<String> original = new ArrayList<>(Arrays.asList("A", "B", "C"));
// Копирование в новый список
List<String> copy = original.stream()
.collect(Collectors.toList());
// Неизменяемая копия
List<String> immutableCopy = original.stream()
.collect(Collectors.toUnmodifiableList());
// Копирование в HashSet
Set<String> setCopy = original.stream()
.collect(Collectors.toSet());
3. Копирование с помощью Collections.copy()
List<String> original = new ArrayList<>(Arrays.asList("A", "B", "C"));
List<String> copy = new ArrayList<>(original.size());
// Заполняем копию nullами
for (int i = 0; i < original.size(); i++) {
copy.add(null);
}
// Копируем элементы
Collections.copy(copy, original);
// Или просто
List<String> copy2 = new ArrayList<>(original); // Проще
4. Глубокое копирование (Deep Copy) для объектов
Когда коллекция содержит сложные объекты, нужна глубокая копия:
а) Через Stream с map()
public class User {
private String name;
private int age;
public User(String name, int age) {
this.name = name;
this.age = age;
}
// Copy constructor
public User(User other) {
this.name = other.name;
this.age = other.age;
}
}
List<User> original = new ArrayList<>(Arrays.asList(
new User("Alice", 25),
new User("Bob", 30)
));
// Глубокое копирование
List<User> deepCopy = original.stream()
.map(User::new) // Используем copy constructor
.collect(Collectors.toList());
deepCopy.get(0).setName("Charlie");
System.out.println(original.get(0).getName()); // "Alice" (не изменилось)
System.out.println(deepCopy.get(0).getName()); // "Charlie"
б) Через Cloneable интерфейс
public class User implements Cloneable {
private String name;
private int age;
@Override
public User clone() throws CloneNotSupportedException {
return (User) super.clone();
}
}
List<User> deepCopy = original.stream()
.map(u -> {
try {
return u.clone();
} catch (CloneNotSupportedException e) {
throw new RuntimeException(e);
}
})
.collect(Collectors.toList());
в) Через JSON сериализацию (ObjectMapper)
ObjectMapper mapper = new ObjectMapper();
List<User> deepCopy = mapper.readValue(
mapper.writeValueAsString(original),
new TypeReference<List<User>>() {}
);
5. Неизменяемые копии (Immutable Collections)
List<String> original = new ArrayList<>(Arrays.asList("A", "B", "C"));
// Java 9+
List<String> unmodifiable = List.copyOf(original);
// unmodifiable.add("D"); // UnsupportedOperationException
// Java 8
List<String> immutable = Collections.unmodifiableList(
new ArrayList<>(original)
);
// Set
Set<String> immutableSet = Set.copyOf(original);
// Map
Map<String, Integer> immutableMap = Map.copyOf(
Map.of("A", 1, "B", 2)
);
6. Apache Commons Lang - ArrayUtils
List<String> original = new ArrayList<>(Arrays.asList("A", "B", "C"));
List<String> copy = new ArrayList<>(original);
// Если нужна примитивная копия
int[] arr = {1, 2, 3};
int[] arrCopy = ArrayUtils.clone(arr);
Таблица сравнения методов
| Метод | Тип копии | Скорость | Использование |
|---|---|---|---|
| new ArrayList<>(list) | Поверхностная | ⚡⚡⚡ Быстро | 99% случаев |
| stream().collect() | Поверхностная | ⚡⚡ Нормально | Функциональный стиль |
| clone() | Поверхностная | ⚡⚡⚡ Быстро | Если есть Cloneable |
| stream().map(copy) | Глубокая | ⚡ Медленно | Сложные объекты |
| List.copyOf() | Неизменяемая | ⚡⚡ | Java 9+ для защиты |
| Collections.unmodifiable | Неизменяемая | ⚡⚡⚡ | Java 8 и ниже |
Когда что использовать
// Простые типы (String, Integer, etc.)
List<String> copy = new ArrayList<>(original); // ✅ Проще и быстрее
// Нужна защита от изменений
List<String> safe = List.copyOf(original); // ✅ Java 9+
// Сложные объекты с изменяемыми полями
List<User> deepCopy = original.stream()
.map(User::new)
.collect(Collectors.toList()); // ✅ Правильно
// Функциональный стиль с трансформацией
List<String> names = users.stream()
.map(User::getName)
.collect(Collectors.toList()); // ✅ Идеально
Главное правило: используй конструктор коллекции для простого копирования, Stream API для трансформаций, и copy constructor для объектов при глубоком копировании.