从不可变的集合创建可变集合

时间:2014-12-26 01:08:36

标签: java guava

我们说我有以下使用Guava的库创建的Map :( List<Integer>也是不可变的)

Map<String, List<Integer>> map = ImmutableMap.builder()...

我将此映射传递给一个类,我想在其中创建一个可变副本并对其进行修改。当然可以手动完成,但有没有办法将嵌套的不可变集合转换回可变集合?

2 个答案:

答案 0 :(得分:2)

正如所指出的,我使用的是ImmutableListMultimap<String, Integer>而不是ImmutableMap<String, ImmutableList<Integer>>

然后,如果你想要一个可变副本,你可以在一个可变的create实现(ListMultimapArrayListMultimap上将不可变多图传递给LinkedListMultimap静态工厂方法。 })。

答案 1 :(得分:1)

这是我的解决方案。设置它需要相当多的代码,但一旦完成它就非常容易使用。

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);
    }
}