【问题标题】:How to store complex data structures in Enum java? [duplicate]如何在 Enum java 中存储复杂的数据结构? [复制]
【发布时间】:2021-10-15 21:11:24
【问题描述】:

我需要创建 Enum 类进行身份验证。每个枚举都需要存储一个 Map。所以,我知道如何创建一个 Enum,但是将值设置为 map 和 set 似乎很奇怪。也许你有想法,如何做得更好?我的代码:

public enum Auth{
  NO_AUTH(new HashMap<>()),
  Auth(new HashMap<>());
  private Map<String,Set<String>> fields;

  private Auth(Map<String,Set<String>> fields){
    this.fields = fields;
  }
}

我想填满我的地图,像这样:

NO_AUTH(new HashMap<String>().put(1,new HashSet<String>().add("2"));

【问题讨论】:

  • 你希望那些是可变的吗?在这种情况下:不要。 enum 值应该绝对是不可变的。你可以采取不同的方式,但这是一个非常糟糕的主意。
  • 我不想要可变数据。只需存储和阅读。
  • 您当前的代码有什么问题?您在向地图添加多个值时遇到问题吗?还是您只是想要一种更清洁的方式?
  • 我只是想要一个更干净的方式来做到这一点
  • 这实际上只是“如何使用流畅的界面创建地图/设置?”变相。您的代码可以很好地传递 Map.of(1, Set.of(2)) 作为参数。问题是 HashMap 和 HashSet 上的 putadd 返回错误的类型。它们不是为流畅使用而设计的。

标签: java


【解决方案1】:

您只需要一些可让您在线构建地图和设置的构建器。

Java 9 added some:

public enum Auth{
    NO_AUTH(Map.of("1", Set.of("2"))),
    Auth(Map.of("2", Set.of("3")));
    
    private Map<String, Set<String>> fields;

    Auth(Map<String, Set<String>> fields){
        this.fields = fields;
    }
}

在各种图书馆中可能还有其他人。在您无法访问任何 Map/Set 构建器的最坏情况下,您可以在 ctor 中切换身份:

public enum Auth {
    NO_AUTH,
    AUTH;

    private final Map<String, Set<String>> fields = new HashMap<>();

    Auth(){
        Map<String, Set<String>> tmp = new HashMap<>();
        switch (this) {
            case NO_AUTH:
                tmp.put("1", Collections.singleton("2"));
                break;
            case AUTH:
                tmp.put("2", Collections.singleton("3"));
                break;
            default:
                throw new RuntimeException("Missing case for " + this);
        }
        this.fields = Collections.unmodifiableMap(tmp);
    }
}

【讨论】:

  • 我强烈建议使用 Collection.unmodifiableMap 以避免在前 9 版本的代码中返回的 Map 发生突变。
  • 我想我会编写地图/设置构建器而不是选择此开关:/
  • @JoachimSauer 在大多数情况下,我会在地图的吸气剂内将包装器放在地图周围。当然,它创建包装器的次数超过了严格必要的次数,但在 95% 的情况下,这无关紧要。我能想到的使用 unmodifiableMap 实例化字段的所有方法都有些繁琐
  • 在切换之前我会做Map&lt;String, Set&lt;String&gt;&gt; content。分配给它并在构造函数的末尾有this.fields = Collections.umodifiableMap(content)。我猜这是否过于繁琐,取决于个人品味。我只是想保证没有任何东西可以修改我的地图,即使是意外地不让不受保护的引用留在周围。但我猜 Java 9 完全避免了这个问题。
  • @JoachimSauer 是的,实际上想想,这并不可怕。这仍然不是我个人的做法——我相信自己会记得在 getter 中添加到包装器中。但是,由于某些人可能会复制粘贴到他们的项目中,而我不能相信他们会这样做,所以你的方式更好。
猜你喜欢
  • 1970-01-01
  • 2020-02-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-09-11
  • 1970-01-01
相关资源
最近更新 更多