Map<Integer, String> map = new TreeMap<>();
map.put(1, "String1");
map.put(2, "String2");
map.put(3, "String3");
I wanted to convert the map's values to set. I know I could easily do
Set<String> set = new HashSet<>(map.values());
While thinking about this, I was curious what is map.values() by itself anyway? So I tried this
System.out.println("Set:"+ (map.values() instanceof Set));
System.out.println("List:"+ (map.values() instanceof List));
System.out.println("Queue:"+ (map.values() instanceof Queue));
System.out.println("SortedSet:"+ (map.values() instanceof SortedSet));
And the output surprisingly was
Set:false
List:false
Queue:false
SortedSet:false
This is all the documentation says.
a collection view of the values contained in this map
I then looked at the decompiled class file.
public Collection<V> values() {
if (values == null) {
values = new AbstractCollection<V>() {
public Iterator<V> iterator() {
return new Iterator<V>() {
private Iterator<Entry<K,V>> i = entrySet().iterator();
public boolean hasNext() {
return i.hasNext();
}
public V next() {
return i.next().getValue();
}
public void remove() {
i.remove();
}
};
}
public int size() {
return AbstractMap.this.size();
}
public boolean isEmpty() {
return AbstractMap.this.isEmpty();
}
public void clear() {
AbstractMap.this.clear();
}
public boolean contains(Object v) {
return AbstractMap.this.containsValue(v);
}
};
}
return values;
}
Why does java return an abstract implementation instead of List/Set/Queue which could be immediately compatible with use cases?