我有这个清单(List<String>):
["a", "b", null, "c", null, "d", "e"]
Run Code Online (Sandbox Code Playgroud)
我想要这样的事情:
[["a", "b"], ["c"], ["d", "e"]]
Run Code Online (Sandbox Code Playgroud)
换句话说,我想使用null值作为分隔符将我的列表拆分为子列表,以获取列表列表(List<List<String>>).我在寻找Java 8解决方案.我尝试过,Collectors.partitioningBy但我不确定这是我在寻找什么.谢谢!
我想实现一个Stream<T>.
我不想只使用implements Stream<T>,因为我必须实施大量的方法.
这可以避免吗?
更具体的,我怎么能流t1,t2以及t3例如:
class Foo<T> {
T t1, t2, t3;
Foo(T t1, T t2, T t3) {
this.t1 = t1;
this.t2 = t2;
this.t3 = t3;
}
}
Run Code Online (Sandbox Code Playgroud) 我正在寻找一种方法来实现非终端分组操作,这样内存开销将是最小的.
例如,考虑distinct().在一般情况下,它别无选择,只能收集所有不同的项目,然后才向前流式传输.但是,如果我们知道输入流已经排序,则可以使用最少的内存"在运行中"完成操作.
我知道我可以使用迭代器包装器并自己实现分组逻辑来实现迭代器.是否有更简单的方法来使用流API来实现它?
- 编辑 -
我发现了一种滥用Stream.flatMap(..)来实现此目的的方法:
private static class DedupSeq implements IntFunction<IntStream> {
private Integer prev;
@Override
public IntStream apply(int value) {
IntStream res = (prev != null && value == prev)? IntStream.empty() : IntStream.of(value);
prev = value;
return res;
}
}
Run Code Online (Sandbox Code Playgroud)
然后:
IntStream.of(1,1,3,3,3,4,4,5).flatMap(new DedupSeq()).forEach(System.out::println);
Run Code Online (Sandbox Code Playgroud)
哪个印刷品:
1
3
4
5
Run Code Online (Sandbox Code Playgroud)
通过一些更改,相同的技术可用于任何类型的存储器有效的流序列分组.无论如何,我不太喜欢这个解决方案,而且我正在寻找更自然的东西(比如映射或过滤工作的方式).此外,我在这里违约,因为提供给flatMap(..)的函数是有状态的.
我最近在Java 8中学习了流,并开始使用它们.现在我有一个关于groupingBy收集器方法的问题:
通常我使用.NET的工作,所以我比较(因为他们知道自己是不一样的)的Java Stream<T>与.NET IEnumerable<T>.在此比较之后,List<T>存储元素和特定Stream/ IEnumerable应用操作.一个例子:
C#:
elements.Where(x => x.Value == 5).ToList();
Run Code Online (Sandbox Code Playgroud)
Java的:
elements.stream().filter(x -> x.getValue() == 5).collect(Collectors.toList());
Run Code Online (Sandbox Code Playgroud)
在这两个示例中,我从列表开始,定义操作(在此示例中为过滤器)并收集结果以存储它(在此示例中的新列表中).
现在我得到了一个更复杂的案例:
data.stream()
.map( ... ).filter( ... ) // Some operations
.collect(groupingBy(Chunk::getName, summingLong(Chunk::getValue)));
Run Code Online (Sandbox Code Playgroud)
这个查询的结果是a Map<String, Long>,我可以使用它,但是让我们说,我想继续使用这些数据而不是存储它.我目前的方法很简单:
...
.collect(groupingBy(Chunk::getName, summingLong(Chunk::getValue)))
.entrySet().stream().
.map( ... ) // Do more operations
Run Code Online (Sandbox Code Playgroud)
但是这样,我离开了流,将第一个结果存储在Map中并打开一个新流继续.有没有一种方法可以在没有收藏家的情况下进行分组,这样我就可以"留在"流中?
我有一些大型的文本文件,我想通过对其行进行分组来处理.
我尝试使用新的流媒体功能,比如
return FileUtils.readLines(...)
.parallelStream()
.map(...)
.collect(groupingBy(pair -> pair[0]));
Run Code Online (Sandbox Code Playgroud)
问题是,AFAIK,这会生成一个Map.
是否有任何方法可以像上面那样生成高级代码,例如,条目流?
更新:我正在寻找的是像python的itertools.groupby.我的文件已经排序(通过pair [0]),我只想逐个加载组.
我已经有了一个迭代解决方案.我只是想知道是否有更多的声明方式来做到这一点.顺便说一句,使用番石榴或其他第三方图书馆不会是一个大问题.
我有一段使用传统for循环编写的代码,如下所示.我想重构它以使用java 8流并删除for循环.以下代码的输出应为3,因为这是最长的连续数字列表(4,5和6)
List<Integer> weekDays = Lists.newArrayList(1, 2, 4, 5, 6);
List<Integer> consecutiveIntervals = Lists.newArrayList();
int maxConsecutiveTillNow = 1;
for (int i = 1; i < weekDays.size(); i++) {
if (weekDays.get(i) - weekDays.get(i - 1) == 1) {
maxConsecutiveTillNow++;
} else {
consecutiveIntervals.add(maxConsecutiveTillNow);
maxConsecutiveTillNow = 1;
}
}
consecutiveIntervals.add(maxConsecutiveTillNow);
System.out.println(consecutiveIntervals.stream()
.max(Integer::compareTo)
.get()
);
Run Code Online (Sandbox Code Playgroud)