Яркий фильтр Java 8 по спискам
У меня есть два списка, и я хочу, чтобы были элементы фильтра, содержащие оба списка. И я хочу сделать это с помощью выражения лямбда.
Пользователи getName и клиенты getUserName возвращаются с помощью String.
Вот мой пример кода:
List<Client> clients = new ArrayList<>();
List<User> users = new ArrayList<>();
List<Client> results = new ArrayList<>();
for (Client user : users) {
for(Client client: clients){
if(user.getName().equals(client.getUserName())){
result.add(client);
}
}
}
Ответы
Ответ 1
Predicate<Client> hasSameNameAsOneUser =
c -> users.stream().anyMatch(u -> u.getName().equals(c.getName()));
return clients.stream()
.filter(hasSameNameAsOneUser)
.collect(Collectors.toList());
Но это довольно неэффективно, потому что это O (m * n). Вам лучше создать набор допустимых имен:
Set<String> acceptableNames =
users.stream()
.map(User::getName)
.collect(Collectors.toSet());
return clients.stream()
.filter(c -> acceptableNames.contains(c.getName()))
.collect(Collectors.toList());
Также обратите внимание, что он не является строго эквивалентным коду, который у вас есть (если он скомпилирован), который дважды добавляет один и тот же клиент в список, если несколько пользователей имеют то же имя, что и клиент.
Ответ 2
Посмотрите:
List<Client> result = clients
.stream()
.filter(c ->
(users.stream().map(User::getName).collect(Collectors.toList())).contains(c.getName()))
.collect(Collectors.toList());
Ответ 3
Я хотел бы поделиться примером, чтобы понять использование stream(). filter
Фрагмент кода. Пример программы для определения четного числа.
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
public void fetchEvenNumber(){
List<Integer> numberList = new ArrayList<>();
numberList.add(10);
numberList.add(11);
numberList.add(12);
numberList.add(13);
numberList.add(14);
numberList.add(15);
List<Integer> evenNumberListObj = numberList.stream().filter(i -> i%2 == 0).collect(Collectors.toList());
System.out.println(evenNumberListObj);
}
Выход будет: [10, 12, 14]
Список evenNumberListObj = numberList.stream(). filter (i → i% 2 == 0).collect(Collectors.toList());
numberList: объект ArrayList содержит список чисел.
java.util.Collection.stream(): stream() получит поток коллекции, который вернет поток Integer.
фильтр: возвращает поток, соответствующий данному предикату. на основе заданного условия (i → i% 2!= 0) возвращает соответствующий поток.
собирать: независимо от потока фильтра Integer, базирующегося в условиях фильтра, это целое число будет помещено в список.
Ответ 4
Что-то вроде:
clients.stream.filter(c->{
users.stream.filter(u->u.getName().equals(c.getName()).count()>0
}).collect(Collectors.toList());
Это, однако, не очень эффективный способ сделать это. Если коллекции не очень малы, вам лучше создать набор имен пользователей и использовать их в этом состоянии.