我有一个HashMap<Integer, Integer>
,唯一键可能有重复的值。有没有办法将HashMap转换为Set<Integer>
,其中包含键和值的唯一整数。
通过迭代keySet()和.values(),这绝对可以在两个循环中完成。我想知道java 8流是否可行。
答案 0 :(得分:7)
您可以使用stream函数组合值和键:
Map<Integer, Integer> map = ...
Set<Integer> total = Stream.concat(
map.keySet().stream(),
map.values().stream()
).collect(Collectors.toSet());
这会使用地图的keySet().stream()
和values().stream()
来获取两者的流,然后使用Stream.concat
连接它们,最后将其转换为集合。对.toSet()
的调用可防止重复元素,因为集合不能包含重复元素。
如果键是double,并且值是浮点数,也可以使用此技巧,在这种情况下,java将返回最大的公共分隔符类,在这种情况下是数字。
答案 1 :(得分:4)
调用addAll()
两次很简单,因为地狱而且非常易读,所以这应该是你的解决方案。但如果您希望满足您的好奇心,您可以使用这种基于流的解决方案(可读性较差,可能效率较低):
Map<Integer, Integer> map = ...;
Set<Integer> result = map.entrySet()
.stream()
.flatMap(e -> Stream.of(e.getKey(), e.getValue()))
.collect(Collectors.toSet());
答案 2 :(得分:1)
您可以将所有密钥作为一组获取,然后使用addAll
Map<Integer, Integer> map = ...
Set<Integer> set = new HashSet<>(map.keySet());
set.addAll(map.values());
如果您真的想要使用Java 8流,您可以执行以下操作,但我不知道这会更好:
Map<Integer, Integer> map = ...
Set<Integer> set = new HashSet<>();
map.keySet().stream().forEach(n -> set.add(n));
map.values().stream().forEach(n -> set.add(n));
或者看看所有其他解决方案,但在我看来,一个简单的addAll
在这里效果最好。它应该是最有效和最可读的方式。
答案 3 :(得分:1)
您可以在条目集上迭代一次,这将为您提供所有对。无论你是否通过流API执行它都是无关紧要的,因为这种操作的复杂性保持不变。
public class StreamMapTest {
public static void main(String[] args) {
Map<Integer, Integer> map = new HashMap<Integer, Integer>();
map.put(1, 20);
map.put(2, 20);
map.put(3, 10);
map.put(4, 30);
map.put(5, 20);
map.put(6, 10);
Set<Integer> result = map.entrySet().stream()
.flatMap(e -> Stream.of(e.getKey(), e.getValue()))
.collect(Collectors.toSet());
System.out.println(result);
}
}