Java 8 пропонує новий спосіб виклику конструктора копій або методу клонування на елементах собак елегантно і компактно: Потоки , лямбда і колектори .
Конструктор копіювання:
List<Dog> clonedDogs = dogs.stream().map(Dog::new).collect(toList());
Вираз Dog::new
називається посиланням на метод . Він створює об'єкт функції, який викликає конструктор, на Dog
якому приймає іншу собаку як аргумент.
Клонний метод [1]:
List<Dog> clonedDogs = dogs.stream().map(d -> d.clone()).collect(toList());
Отримання ArrayList
результату
Або, якщо вам доведеться повернутись ArrayList
назад (якщо ви хочете його змінити пізніше):
ArrayList<Dog> clonedDogs = dogs.stream().map(Dog::new).collect(toCollection(ArrayList::new));
Оновіть список на місці
Якщо вам не потрібно зберігати оригінальний вміст dogs
списку, ви можете скористатися replaceAll
методом та оновити список на місці:
dogs.replaceAll(Dog::new);
Усі приклади припускають import static java.util.stream.Collectors.*;
.
Колекціонер для ArrayList
с
Колектор з останнього прикладу можна перетворити на утилітний метод. Оскільки це така звичайна річ, я особисто люблю, щоб вона була короткою і красивою. Подобається це:
ArrayList<Dog> clonedDogs = dogs.stream().map(d -> d.clone()).collect(toArrayList());
public static <T> Collector<T, ?, ArrayList<T>> toArrayList() {
return Collectors.toCollection(ArrayList::new);
}
[1] Примітка щодо CloneNotSupportedException
:
Для цього рішення для роботи clone
метод Dog
не повинен оголошувати, що він кидає CloneNotSupportedException
. Причина полягає в тому, що аргумент до map
заборонено кидати перевірені винятки.
Подобається це:
// Note: Method is public and returns Dog, not Object
@Override
public Dog clone() /* Note: No throws clause here */ { ...
Однак це не повинно бути великою проблемою, оскільки це якнайкраща практика. ( Дана порада дає Effectice Java .)
Дякую Густаво, що зауважив це.
PS:
Якщо вам здається красивішим, ви можете замість цього використовувати синтаксис опорного методу, щоб зробити саме те саме:
List<Dog> clonedDogs = dogs.stream().map(Dog::clone).collect(toList());