Операция Java 8 Stream на основе списков - PullRequest
0 голосов
/ 24 июня 2019

У меня есть два списка.Первый - это список строк - список, второй содержит список нового класса, скажем, класс B.

Класс B содержит строковые поля, такие как example1, example2, example3, example4 и многие другие.

Я пробовал что-то подобное, но я думаю, что он работает над коллекцией клонов и не меняет определенное значение на ноль.

listOfB.stream().flatMap(p -> Stream.of(p.getExample1(),p.getExample2(), 
p.getExample3(), p.getExample4()))
            .forEach(i -> {
                if (listOfA.contains(i)) {
                    i = null
                }
            });

то, чего я хочу достичь, - это пролистать список объектов B, получитьвсе примерные поля (от 1 до 4), а затем проверьте, содержит ли список хотя бы одно из значений примерных полей, если да, то установите для этого конкретного примерного поля значение null.

Ответы [ 3 ]

1 голос
/ 24 июня 2019

Чтобы выполнить это только с одним потоком, вы должны пройти серию if проверок внутри вашей лямбды.

public void stack() {
    List<String> aList = Arrays.asList("foo2", "baz4");

    B b1 = new B("foo1", "foo2", "foo3", "foo4");
    B b2 = new B("bar1", "bar2", "bar3", "bar4");
    B b3 = new B("baz1", "baz2", "baz3", "baz4");

    List<B> bList = Stream.of(b1, b2, b3).peek(b -> {
        if (aList.contains(b.getExample1())) {
            b.setExample1(null);
        }
        if (aList.contains(b.getExample2())) {
            b.setExample2(null);
        }
        if (aList.contains(b.getExample3())) {
            b.setExample3(null);
        }
        if (aList.contains(b.getExample4())) {
            b.setExample4(null);
        }
    }).collect(Collectors.toList());

    System.out.println(bList);
}

Вывод:

B [example1 = foo1, example2 = null, example3 = foo3, example4 = foo4],

B [example1 = bar1, example2 = bar2, example3 = bar3, example4 = bar4],

B [example1 = baz1, example2 = baz2, example3 = baz3, example4 = null]

0 голосов
/ 24 июня 2019

Вы можете сделать это примерно так: использовать набор вместо списка

bList = bList.stream().map(b -> b.modify(aSet))
            .collect(Collectors.toList());

OR

bList.replaceAll(b -> b.modify(aSet));

и определите метод в классе B:

public B modify(Set<String> set) {
    this.example1 = set.contains(this.example1) ? null : this.example1;
    this.example2 = set.contains(this.example2) ? null : this.example2;
    this.example3 = set.contains(this.example3) ? null : this.example3;
    this.example4 = set.contains(this.example4) ? null : this.example4;
    return this;
}
0 голосов
/ 24 июня 2019

Изменение параметров лямбда не действует вне лямбда. Метод, который вы ищете: .filter()

.filter(i -> !listOfA.contains(i))

Хотя замена forEach на filter мало что даст, потому что filter не является терминальной операцией. Обратите внимание, как он возвращает Stream<T>. Если вы хотите, чтобы изменения вступили в силу в listOfB, вам нужно собрать поток в новый список и переназначить его.

List<String> list = stream.collect(Collectors.toList())
...