Java 8: проверка общих элементов в двух списках с использованием потоков - PullRequest
0 голосов
/ 24 октября 2018

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

List<User> a;
List<User> b;
for (User user : a) {
    for (User newUser : b) {
        if (user.getName().equals(newUser.getName())) {
        }
    }
}

Как я могу написать это в java 8?Что-то вроде этого:

List<User> intersect = a.stream()
                    .filter(User::getName)
                    .collect(Collectors.toList());

Ответы [ 3 ]

0 голосов
/ 24 октября 2018

Один из способов сделать это, используя Stream.anyMatch (это будет break в пределах if), может быть:

a.stream().filter(user -> b.stream().anyMatch(newUser -> user.getName().equals(newUser.getName())))
          .map(User::getName)
          .forEach(System.out::println); // logic inside 'if' here (print for e.g.)

Если вы хотите повторить цикл (логика if) для всехтакие совпадения:

a.forEach(user -> b.stream()
                   .filter(newUser -> user.getName().equals(newUser.getName()))
                   .map(newUser -> user.getName())
                   .forEach(System.out::println));
0 голосов
/ 24 октября 2018

Когда пользователь правильно определен с hashCode и equals (в противном случае вы можете попробовать TreeSet вместо HashSet), выполните операции набора:

Set<User> common = new HashSet<>(a);
common.retainAll(b);

Если User.getNameне используется для равенства:

Set<User> common = new TreeSet<>(Comparator.comparing(User::getName));
common.addAll(a);
common.retainAll(b);

Два вложенных цикла for для списков (также как потоки) будут иметь сложность O (N²), тогда как это O (N.log N).

0 голосов
/ 24 октября 2018

Вы можете сделать что-то вроде ниже:

List<User> intersect = a.stream()
                     .filter(b::contains)
                     .collect(Collectors.toList());

Вам нужно переопределить equals и hashCode методы в User.Для оптимизации вы можете сначала преобразовать b в HashSet.

...