【发布时间】:2015-12-04 10:43:47
【问题描述】:
假设我们有这个流
Stream.of("a", "b", "err1", "c", "d", "err2", "e", "f", "g", "h", "err3", "i", "j");
我想在地图中保存第一个以“err”开头的相邻字符串对。
我想到的是这样的
Map<String, String> map = new HashMap<>();
Stream.of("a", "b", "err1", "c", "d", "err2", "e", "f", "g", "h", "err3", "i", "j")
.reduce((acc, next) -> {
if (acc.startsWith("err"))
map.put(acc,next);
if (next.startsWith("err"))
return next;
else
return "";
});
但我对它并不完全满意,主要有两个原因
- 我在“滥用”
reduce函数。在 Stream API 中,每个函数都有其明确、明确定义的用途:max应该计算最大值,filter应该根据条件过滤,reduce应该产生增量累加值等等。 - 这样做会阻止我使用 Streams 强大的机制:如果我想将搜索限制在前两个结果中怎么办?
在这里我使用了reduce,因为(据我所知)它是唯一可以让您比较几个值的函数,您可以以某种方式返回类似于“当前值”和“下一个值”概念的东西.
有没有更直接的方法?允许您在每次迭代时考虑多个值来迭代流的东西?
编辑
我正在考虑的是某种机制,在给定当前元素的情况下,它允许您为每次迭代定义要考虑的“元素窗口”。
类似
<R> Stream<R> mapMoreThanOne(
int elementsBeforeCurrent,
int elementsAfterCurrent,
Function<List<? super T>, ? extends R> mapper);
而不是
<R> Stream<R> map(Function<? super T, ? extends R> mapper);
这将是对当前 API 的强大“升级”。
EDIT2
我感谢人们提出解决方案的努力,但问题不在于算法本身。有不同的方法可以通过将流、索引、临时变量放在一起来存储以前的值来实现我的目标......但我想知道 Stream API 中是否有一些方法是为处理当前元素以外的元素而设计的在不打破“流范式”的情况下。像这样的
List<String> list =
Stream.of("a", "b", "err1", "c", "d", "err2", "e", "f", "g", "h", "err3", "i", "j")
.filterFunctionImWonderingIfExist(/*filters couples of elements*/)
.limit(2)
.collect(Collectors.toList());
鉴于答案,我认为没有“清晰快捷”的解决方案,除非使用 StreamEx 库
【问题讨论】:
-
看来你需要一个收藏家
-
我想过,但我找不到(又好又干净的)解决方案
标签: java java-8 java-stream