There is a method in the Collections class.
Set<E> Collections.newSetFromMap(<backing map>)
What does it mean by the backing map and the set backed by a map?
You should strive to use immutable types as keys for Map s. Collections and sets are generally very easily mutable so usually are a bad idea to use this way. If you want to use many key values as a Map key you should use a class implementation designed for that purpose, like Apache Commons Collections MultiKey .
To convert, Java Map to Set , we can use the conventional constructor with HashSet , however, there are few things to consider before we proceed with the conversion.
a) The values can be stored in a map by forming a key-value pair. The value can be retrieved using the key by passing it to the correct method. b) If no element exists in the Map, it will throw a 'NoSuchElementException'. c) HashMap stores only object references.
Perhaps it would be illuminating to look at the implementation:
private static class SetFromMap<E> extends AbstractSet<E>
implements Set<E>, Serializable
{
private final Map<E, Boolean> m; // The backing map
private transient Set<E> s; // Its keySet
SetFromMap(Map<E, Boolean> map) {
if (!map.isEmpty())
throw new IllegalArgumentException("Map is non-empty");
m = map;
s = map.keySet();
}
public void clear() { m.clear(); }
public int size() { return m.size(); }
public boolean isEmpty() { return m.isEmpty(); }
public boolean contains(Object o) { return m.containsKey(o); }
public boolean remove(Object o) { return m.remove(o) != null; }
public boolean add(E e) { return m.put(e, Boolean.TRUE) == null; }
public Iterator<E> iterator() { return s.iterator(); }
public Object[] toArray() { return s.toArray(); }
public <T> T[] toArray(T[] a) { return s.toArray(a); }
public String toString() { return s.toString(); }
public int hashCode() { return s.hashCode(); }
public boolean equals(Object o) { return o == this || s.equals(o); }
public boolean containsAll(Collection<?> c) {return s.containsAll(c);}
public boolean removeAll(Collection<?> c) {return s.removeAll(c);}
public boolean retainAll(Collection<?> c) {return s.retainAll(c);}
// addAll is the only inherited implementation
private static final long serialVersionUID = 2454657854757543876L;
private void readObject(java.io.ObjectInputStream stream)
throws IOException, ClassNotFoundException
{
stream.defaultReadObject();
s = m.keySet();
}
}
Edit - added explanation:
The map that you provide is used as the m
field in this object.
When you add an element e
to the set, it adds an entry e -> true
to the map.
public boolean add(E e) { return m.put(e, Boolean.TRUE) == null; }
So this class turns your Map
into an object that behaves like a Set
by simply ignoring the values that things are mapped to, and just using the keys.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With