Stream API. Собрать все значения поля String класса Model в одну коллекцию, распечатать - PullRequest
1 голос
/ 04 августа 2020

// Задача: есть класс Model, у которого есть поле типа String. Есть два класса контейнеров. Класс A содержит список объектов определенного типа Model и поле типа B. Класс B также содержит список объектов Model. Создать коллекцию объектов A, заполнить их внутреннее состояние (список, объект B) аналогично B. Собрать все значения поля String класса Model в одну коллекцию, распечатать. писал так: Как написать короче?

public class Task_2 {

public static void main(String[] args) {

    List<Model> modelsForB = new ArrayList<>();
    modelsForB.add(new Model("B1 "));
    modelsForB.add(new Model("B2 "));
    B b = new B(modelsForB);

    List<Model> modelsForA = new ArrayList<>();
    modelsForA.add(new Model("A1 "));
    modelsForA.add(new Model("A2 "));
    A a = new A(modelsForA, b);

    final List<String> collected = new ArrayList<>();

    Stream.of(a)
            .flatMap(item -> Stream.of(item.b))
            .flatMap(itemB -> itemB.models.stream())
            .map(model -> model.string)
            .forEach(collected::add);

    Stream.of(a)
            .flatMap(itemA -> itemA.models.stream())
            .map(model -> model.string)
            .forEach(collected::add);
    collected.forEach(System.out::println);
}

static class Model {

    String string;

    public Model(String string) {
        this.string = string;
    }
}

static class A {

    private List<Model> models;
    B b;

    public A(List<Model> models, B b) {
        this.models = models;
        this.b = b;
    }
}

static class B {
    private List<Model> models;

    public B(List<Model> models) {
        this.models = models;
    }
}

как написать короче?

Ответы [ 2 ]

1 голос
/ 05 августа 2020

Для этой задачи можно использовать метод stati c concat :

    List<String> collected = Stream
            .concat(a.models.stream(), a.b.models.stream())
            .map(model -> model.string)
            .collect(Collectors.toList());
0 голосов
/ 05 августа 2020

В соответствии с вашим вопросом вы хотите «Создать коллекцию объектов A», поэтому я хотел бы убедиться, что ваш ответ предусматривает это, а не только один A.

Я также добавил, используя массивы. asList (для добавленных записей), для краткости

public static void main(String[] args) {
    List<Model> modelsForB = new ArrayList<>();
    modelsForB.add(new Model("B1 "));
    modelsForB.add(new Model("B2 "));
    B b = new B(modelsForB);
    B b1 = new B(Arrays.asList( new Model("B1.1" ), new Model("B1.2" )));
    List<Model> modelsForA = new ArrayList<>();
    modelsForA.add(new Model("A1 "));
    modelsForA.add(new Model("A2 "));
    A a = new A(modelsForA, b);
    A a1 = new A(Arrays.asList( new Model("A1.1" ), new Model( "A1.2" )), b1 );
    List<A> listOfA = Arrays.asList( a, a1 );

    // If you need the collection, per the requirement, otherwise just use forEach to print instead of collect
    final List<String> collected = listOfA.stream()
            .flatMap( x -> Stream.concat( x.models.stream(), x.b.models.stream() ))
            .map(m -> m.string )
            .collect(Collectors.toList());
    collected.forEach(System.out::println);
}
...