【发布时间】:2019-10-25 01:15:58
【问题描述】:
关于 java 方法是否应该返回 Collections or Streams 的问题是,Brian Goetz 在其中回答即使对于有限序列,通常也应该首选 Streams。
但在我看来,目前对来自其他地方的 Streams 的许多操作无法安全执行,并且无法进行防御性代码保护,因为 Streams 不会显示它们是无限的还是无序的。
如果并行是我想在 Stream() 上执行的操作的问题,我可以调用 isParallel() 来检查或顺序以确保计算是并行的(如果我记得的话)。
但如果有序性或有限性(大小)与我的程序的安全性有关,我就无法编写保护措施。
假设我使用了一个实现这个虚构接口的库:
public interface CoordinateServer {
public Stream<Integer> coordinates();
// example implementations:
// finite, ordered, sequential
// IntStream.range(0, 100).boxed()
// final AtomicInteger atomic = new AtomicInteger();
// // infinite, unordered, sequential
// Stream.generate(() -> atomic2.incrementAndGet())
// infinite, unordered, parallel
// Stream.generate(() -> atomic2.incrementAndGet()).parallel()
// finite, ordered, sequential, should-be-closed
// Files.lines(Path.path("coordinates.txt")).map(Integer::parseInt)
}
那么我可以在这个流上安全地调用哪些操作来编写正确的算法?
似乎如果我想将元素写入文件作为副作用,我需要关注流是并行的:
// if stream is parallel, which order will be written to file?
coordinates().peek(i -> {writeToFile(i)}).count();
// how should I remember to always add sequential() in such cases?
如果是并行的,基于什么线程池是并行的?
如果我想对流进行排序(或其他非短路操作),我需要小心它是无限的:
coordinates().sorted().limit(1000).collect(toList()); // will this terminate?
coordinates().allMatch(x -> x > 0); // will this terminate?
我可以在排序之前施加一个限制,但是如果我期望一个未知大小的有限流,那应该是哪个幻数?
最后也许我想并行计算以节省时间然后收集结果:
// will result list maintain the same order as sequential?
coordinates().map(i -> complexLookup(i)).parallel().collect(toList());
但是如果流没有被排序(在那个版本的库中),那么结果可能会由于并行处理而变得混乱。但是,除了不使用并行(这违背了性能目的)之外,我该如何防范呢?
集合明确表示有限或无限,是否有顺序,并且它们不携带处理模式或线程池。这些似乎是 API 的宝贵属性。
另外,Streams may sometimes need to be closed,但大多数情况下不是。如果我从一个方法(来自一个方法参数)消费一个流,我通常应该调用 close 吗?
另外,流可能已经被消费了,能够优雅地处理这种情况会很好,所以check if the stream has already been consumed会很好;
我希望有一些代码 sn-p 可用于在处理流之前验证有关流的假设,例如>
Stream<X> stream = fooLibrary.getStream();
Stream<X> safeStream = StreamPreconditions(
stream,
/*maxThreshold or elements before IllegalArgumentException*/
10_000,
/* fail with IllegalArgumentException if not ordered */
true
)
【问题讨论】:
-
我猜很多“这取决于”。会等待像霍尔格这样的人来回答这个问题,如果不是被认为是广泛的。
-
我认为你可以使用流特征 - 检查this问题了解更多详情。
-
谢谢,我不知道拆分器的特性。它们看起来仍然不像在应用程序编程中使用的东西(更像是 Stream 的实现细节)。
-
也许这回答了你的一些问题baeldung.com/java-stream-ordering
-
正如 Brian 在您发布的答案中所说的那样,“您必须返回 Collection 的一种情况是存在强一致性要求时”。要求它是有限的就是其中之一。
标签: java java-stream