Here is my solution. There is enough code to configure it, but after that it is very easy to use.
public class Main { // UnaryOperator and identity are in Java 8. // I include them here in case you are using an earlier version. static interface UnaryOperator<T> { T apply(T t); } static <T> UnaryOperator<T> identity() { return new UnaryOperator<T>() { @Override public T apply(T t) { return t; } }; } // This unary operator turns any List into an ArrayList. static <E> UnaryOperator<List<E>> arrayList(final UnaryOperator<E> op) { return new UnaryOperator<List<E>>() { @Override public List<E> apply(List<E> list) { List<E> temp = new ArrayList<E>(); for (E e : list) temp.add(op.apply(e)); return temp; } }; } // This unary operator turns any Set into a HashSet. static <E> UnaryOperator<Set<E>> hashSet(final UnaryOperator<E> op) { return new UnaryOperator<Set<E>>() { @Override public Set<E> apply(Set<E> set) { Set<E> temp = new HashSet<E>(); for (E e : set) temp.add(op.apply(e)); return temp; } }; } // This unary operator turns any Map into a HashMap. static <K, V> UnaryOperator<Map<K, V>> hashMap(final UnaryOperator<K> op1, final UnaryOperator<V> op2) { return new UnaryOperator<Map<K, V>>() { @Override public Map<K, V> apply(Map<K, V> map) { Map<K, V> temp = new HashMap<K, V>(); for (Map.Entry<K, V> entry : map.entrySet()) temp.put(op1.apply(entry.getKey()), op2.apply(entry.getValue())); return temp; } }; } public static void main(String[] args) { // In this example I will first create an unmodifiable collection of unmodifiable collections. Map<String, List<Set<Integer>>> map = new HashMap<String, List<Set<Integer>>>(); map.put("Example", Collections.unmodifiableList(Arrays.asList(Collections.unmodifiableSet(new HashSet<Integer>(Arrays.asList(1, 2, 3)))))); map = Collections.unmodifiableMap(map); // Now I will make it mutable in one line! map = hashMap(Main.<String>identity(), arrayList(hashSet(Main.<Integer>identity()))).apply(map); } }
source share