问题 使用流或循环之间的决定


通过在Java中编写应用程序,有许多用例 java.util.Collection。 以来 java.util.stream.Stream 随着Java 8的推出,我遇到了一些很难决定使用什么的用例。

例如: 您将编写一些util-methods。

public static List<?> filterHashToList(int hash, Collection<?> toFilter) {
    return toFilter.stream()
        .filter((Object o) -> hash == o.hashCode())
        .collect(Collectors.toCollection(LinkedList::new));
}

怎么样这样写:

public static List<?> filterHashToList(int hash, Collection<?> toFilter) {
    List<Object> result = new LinkedList<>();

    for(Object o : toFilter) {
        if(hash == o.hashCode()) {
            result.add(o);
        }
    }

    return result;
}

两种方法都会产生相同的结果。 java.util.stream.Stream 和 java.util.stream.Collector 是接口,因此如果我使用自定义流和收集器,实现也会有所不同。

我认为有很多实现使用旧的fashoined循环方式。

那么,是否有可能通过用例回答使用,流或循环的内容? 如果是这样,是否必须在适当的时候更新所有实施?

或者我应该通过实现util-methods提供两种方式? 或者我是否应该在过滤过程之后提供一个返回流的mthed,以便在需要时也可以使用该流?


7748
2017-09-19 16:02


起源

我会使用两个简单的规则:1。如果没有破坏,请不要修复它。 2.使用您认为最易读和可维护的内容。也就是说,你的两个例子不会返回相同的东西:一个返回一个ArrayList,另一个返回一个LinkedList。 - JB Nizet
无论是流还是循环都没有什么神奇之处。您应该编写最易读,清晰且可维护的代码。这些都是可以接受的。 (注意,如果LinkedList真的是你想要的,你可能想在第一个例子中使用toCollection(LinkedList :: New)。) - Brian Goetz
@JBNizet同意,除了你不能指望toList()返回一个ArrayList。它返回一个List - 这就是你所知道的。 - Brian Goetz
@BrianGoetz同意了。请告诉我你实际上不打算在将来返回LinkedList :-) - JB Nizet
@JBNizet说了一切:如果有效,请不要修理它。但是,出于好奇,为什么一个LinkedList呢?由于您返回了List,因此无论如何都无法访问任何特定于LinkedList的方法,并且ArrayList作为一个整体表现更好...... - fge


答案:


请注意,在您的实现中,您坚持使用特定的结果集合类型 LinkedList 与...相比通常性能非常差 ArrayList。如果您的方法的用户想要以随机访问方式使用结果列表,该怎么办?可能此方法的用户需要一个数组,因为它应该传递给另一个接受数组的API方法。有时,用户只需要知道输入集合中存在多少具有给定hashCode的对象,因此根本不需要创建结果列表。 Java-8方法是从方法返回流,而不是集合,让调用者决定如何收集它:

public static <T> Stream<T> filterHashToList(int hash, Collection<T> toFilter) {
    return toFilter.stream()
        .filter(o -> hash == o.hashCode());
}

并使用它:

filterHashToList(42, input).count();

要么

filterHashToList(42, input).collect(toCollection(ArrayList::new));

要么

filterHashToList(42, input).toArray();

这种方法变得非常简单,所以你可能根本不需要它,但是如果你想做更多的软化过滤/转换,那就没关系。

因此,如果您不想更改API并仍然返回 LinkedList,没有必要改变实施。但是,如果您想利用Stream API,最好将返回类型更改为 Stream


5
2017-09-20 02:34





如果没有公布的答案,我会引用 Brian Goetz 谁回应我的情绪,我怀疑很多其他人。

无论是流还是循环都没有什么神奇之处。您应该编写最易读,清晰且可维护的代码。这些都是可以接受的。


8
2017-09-20 02:49





我认为这在很大程度上取决于预期的收藏规模和该计划的实际应用。前者稍微高效一点,但我发现它的可读性较差,仍有系统在Java 7(即Google App Engine)上运行。此外,后者可能更容易为未来添加更复杂的过滤器。但是,如果效率是主要关注点,我会选择前者。


0