问题
I have a HashMap<Integer, Integer>
, There can be duplicate values for the unique keys. Is there a way to convert the HashMap to a Set<Integer>
which contains unique Integers of both the keys and values.
This can definitely be done in two loops by iterating over the keySet() and .values(). I'm would like to know whether this is possible in java 8 streams.
回答1:
You can use the stream function to combine both the values and the keys:
Map<Integer, Integer> map = ...
Set<Integer> total = Stream.concat(
map.keySet().stream(),
map.values().stream()
).collect(Collectors.toSet());
This uses the map's keySet().stream()
and values().stream()
to get a stream of both, then connects them using Stream.concat, then finally turns it into a set. The call to .toSet()
prevents duplicate elements, because a set cannot contain duplicate elements.
This trick can also be used if the keys are double, and the values are floats, in this case java will give the greatest common divider class back, what in this case is Number.
回答2:
Calling addAll()
twice is simple as hell and very readable, so that should be your solution. But if you want your curiosity to be satisfied, you can use this stream based solution (less readable, probably less efficient):
Map<Integer, Integer> map = ...;
Set<Integer> result = map.entrySet()
.stream()
.flatMap(e -> Stream.of(e.getKey(), e.getValue()))
.collect(Collectors.toSet());
回答3:
You can just get all keys as a set and then add all values with addAll
Map<Integer, Integer> map = ...
Set<Integer> set = new HashSet<>(map.keySet());
set.addAll(map.values());
If you really really want to use Java 8 streams you can do the following but I don't see how this would be any better:
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));
Or look at all the other solutions but in my opinion a simple addAll
works best here. It should be the most efficient and definetelly the most readable way to do it.
回答4:
You can iterate once over entry set, which will give you all pairs. Whether you do it through streams api or not is irrelevant, because the complexity of this operation remains the same.
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);
}
}
来源:https://stackoverflow.com/questions/35646249/combine-keys-and-values-of-a-hashmap-to-a-set