从 java 8 流中的列表中过滤值

Posted

技术标签:

【中文标题】从 java 8 流中的列表中过滤值【英文标题】:Filtering values from a list in a java 8 stream 【发布时间】:2021-11-06 18:03:48 【问题描述】:

我们有一个 Object 类型的对象列表,例如,我们可能从缓存中获取它们,所以我们想用 lambda 流迭代该列表,并且在每次迭代中映射一个对象之后,我们想看看是否该新类的属性存在于我们传递给该方法的字符串值列表中。

【问题讨论】:

请提供足够的代码,以便其他人更好地理解或重现问题。 【参考方案1】:

您的解决方案未优化。使用List.contains 会给您带来O(n*m) 的复杂性。请改用HashSet

public List<MyClass> getMyClassListByStates(List<String> states) 
    Set<String> set = new HashSet<>(states);
    return cache.getCacheByCacheNameList(CacheTypeConstants.MY_CLASS)
                .stream()
                .map(MyClass.class::cast)
                .filter(myc -> set.contains(myc.getState()))
                .collect(Collectors.toList());

这将在O(max(n,m)) 时间运行,而不是O(n*m)

【讨论】:

请注意,从 Java 16 开始,您可以直接在流上使用 .toList() 是的,但是 OP 将问题明确标记为 java-8 那是公平的,那么我将把便条留给任何未来的访客。【参考方案2】:

这是我对该问题的解决方案:

public List<MyClass> getMyClassListByStates(List<String> states) 
    return cache.getCacheByCacheNameList(CacheTypeConstants.MY_CLASS)
            .stream()
            .map((myc) -> (MyClass) myc)
            .filter(myc -> states.contains(myc.getState()))
            .collect(Collectors.toList());

如果有人有其他方法,请随意评论,谢谢。

【讨论】:

如果您希望有人批评您的解决方案,最好将其放在您的问题中,而不是将其作为答案发布 您的states.contains 通话费用很高。去Set,它会更快。就个人而言,我更喜欢演员阵容中的方法参考,所以MyClass.class::cast。此外,对于 Java 16+,您可以直接在流上使用 .toList(),而不再需要 .collect(Collectors.toList())

以上是关于从 java 8 流中的列表中过滤值的主要内容,如果未能解决你的问题,请参考以下文章

Java 8 Stream 按键过滤对象列表。排除列表中的键并获取字符串

使用 Java Stream 根据第二个列表中的值过滤列表

我可以以某种方式从java中的Collections.Min / Collections.Max中排除或过滤掉一个值吗?

使用java 8迭代和过滤两个列表

从 R 中的列表中过滤值

java-8 过滤列表而不创建新列表