给定一个字符串列表,是否可以在一行中得到从每个长度到具有该长度的字符串集的映射,并按长度排序?
Given a list of strings, is it feasible to get in one line a map from each length to the set of strings having that length, sorted by length?
我想出了以下方法,它确实有效,但我觉得应该有一种不依赖于“外部”地图的更简洁的单行方式(下面的result
):
public TreeMap<Integer, HashSet<String>> mapLenToString(List<String> strings){
TreeMap<Integer, HashSet<String>> result = new TreeMap<>();
strings.stream()
.forEach(s -> {
int len = s.length();
if (result.containsKey(len)) {
HashSet<String> larger = result.get(len);
larger.add(s);
result.replace(len, larger);
}
else {
HashSet<String> newSet = new HashSet<>();
newSet.add(s);
result.put(len, newSet);
}
});
return result;
}
只需使用 groupingBy
收集器。您可以控制地图类型和元素收集到的集合类型。
TreeMap<Integer, HashSet<String>> result = strs
.stream()
.collect(
Collectors.groupingBy(
s -> s.length(),
TreeMap::new,
Collectors.toCollection(HashSet::new)
)
);
使用这个
List<String> strs = Arrays.asList(
"DEF", "ABC", "Hello world", "z",
"a", "q", "90", "12345678910", "ab");
输出是
{1=[a, q, z], 2=[90, ab], 3=[ABC, DEF], 11=[12345678910, Hello world]}
您也可以使用 Collectors.toSet()
而不是 toCollection(HashSet::new)
,其中默认实现是 HashSet
(但可能不保证如此)
使用 Guava Multimaps 的替代方法:
com.google.common.collect.Multimaps.index(iterable, function)-
Multimap<Integer, String> index =
Multimaps.index(strs, s -> s.length());
不幸的是,它没有按结果排序。
我想出了以下方法,它确实有效,但我觉得应该有一种不依赖于“外部”地图的更简洁的单行方式(下面的result
):
public TreeMap<Integer, HashSet<String>> mapLenToString(List<String> strings){
TreeMap<Integer, HashSet<String>> result = new TreeMap<>();
strings.stream()
.forEach(s -> {
int len = s.length();
if (result.containsKey(len)) {
HashSet<String> larger = result.get(len);
larger.add(s);
result.replace(len, larger);
}
else {
HashSet<String> newSet = new HashSet<>();
newSet.add(s);
result.put(len, newSet);
}
});
return result;
}
只需使用 groupingBy
收集器。您可以控制地图类型和元素收集到的集合类型。
TreeMap<Integer, HashSet<String>> result = strs
.stream()
.collect(
Collectors.groupingBy(
s -> s.length(),
TreeMap::new,
Collectors.toCollection(HashSet::new)
)
);
使用这个
List<String> strs = Arrays.asList(
"DEF", "ABC", "Hello world", "z",
"a", "q", "90", "12345678910", "ab");
输出是
{1=[a, q, z], 2=[90, ab], 3=[ABC, DEF], 11=[12345678910, Hello world]}
您也可以使用 Collectors.toSet()
而不是 toCollection(HashSet::new)
,其中默认实现是 HashSet
(但可能不保证如此)
使用 Guava Multimaps 的替代方法: com.google.common.collect.Multimaps.index(iterable, function)-
Multimap<Integer, String> index =
Multimaps.index(strs, s -> s.length());
不幸的是,它没有按结果排序。