是否有可能将不可变列表作为Java中不可变映射内的值字段?

时间:2014-08-27 08:54:23

标签: java list collections

我有一个返回不可变列表的方法,我想创建一个不可变的映射,其中String为其键,上面的列表作为值返回。这可能吗 ?这个地方有一个有效的例子吗?

3 个答案:

答案 0 :(得分:4)

如果您使用Guava,您可以使用函数在任何Map上构建ImmutableMap

Map<String, List<? extends Foobar> maps = ...;
Maps.transformValues(maps, new Function<List<? extends Foobar>, ImmutableList<? extends Foobar>>() {
  public ImmutableList<? extends Foobar> apply(List<? extends Foobar> list) {
    return ImmutableList.copyOf(list);
  }
});
ImmutableMap.copyOf(maps);

纯Java8:

maps.replaceAll((key, value) -> Collections.unmodifiableList(value);
Map<String, List<? extends Foobar>> unmodifiableMap = Collections.unmodifiableMap(maps);

在纯Java7中(这不会修改输入映射):

Map<String, List<? extends Foobar>> maps = ...;
Map<String, List<? extends Foobar>> copy = ...;
for (Map<String, List<? extends Foobar>> entry : maps.entrySet()) {
  copy.put(entry.getKey(), Collections.unmodifiableList(entry.getValue()));
}
Map<String, List<? extends Foobar>> unmodifiableMap =     Collections.unmodifiableMap(copy);

答案 1 :(得分:4)

这是普通Java中的一个工作示例:

List<String> list = new ArrayList<>();
list.add("Value");

List<String> unmodifiableList = Collections.unmodifiableList(list);

Map<String, List<String>> map = new HashMap<>();
map.put("Key", unmodifiableList);

Map<String, List<String>> unmodifiableMap = Collections.unmodifiableMap(map);

但是,我建议使用Guava的不可变集合来完成这类任务。可以找到文档here。该文档列出了Java的不可修改集合的以下缺点:

  
      
  • 笨拙而冗长;在你想制作防御性副本的任何地方使用都是不愉快的。
  •   
  • unsafe:如果没有人拥有对原始集合的引用,则返回的集合只是真正不可变的
  •   
  • 效率低下:数据结构仍然具有可变集合的所有开销,包括并发修改检查,额外   哈希表中的空格等。
  •   

上面的例子,在Guava中将读作:

ImmutableMap<String, ImmutableList<String>> map = ImmutableMap
            .of("Key", ImmutableList.of("Value"));

答案 2 :(得分:2)

是。使用:

Collections.unmodifiableMap(someMap);

它会返回Map视图,如果有人试图修改地图,它会抛出UnsupportedOperationException