0

我想出了以下方法,它确实有效,但我觉得应该有一种更干净的单线方式,它不依赖于“外部”地图(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;
}
4

2 回答 2

3

使用 Guava Multimaps 的替代方法: com.google.common.collect.Multimaps.index(iterable, function) -

Multimap<Integer, String> index =
       Multimaps.index(strs,  s -> s.length());

不幸的是,它没有按结果排序。

于 2020-07-08T15:59:16.567 回答
3

只需使用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]}

链接到 repl.it


您也可以使用Collectors.toSet()而不是toCollection(HashSet::new),默认实现是HashSet(但可能不保证是这样)

于 2020-07-08T15:48:32.167 回答