【问题标题】:allMatch, anyMatch on lists without creating streams列表上的 allMatch、anyMatch 而不创建流
【发布时间】:2017-09-19 17:38:05
【问题描述】:

这让我很困扰(出于性能原因),如果不先创建流,我就无法在列表上调用 allMatch、anyMatch。所以我开始创建这样的实用方法:

public static <T> boolean anyMatch(List<T> list, Predicate<T> predicate) {
    for (T element : list) {
        if (predicate.test(element)) {
            return true;
        }
    }
    return false;
}

没有更简单的方法吗?

编辑我不只是担心单个对象的成本。如果您查看 Stream.anyMatch 的源代码,您会发现在这个简单的案例中发生了很多不必要的事情。

【问题讨论】:

  • 嗯,Java8 之前的其他几个库已经解决了这些问题。
  • 当您尝试使用Stream 时会出现哪些性能问题?
  • 所以您没有看到循环创建的Iterator 并且感觉更好?那么,您的目标就没有更简单的解决方案了。
  • 您在胡乱猜测。 Iterator 没有理由比 Stream 优化得更好,两者都是普通的小型 Java 对象。有关 Stream API 的设计决策已在其他地方讨论过。您应该衡量而不是浪费时间创建冗余方法。
  • @Holger 正如我在另一条评论中解释的那样,Stream 可能是单个对象,但显然针对更复杂的使用场景进行了优化,并且做了很多在如此简单的情况下不必要的事情案子。请指导我讨论有关将 anyMatch 包含在列表中的任何讨论 - 我搜索过,但没有找到。

标签: java java-8


【解决方案1】:

您的新方法似乎是个好主意。虽然如果您使用Decorator Pattern 而不是实用程序方法来保持良好的面向对象设计会更好。

public class StreamList<T> {
 List<T> list;
 public StreamList(List list) {
  this.list = list;
 }
 public boolean anyMatch(Predicate<T> predicate) {
    for (T element : list) {
        if (predicate.test(element)) {
            return true;
        }
    }
    return false;
 }
}

【讨论】:

  • 有趣的想法,+1!在这种情况下,您显然是要删除“静态”
  • 构造函数的参数应该是List&lt;T&gt;类型的,而你因为StreamList#anyMatch的某种原因再次定义了T
  • 是的……创建另一个对象,对于担心创建单个对象的性能影响的人来说,这是显而易见的解决方案……
  • @Holger 不,我不只是担心单个对象的成本。如果您查看 Stream.anyMatch 的源代码,您会发现在这个简单的案例中发生了很多不必要的事情
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2022-12-09
  • 1970-01-01
  • 2017-09-04
  • 2019-01-03
  • 1970-01-01
  • 2016-01-13
  • 2018-04-11
相关资源
最近更新 更多