【问题标题】:How do I make a Map<String, List<String> unmodifiable? [duplicate]如何使 Map<String, List<String> 不可修改? [复制]
【发布时间】:2013-09-30 13:45:42
【问题描述】:

java.util.Collections 类允许我使集合实例不可修改。下面的方法

protected Map<String, List<String>> getCacheData() {
    return Collections.unmodifiableMap(tableColumnCache);
}

返回一个不可修改的Map,因此UnsupportedOperationException 是由尝试更改地图实例引起的。

@Test(expected = UnsupportedOperationException.class)
public void checkGetCacheData_Unmodifiable() {
    Map<String, List<String>> cacheData = cache.getCacheData();
    cacheData.remove("SomeItem");
}

不幸的是,所有List&lt;String&gt; 孩子都不是不可修改的。所以我想知道是否有办法对子值List&lt;String&gt; 强制执行不可修改的行为?

当然,或者我可以遍历映射键值对,使列表不可修改并重新组合映射。

【问题讨论】:

  • 使用最终访问修饰符
  • @Ashokkuttuva 不正确,final 阻止您创建对象的新实例,如果列表已成为 final,您仍然可以修改列表的内容。
  • @Ashokkuttuva final ---> 分配。不是内容。喜欢阅读stackoverflow.com/questions/19049697/…
  • @OP 我猜默认是不可能的。自己写一篇,根据自己的需要。 stackoverflow.com/questions/16356232/unmodifiable-list-in-java
  • 地图对列表如何处理它们的数据没有影响,所以事实上,你唯一能做的就是为不可修改的列表创建一个不可修改的地图。

标签: java collections map unmodifiable


【解决方案1】:

您需要一个包含 ImmutableList 实例的 ImmutableMap。使用Guava 保持理智。

首先,创建您需要的 ImmutableList 实例:

ImmutableList<String> list1 = ImmutableList.of(string1, string2, etc);
ImmutableList<String> list2 = ImmutableList.of(string1, string2, etc);

然后创建你的 ImmutableMap:

ImmutableMap<String,List<String>> map = ImmutableMap.of("list1", list1, "list2", list2);

有许多方法可以实例化不可变列表和映射,包括构建器模式。查看ImmutableListImmutableMap 的JavaDocs 了解更多详情。

【讨论】:

    【解决方案2】:

    不幸的是,您需要将每个列表包装为不可修改的List。这可以通过使用java.util.Collections.unmodifiableList(...) 来完成。如果您可以控制Lists 的创建,那么您可以(并且应该)在设置值后立即执行此操作。如果您无法控制这些集合的创建,那么您可能需要重新考虑使其不可修改,因为您不知道的其他一些代码可能依赖于该行为。希望对您有所帮助。

    【讨论】:

      【解决方案3】:

      也许这不是您所需要的,但我建议使用 Guava immutable list multimap

      【讨论】:

      • A ListMultiMap 与 Map> 不同
      • @JasonNichols 请告诉我为什么我可以使用 Map> 而不是 ListMultiMap
      • ImmutableListMultiMap 只是 MultiMap 的不可变实现,它允许在单个映射中使用多个键,这与 Map 不同。我会发布一些代码
      【解决方案4】:

      子类 Map 返回不可修改的列表。

      【讨论】:

      • 当您可以使用现成的 ImmutableList 和 ImmutableMap 实例时,为什么要这样做?
      • 他正在创建一个带有可修改列表的地图。当他从地图中拉出时,他想确保列表是不可修改的。原始列表是可修改的。
      • 我喜欢这个解决方案,因为我不依赖第三方库。如果解决方案可以通过几行额外的源代码轻松完成,我更喜欢这个解决方案。 private class CacheMap extends Hashtable&lt;String, List&lt;String&gt;&gt; { @Override public List&lt;String&gt; get(Object key) { List&lt;String&gt; cacheData = super.get(key); return Collections.unmodifiableList(cacheData); } }
      • 我不知道他为什么不想使用番石榴。也许他不想依赖第三方库和所有这些临时依赖项来解决一个他可以自己管理的简单问题。这是他决定采用的解决方案。也可能有人问,“Java 提供了 API 中不可修改的列表,为什么还要使用 Guava?”
      • @My-Name-Is:地图上的其他方法仍将返回原始列表,例如iterator(),以及values() 视图。
      猜你喜欢
      • 1970-01-01
      • 2015-06-15
      • 2020-08-01
      • 2020-07-10
      • 1970-01-01
      • 2020-03-17
      • 2018-09-22
      • 2020-01-26
      • 1970-01-01
      相关资源
      最近更新 更多