将HashMap的键和值组合到Set

时间:2016-02-26 07:49:08

标签: java java-8 java-stream

我有一个HashMap<Integer, Integer>,唯一键可能有重复的值。有没有办法将HashMap转换为Set<Integer>,其中包含键和值的唯一整数。

通过迭代keySet()和.values(),这绝对可以在两个循环中完成。我想知道java 8流是否可行。

4 个答案:

答案 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);
    }
}