Подскажите пожалуйста, как написать универсальный метод для добавления объектов в List

List<Animal> cellHerbivore = new ArrayList<>();
   
public int herbivoresInitialize() {
        int numberRabbitCell = ThreadLocalRandom.current().nextInt(1, new Rabbit().getMaxQuantityTypeAnimal());

        for (int i = 1; i <= numberRabbitCell; i++) {
            cellHerbivore.add(new Rabbit());
        }

Есть ещё другие объекты, кроме кролика и получается, что копипастить приходится одно и тоже.


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

Автор решения: Nowhere Man
  1. Нужно написать метод, который принимает на вход ссылку на конструктор подкласса Animal (Supplier) и возвращает список из нескольких элементов.

  2. Результат работы метода следует добавить в нужный список animals, используя List::addAll

public <T extends Animal> List<T> generate(Supplier<T> creator) {
    int n = creator.get().getMaxQuantityTypeAnimal();
    
    return IntStream.range(0, ThreadLocalRandom.current().nextInt(1, n))
        .mapToObj(i -> creator.get())
        .collect(Collectors.toList());
        //.collect(Collectors.toCollection(() -> new ArrayList<T>(n)));
}

private List<Animal> animals = new ArrayList<>();

private void populateAnimals() {
    animals.addAll(generate(Rabbit::new));
    animals.addAll(generate(Hamster::new));
}

Или же можно создать отдельный метод, возвращающий сгенерированный список и принимающий на вход переменный массив конструкторов:

public static <T extends Animal> List<T> animalsOf(Supplier<T> ... creators) {
    return Arrays.stream(creators) // Stream<Supplier>
        .flatMap(creator -> Stream.generate(creator::get)
            .limit(ThreadLocalRandom.current()
                .nextInt(1, creator.get().getMaxQuantityTypeAnimal())
            ) // Stream<T>
        ) // Stream<T>
        .collect(Collectors.toList());
}

// вызов
private List<Animal> animals = animalsOf(Rabbit::new, Hamster::new);
→ Ссылка