繁体   English   中英

Java - 将 map(key, set) 中的不可修改集转换为可修改集

[英]Java - convert unmodifiable sets in a map(key, set) to modifaible

我实现了一个返回Map<key,Set<objects>>的 function ,当我调用这个 function 时,它返回类型为不可修改的集合。

我需要对这个集合做一些操作,如何在最佳实践中将它们转换为可修改的集合? 否则我得到

Exception in thread "main" java.lang.UnsupportedOperationException

提前致谢。

假设Map本身是可变的,你使用类似

map.replaceAll((key, set) -> new HashSet<>(set));

例子:

Map<Integer,Set<Object>> map = new HashMap<>();
map.put(5, Collections.emptySet());
map.put(10, Collections.singleton("foo"));

map.replaceAll((key, set) -> new HashSet<>(set));

map.get(5).add(42);
map.get(10).add("bar");

map.entrySet().forEach(System.out::println);
5=[42]
10=[bar, foo]

当然,您也可以将new HashSet<>(set)替换为new TreeSet<>(set)或通常遵循复制构造函数约定的每个Set实现类型。 当您不能使用复制构造函数时,您必须求助于addAll ,例如

map.replaceAll((key, set) -> {
    TreeSet<Object> newSet = new TreeSet<>(Comparator.comparing(Object::toString));
    newSet.addAll(set);
    return newSet;
});

还有另一种选择。 与其转换 map 的所有值,不如仅按需转换集合,即当您实际想要修改它们但结果却没有预期的类型时:

Map<Integer,Set<Object>> map = new HashMap<>();
map.put(5, Collections.emptySet());
map.put(10, Collections.singleton("foo"));

map.computeIfPresent(5, (key,set)->set instanceof HashSet? set: new HashSet<>()).add(42);
map.computeIfPresent(10, (key,set)->set instanceof HashSet?set:new HashSet<>()).add("bar");

map.entrySet().forEach(System.out::println);

您可以将 原始集复制到另一个可以修改的集。

像这样的东西:

Set<YourType> newSet = unmodifiableSet
                        .stream()
                        .collect(Collectors.toSet());
// Or maybe...
Set<YourTYpe> otherSet = new HashSet<>();
otherSet.addAll(unmodifiableSet);

然后,您可以毫无问题地修改新列表,并将其重新分配到 map。

只需使用复制构造函数

对于HashSet

Set<Type> modifiable = new HashSet<>(unmodifiable);

对于TreeSet

SortedSet<Type> modifiable = new TreeSet<>(unmodifiable);

对于LinkedHashSet

Set<Type> modifiable = new LinkedHashSet<>(unmodifiable);

如果您使用没有此类构造函数的精美 Set 实现:

Set<Type> modifiable = new MyFancySet<>();
modifiable.addAll(unmodifiable);

您可以使用Streams执行此操作:

map是您原来的 map (例如Map<Integer, ImmutableSet<Object>> map;

Map<Integer, Set<Object>> mutableMap = map.entrySet()
                .stream()
                .collect(Collectors.toMap(Map.Entry::getKey, Sets::newHashSet));

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM