Удалить элементы в глубину, используя потоки

У меня есть следующие классы.

Class A {
    List<B> b
   //getters and setters
}

CLass B {
   List<C> c
   //getters and setters
}

 Class C {
    List<D> d
   //getters and setter
}

Class D {}

Что я хочу сделать, это удалить list d если конкретного поискового запроса нет в списке. Я пытался сделать это, но не повезло. Я думаю, что это удаляет, но ссылка не сохраняется.

a.stream()
        .flatMap(a-> a.getB().stream())
        .flatMap(b-> b.getC().stream())
        .map(c-> c.getD())
        .collect(Collectors.toList())
        .removeIf(list -> {
            boolean toBeRemoved = true;
            boolean containsMatch = list.stream().anyMatch(w-> {return w.getId().equalsIgnoreCase(searchTerm);});
            if(containsMatch) {
                toBeRemoved = false;
            }               
            return toBeRemoved;
        });

Кто-нибудь может мне помочь?

2 ответа

Решение

То, что вы сделали, создает List<List<D>> и вы удалите List<D> элементы, которые не соответствуют, но которые никогда не изменяют объекты, которые у вас есть.

  • Вам нужно перебрать все C элементы,
  • Вы оставляете те, которые не соответствуют (используйте noneMatch() проверить это)
  • для этих вы заменяете list пустым (или очистить фактическое c.getD().clear())

a.stream()
    .flatMap(a-> a.getB().stream())
    .flatMap(b-> b.getC().stream())
    .filter(c -> c.getD().stream().noneMatch(w -> w.getId().equalsIgnoreCase(searchTerm)))
    .forEach(c-> c.setD(new ArrayList<>()));    // or .forEach(c-> c.getD().clear());

Поток представляет собой представление "базовой" коллекции. Это означает, что когда вы звоните removeIf() в потоке "базовая" коллекция вообще не затрагивается.

Вам нужно будет сделать две вещи: сначала вы "соберете" все элементы, которые вы собираетесь удалить, а затем просто удалите их (явным вызовом) из списка, который необходимо изменить:

List<B> toBeDeleted = a.stream()....collect(Collectors.toList());
a.b.removeAll(toBeDeleted);

(вышеприведенное подразумевается как псевдокод, я не запускал его через компилятор)

Как уже говорилось: настоящая проблема здесь - ваше неправильное представление: операции над потоком обычно не влияют на базовую коллекцию.

Другие вопросы по тегам