Java 8 Lambda按列表过滤

esz*_*k.k 42 java lambda java-8

我有两个列表,我想要过滤器thoose元素,这两个元素都列表包含.我想用lambda表达式来做这件事.

用户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);
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

JB *_*zet 70

Predicate<Client> hasSameNameAsOneUser = 
    c -> users.stream().anyMatch(u -> u.getName().equals(c.getName()));

return clients.stream()
              .filter(hasSameNameAsOneUser)
              .collect(Collectors.toList());
Run Code Online (Sandbox Code Playgroud)

但这是非常低效的,因为它是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());
Run Code Online (Sandbox Code Playgroud)

另请注意,它并不严格等同于您拥有的代码(如果已编译),如果多个用户与客户端具有相同的名称,则会将相同的客户端两次添加到列表中.

  • 否.列表上的调用contains()会遍历列表.但是在HashSet上调用contains只计算hashCode并遍历与该hashCode相对应的存储桶,该hashCode通常包含0或1个元素.HashSet包含查找是O(1). (3认同)
  • 啊我懂了.在列表上调用.contains()将是O(n),但在HashSet上调用O(1).谢谢你的澄清! (2认同)

Esw*_*san 6

我想分享一个例子来理解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);
}
Run Code Online (Sandbox Code Playgroud)

输出将是:[10,12,14]

列表 EvenNumberListObj = numberList.stream().filter(i -> i%2 == 0).collect(Collectors.toList());

numberList:它是一个包含数字列表的 ArrayList 对象。

java.util.Collection.stream():stream()将获取集合流,该流将返回整数流。

filter:返回与给定谓词匹配的流。即根据给定条件 (i -> i%2 != 0) 返回匹配的流。

collect:无论过滤条件中的整数过滤器的流是什么,这些整数都会被放入一个列表中。


小智 5

看看这个:

List<Client> result = clients
    .stream()
    .filter(c -> 
        (users.stream().map(User::getName).collect(Collectors.toList())).contains(c.getName()))
        .collect(Collectors.toList());
Run Code Online (Sandbox Code Playgroud)