Java: convert obsolete dictionary instance to map

I call a library that, for reasons of API compatibility, returns an instance of type java.util.Dictionary , but I want the instance to execute java.util.Map .

How to easily convert java.util.Dictionary instance to java.util.Map instance?

+4
source share
4 answers

Using Guava and Java 8:

 Iterator<String> keysIter = Iterators.forEnumeration(dict.keys()); Map<String, Object> dictCopy = Maps.toMap(keysIter, dict::get); 
+6
source

Here's how I could program this conversion myself (with the additional assumption that Dictionary has common type arguments).

Add method

 public static <K, V> Map<K, V> addDictionaryToMap(Dictionary<K, V> source, Map<K, V> sink) { for (Enumeration<K> keys = source.keys(); keys.hasMoreElements();) { K key = keys.nextElement(); sink.put(key, source.get(key)); } return sink; } 

and call it, for example, using addDictionaryToMap(dict, new HashMap<String, String>()) .

+2
source

I would prefer to follow the style of public static <K, V> Map<K, V> valueOf(Dictionary<K, V> dictionary) to denote such methods. And I would ask guava guys to add it to Maps .

 public static <K, V> Map<K, V> valueOf(Dictionary<K, V> dictionary) { if (dictionary == null) { return null; } Map<K, V> map = new HashMap<K, V>(dictionary.size()); Enumeration<K> keys = dictionary.keys(); while (keys.hasMoreElements()) { K key = keys.nextElement(); map.put(key, dictionary.get(key)); } return map; } 
+1
source

One interesting way to implement this is with a view approach that allows you to link Dictionary and Map together and are fully functional. As shown in the following code example:

 Dictionary<String, String> dict = new Hashtable<>(); dict.put("PT", "Portugal"); dict.put("CH", "Switzerland"); System.out.println(dict); Map<String, String> map = MapUtils.asMap(dict); System.out.println(map); map.remove("CH"); dict.put("UK", "United Kingdom"); System.out.println(dict); System.out.println(map); map.clear(); System.out.println(dict); System.out.println(map); 

The implementation will be something like this:

 public class MapUtils { public static <K, V> Map<K, V> asMap(Dictionary<K, V> dict) { return new AbstractMap<K, V>() { @Override public Set<Entry<K, V>> entrySet() { return new AbstractSet<Entry<K, V>>() { @Override public Iterator<Entry<K, V>> iterator() { return new Iterator<Entry<K, V>>() { private Enumeration<K> keys = dict.keys(); private Enumeration<V> elements = dict.elements(); private K k = null; @Override public boolean hasNext() { return keys.hasMoreElements(); } @Override public Entry<K, V> next() { k = keys.nextElement(); return new SimpleEntry<>(k, elements.nextElement()); } @Override public void remove() { if (k == null) { throw new IllegalStateException(); } dict.remove(k); k = null; } }; } @Override public int size() { return dict.size(); } }; } @Override public int size() { return dict.size(); } @Override public boolean containsKey(Object key) { return dict.get(key) != null; } @Override public V get(Object key) { return dict.get(key); } @Override public V put(K key, V value) { return dict.put(key, value); } @Override public V remove(Object key) { return dict.remove(key); } }; } } 

Some overridden methods are optional, but I implemented them for performance reasons.

+1
source

Source: https://habr.com/ru/post/1443012/


All Articles