我有一个包含N个hastst表的哈希表:
Map<Integer,Map<String,Double>
我需要创建一个包含内部地图所有键的列表:
----------------
| | a 2 |
| 100 | b 1 |
| | c 2 |
----------------
| | a 2 |
| 101 | d 2 |
----------------
| | a 2 |
| 102 | b 1 |
| | e 2 |
----------------
list = {a,b,c,d,e}
这是我目前的代码:
Set<String> keys= new HashSet<>();
map1.entrySet().forEach(e -> {
keys.addAll(e.getValue().keySet());
});
map1包含数千个条目。
这是最佳方法吗?谁知道更快的方式?
答案 0 :(得分:3)
您可以尝试使用以下代码:
Map<String, Double> innerMap = new HashMap<>();
innerMap.put("a", 2d);
innerMap.put("b", 2d);
innerMap.put("c", 2d);
Map<String, Double> innerMap2 = new HashMap<>();
innerMap2.put("a", 2d);
innerMap2.put("d", 2d);
innerMap2.put("e", 2d);
Map<Integer, Map<String, Double>> map = new HashMap<>();
map.put(100, innerMap);
map.put(101, innerMap2);
Set<String> collect = map.values()
.stream()
.parallel()
.map(Map::keySet)
.flatMap(Collection::stream)
.collect(Collectors.toSet());
不幸的是,如果它对性能产生重大影响,您将不得不自己尝试。
这意味着您使用的是 Java 8 。但是当你使用方法forEach()
时我就是这么认为的。
答案 1 :(得分:1)
我认为您可以使用flatMap()
如果您可以估算所需的尺寸,也可以考虑使用ConcurrentHashMap,即Collections.newSetFromMap(new ConcurrentHashMap())
示例:
final int EST_SIZE = 6_000_000;
// Map<Integer,Map<String,Double>> map1;
Set<String> keys = map1.values().stream().map(Map::keySet)
.flatMap(Set::stream).parallel().unordered()
.collect(Collector.of(
() -> Collections.newSetFromMap(
new ConcurrentHashMap<>(EST_SIZE * 4 / 3 + 1)
),
Set::add,
(set1,set2) -> {
set1.addAll(set2);
return set1;
},
Collector.Characteristics.CONCURRENT,
Collector.Characteristics.UNORDERED
));
注意:上述代码是针对高度专业化方案的尝试优化。在决定之前测试并检查性能。在一般情况下,你应该喜欢这样的东西:
Set<String> keys = map1.values().stream().map(Map::keySet)
.flatMap(Set::stream).collect(Collectors.toSet());
答案 2 :(得分:1)
基本上,您的方法对于通用案例是最佳的。你当然可以定制它,如果你对Map结构,密钥分配等有额外的限制。但对于一般情况,我没有看到更好的方法,也许是其他语法(例如,一直使用流:< / p>
map.entrySet().stream().map(Map.Entry::getValue).flatMap(e -> e.keySet().stream()).collect(Collectors.toSet())
)