发布于2021-07-21 09:19 阅读(1071) 评论(0) 点赞(21) 收藏(5)
在我接触 Java 8 流的过程中,下面的练习阻止了我。
鉴于
IntStream.range(0, 6)
. 产生下面的字符串流:"0, 1" "1, 2" "2, 3" "3, 4" "4, 5"
我想到了使用 Collectors.collectAndThen 将它传递给好的旧列表或数组并循环构建字符串列表,如下所示:
List<String> strgs = new ArrayList<>();
String prev = String.valueOf(nums[0]);
for (int i = 1; i < nums.length; i++) {
strgs.add(prev+", "+String.valueOf(nums[i]));
prev = String.valueOf(nums[i]);
}
但它没有使用流的力量。我觉得 Venkat Subramaniam 说“我之后想洗个澡”。我想知道如何应用函数式技术,这样我就可以在编码后跳过淋浴!
另外,我想避免使用 StreamEx 或 JavaRx 之类的库,我想坚持使用普通的 Java 8 API。
编辑:@Tunaki,感谢您在我的问题中指出不清楚的措辞。它是由 Stream 的两个连续元素组成的对。更具体地说,像 Stream 这样的[1, 3, 5, 7, 9, ...]
将是
"1, 3"
"3, 5"
"5, 7"
...
编辑 2
在对所有答案表示敬意之后,尽管我的问题与 Tunaki 指出的另一个问题重复。我想为 Bohemian 提供的答案扩展社区讨论。尽管有些人不喜欢他的回答,但它提出了一个严重的问题,即具有副作用的 reduce 操作。我对社区的要求是提供一个合理的反有效技术来解决这个问题。因此,我想重用波西米亚式答案如下:
给定输入: nums =new int[]{1,3,5,7,9}
请考虑以下片段:
List<CharSequence> stringList = new ArrayList<>();
IntBinaryOperator reductionWithSideEffect = (int left, int right) -> {
stringList.add(new StringBuilder().append(left).append(", ").append(right));
return right;
};
Arrays.stream(nums)
.reduce(reductionWithSideEffect);
System.out.println(String.join(", ", stringList));
在我看来,解决这个问题的最干净的方法是编写一个自定义拆分器并在其上创建一个 Stream。如果您不需要绝对最大的性能并且不关心并行处理(并行流可以工作,但效率低下),这并不是很难。像这样的事情会起作用:
public static <T, R> Stream<R> pairMap(BaseStream<T, ?> source,
BiFunction<? super T, ? super T, ? extends R> mapper) {
Spliterator<T> spltr = source.spliterator();
long sourceSize = spltr.estimateSize();
Spliterator<R> result = new Spliterators.AbstractSpliterator<R>(
sourceSize > 0 && sourceSize < Long.MAX_VALUE ? sourceSize - 1 : sourceSize,
spltr.characteristics() & (Spliterator.ORDERED | Spliterator.SIZED)) {
T prev;
boolean started;
@Override
public boolean tryAdvance(Consumer<? super R> action) {
if (!started) {
if (!spltr.tryAdvance(t -> prev = t))
return false;
started = true;
}
return spltr.tryAdvance(t -> action.accept(mapper.apply(prev, prev = t)));
}
};
return StreamSupport.stream(result, source.isParallel()).onClose(source::close);
}
这mapper
是基于输入流的一对相邻元素创建新流元素的函数。
用法示例:
pairMap(IntStream.range(0, 6), (a, b) -> a + ", " + b).forEach(System.out::println);
输出:
0, 1
1, 2
2, 3
3, 4
4, 5
作者:黑洞官方问答小能手
链接:http://www.javaheidong.com/blog/article/247967/e28bedeefff2f621fbd0/
来源:java黑洞网
任何形式的转载都请注明出处,如有侵权 一经发现 必将追究其法律责任
昵称:
评论内容:(最多支持255个字符)
---无人问津也好,技不如人也罢,你都要试着安静下来,去做自己该做的事,而不是让内心的烦躁、焦虑,坏掉你本来就不多的热情和定力
Copyright © 2018-2021 java黑洞网 All Rights Reserved 版权所有,并保留所有权利。京ICP备18063182号-2
投诉与举报,广告合作请联系vgs_info@163.com或QQ3083709327
免责声明:网站文章均由用户上传,仅供读者学习交流使用,禁止用做商业用途。若文章涉及色情,反动,侵权等违法信息,请向我们举报,一经核实我们会立即删除!