Java 8 流如何过滤在另一个数组列表中找不到的列表的内容?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/42730691/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-11-03 06:50:38  来源:igfitidea点击:

Java 8 streams how to filter contents a List not found in another arrayList?

javajava-8

提问by Clickmit Wg

Can I filter an array list based on the elements found in another array list in java 8? The whole story is that I have fetched list of active employees from oracle E-business suite app

我可以根据在 java 8 中的另一个数组列表中找到的元素过滤数组列表吗?整个故事是我从oracle电子商务套件应用程序中获取了活跃员工列表

**EmpID**
00123
003456
023299  

and I have a separate file which contains photo with file Name EmpID.jpeg

我有一个单独的文件,其中包含文件名为EmpID.jpeg 的照片

**FileName**
00123.jpeg
003456.jpeg
023299.jpeg         

Now my purpose is to compare the lists and to filter employees who provide me photos and from those they did not give me.

现在我的目的是比较列表并过滤提供我照片的员工和他们没有给我的员工。

private ArrayList<String> _IDsFromFile;
private ArrayList<String> _IDsFromImage;

      ---
      ---

public void compareAndCopy(String fileName){

}

回答by dimo414

First of all, you should convert one or the other of these lists into a Set, so that the .contains()check is efficient. Calling .contains()on a Listis a linear-time operation, meaning doing so ntimes is quadratic.

首先,您应该将这些列表中的一个或另一个转换为Set,以便.contains()检查有效。调用.contains()aList是一个线性时间操作,这意味着这样做n次是二次的。

Once you've done that it's straightforward to use .filter()or even .partitioningBy()to determine where the two lists overlap.

一旦完成,就可以直接使用.filter(),甚至.partitioningBy()可以确定两个列表的重叠位置。

Set<String> imageIdsSet = new HashSet<>(IDsFromImage);

List<String> overlappingIds = IDsFromFile.stream()
    .filter(imageIdsSet::contains)
    .collect(toList());

// OR

Map<Boolean, List<String>> partitionedIds = IDsFromFile.stream()
    .collect(partitioningBy(imageIdsSet::contains));
List<String> overlappingIds = partitionedIds.get(true);
List<String> missingIds = partitionedIds.get(false);


What you're describing, in principle, are set operations. The "overlapping" IDs are the intersectionof the two sets of IDs, while the "missing" IDs are the difference.

原则上,您所描述的是set operations。“重叠”ID 是两组ID 的交集,而“缺失”ID 是差异

Guavaprovides efficient implementations of these operations in their Setsutility. (union, intersection, difference, and complementOf).

Guava在其Sets效用中提供了这些操作的有效实现。( union, intersection, difference, 和complementOf)。

回答by shizhz

You can use filter API in java 8 Streamto do it. Like the following code snippet:

您可以在 java 8 Stream 中使用过滤器 API来做到这一点。像下面的代码片段:

import java.util.HashSet;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * @author Shizhz
 */
public class Main {
    private static Set<String> _IDsFromFile;
    private static Set<String> _IDsFromImage;

    static {
        _IDsFromFile = new HashSet();
        _IDsFromFile.add("00123");
        _IDsFromFile.add("003456");
        _IDsFromFile.add("023299");
        _IDsFromFile.add("023300");

        _IDsFromImage = new HashSet<>();
        _IDsFromImage.add("00123.jpeg");
        _IDsFromImage.add("003456.jpeg");
        _IDsFromImage.add("023299.jpeg");
    }

    private static Set<String> filterEmployeesWithPhones(Set<String> employeeSet, Set<String> photoSet) {
        return employeeSet.stream().filter(empId -> photoSet.contains(empId + ".jpeg")).collect(Collectors.toSet());
    }

    public static void main(String[] args) {
        filterEmployeesWithPhones(_IDsFromFile, _IDsFromImage).forEach(emp -> System.out.println(emp));
    }
}

will give you the result:

会给你结果:

00123

003456

023299

00123

003456

023299