我目前正在努力学习以下练习:
给定
Stream<String>
收集(使用Collector
)所有String
的集合 最大长度。
以下是我的尝试:
private static class MaxStringLenghtCollector
implements Collector<String, List<String>, List<String>> {
@Override
public Supplier<List<String>> supplier() {
return LinkedList::new;
}
@Override
public BiConsumer<List<String>, String> accumulator() {
return (lst, str) -> {
if(lst.isEmpty() || lst.get(0).length() == str.length())
lst.add(str);
else if(lst.get(0).length() < str.length()){
lst.clear();
lst.add(str);
}
};
}
@Override
public BinaryOperator<List<String>> combiner() {
return (lst1, lst2) -> {
lst1.addAll(lst2);
return lst1;
};
}
@Override
public Function<List<String>, List<String>> finisher() {
return Function.identity();
}
@Override
public Set<java.util.stream.Collector.Characteristics> characteristics() {
return EnumSet.of(Characteristics.IDENTITY_FINISH);
}
}
所以我写了我的自定义收藏家来完成这项工作,但......它确实看起来很难看。也许有一些标准的方法来做到这一点。例如,我会尝试分组收集器:
public static Collection<String> allLongest(Stream<String> str){
Map<Integer, List<String>> groups = str.collect(Collectors.groupingBy(String::length));
return groups.get(groups.keySet()
.stream()
.mapToInt(x -> x.intValue())
.max()
.getAsInt());
}
但这既丑陋又效率低下。首先,我们构建一个Map
,然后对其进行搜索以构建Set
,然后遍历它获取最大值 - List
。
答案 0 :(得分:4)
我会这样做:
List<String> values = Arrays.asList("abc", "ab", "bc", "bcd", "a");
// I group by length and put it into a TreeMap then get the max value
values.stream().collect(groupingBy(String::length, TreeMap::new, toList()))
.lastEntry()
.getValue()
.forEach(System.out::println);
<强>输出:强>
abc
bcd