如何使用Java流仅收集长度最大的元素?
我正在尝试使用Java Streams从我的列表中收集所有最长的String
:
List<String> strings = Arrays.asList("long word", "short", "long wwww", "llll wwww", "shr");
List<String> longest = strings.stream()
.sorted(Comparator.comparingInt(String::length).reversed())
.takeWhile(???)
.collect(Collectors.toList());
我希望我的longest
包含{"long word", "long wwww", "llll wwww"}
,因为这些是长度最大的String
。在只有一个长度最大的String
的情况下,我显然希望得到的List
只包含该元素
我试图首先对它们进行排序,以便在第一个元素中显示最大长度,但无法检索流中第一个元素的长度。我可以试试类似peek()
的东西:
static class IntWrapper {
int value;
}
public static void main(String[] args) throws IOException {
List<String> strings = Arrays.asList("long word", "short", "long wwww", "llll wwww", "shr");
IntWrapper wrapper = new IntWrapper();
List<String> longest = strings.stream()
.sorted(Comparator.comparingInt(String::length).reversed())
.peek(s -> {
if (wrapper.value < s.length()) wrapper.value = s.length();
})
.takeWhile(s -> s.length() == wrapper.value)
.collect(Collectors.toList());
System.out.println(longest);
}
但是<丑陋的?我不喜欢引入虚拟包装器(谢谢,实际上是最终的要求)或peek()
hack
有没有更优雅的方法来实现这一点
# 1 楼答案
我不知道你是否觉得它更优雅,但它很简洁:
# 2 楼答案
嗯,我不知道这是否会更优雅,但它应该满足您的要求:
输出:
# 3 楼答案
试试这个:
输出:
# 4 楼答案
您可以认为它更丑陋,但是自定义收集器确实是正确的、更有效的,甚至是并行的: