java - 如何使用 Google Guava 创建具有不可变键且无重复项的 map ?

标签 java guava

我想使用 Google Guava 创建一个键/值映射结构,其中键不能修改,但值可以。我还希望能够使用谓词(或类似的东西)来迭代 Map 并仅检索那些具有值的条目。

例如,概念上:

// start
Map data =
{Constants.KEY_NAME_1, Optional.absent()},
{Constants.KEY_NAME_2, Optional.absent()};

// succeeds
data.put(Constants.KEY_NAME_2, Optional.of("new_data"));

// finish
Map data =
{Constants.KEY_NAME_1, Optional.absent()},
{Constants.KEY_NAME_2, Optional("new_data")};

// fails
data.put(Constants.KEY_NAME_3, Optional.of("more_new_data"));

知道如何实现吗?

-------- 解决方案--------

根据下面的评论,我选择了 ForwardingMap。实现很简单

import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ForwardingMap;
import com.google.common.collect.ImmutableList;
import java.util.Map;

Map<String, String> labelMap = ImmutableMap.<String, String> builder()
    .put("KEY_1", "data1")
    .put("KEY_2", "data2")
    .build();

MyCustomMap<String> map = new MyCustomMap(labelMap);

public class MyCustomMap<String> extends ForwardingMap<String, String> {

    private final Map<String, String> delegate;
    private final ImmutableMap<String, String> immutableMap;

    public MyCustomMap(Map<String, String> labelMap) {

        /*
            Check for duplicate values in the map here.  The construction of 
            the ImmutableMap above ensures that there are no duplicate
            keys.  Otherwise it will throw
            "IllegalArgumentException: Multiple entries with same key".
        */

        delegate = labelMap;
        immutableMap = ImmutableMap.<String, String>builder().putAll(delegate).build();
    }

    @Override
    protected Map<String, String> delegate() {
        return immutableMap;
    }
}

最佳答案

如果您的 key 不是不可变的,Guava 将无法为您做任何事情;这是您必须确保自己的事情(通过确保所有键的类都是不可变类)。

即使是 ImmutableMap 也不能避免这种事故:

// Modify the key
victim.keySet().iterator().next().alterMe();

如果您想做的是自定义插入/检索时的行为,那么您可以使用 ForwardingMap包装另一个 Map 实例。

但是请注意,此类给您留下了很多自由,包括违反 Map 契约的自由,您显然应该避免这样做!

关于java - 如何使用 Google Guava 创建具有不可变键且无重复项的 map ?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31592903/

相关文章:

JavaFx : Event Filter on Tab (Tab Pane)

java - 将 HttpServletRequest 和 Response 转储到文件的过滤器

java - 变量未初始化,我不能将 null 用于 boolean 值

java - 部署php项目

java - guava-teSTLib future 版本 JAR

java - Guava 是否提供对定义字符范围的支持?

java - 在哪里可以找到像 Guava 的 greaterThan 这样的基本谓词?

java - Twitter 分享带有文本的图像,toast "Image Could Not Be Loaded"

java - 使用库检查空值比获取 NPE 有何优势?

java - 为什么 Guava 的 MultiMap 的 size 方法返回(非)预期的结果?