Java HashMap :键是两个 Enum 值的组合。是否有任何内置函数可以检查是否确实是两个枚举的连接

发布于 2025-01-19 07:20:53 字数 588 浏览 0 评论 0 原文

我想在java中创建一个HashMap,其中键是String类型,它是两个枚举的连接。

示例:

枚举1: 公共枚举 Type1{NONE,VALIDATE,CONFIGURE}

Enum2: public enum Type2{A,B,C}

映射声明: 地图<字符串,类> enumClassMap

Ex1: enumClassMap.put(Type2.A.name()+Type1.VALIDATE.name(),Test1.class) 这是有效的,因为键是两个枚举的连接。

示例2:enumClassMap.put(Type2.A.name(),Test1.class) 这个是无效的,因为 key 不是两个枚举的连接。

我想检查 key 是否真的是 Type1 和 Type2 的连接。

我可以编写单独的代码来迭代所有键并进行验证。但我想知道是否有任何内置功能可以做到这一点?我的期望是,如果这不是枚举的组合,java应该默认抛出错误或异常。

I want to create a HashMap in java, where key is String type which is concat of two enums.

Sample:

Enum1:
public enum Type1{NONE,VALIDATE,CONFIGURE}

Enum2:
public enum Type2{A,B,C}

Map declaration:
Map<String, Class<? extends InterfaceTest>> enumClassMap

Ex1: enumClassMap.put(Type2.A.name()+Type1.VALIDATE.name(),Test1.class)
This is valid one, because key is concat of two enums.

Ex2: enumClassMap.put(Type2.A.name(),Test1.class)
This one is invalid, because key is not a concat of two enums.

I want to check whether key is really a concat of Type1 and Type2.

I can write separate code to iterate all the keys and validate. But I want to know is there any inbuilt function to do that? My expectation is, java should throw error or exception by default if this is not a combination of enums.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

会发光的星星闪亮亮i 2025-01-26 07:20:53

当然不是。

但是,原则当然是的。 Java 非常名义上。类型应该准确地描述它们所代表的内容,并且应该尽可能具体。

举个例子:String 非常笼统,根本没有描述“来自类型 com.foo 的枚举名称的串联”的概念。 raghavan.Type1 和 com.foo.raghavan.Type2。

结论:此处的字符串不正确

为了实现具有高度描述性和特定类型名称的理想,您必须创建自己的类型。很多。然后这个问题就解决了!

你的名字太笼统,想不出好名字,而好名字很重要。因此,假设 Type1CardSuit(并且具有 CLUBS、SPADES 等值),Type2CardRank > (使用值 TWOKINGACE 等),那么您可以:

import lombok.Value;
import lombok.NonNull;

@Value
public class Card {
  @NonNull CardSuit suit;
  @NonNull CardRank rank;
}

Map<Card, Class<? extends InterfaceTest>> map;

具有各种优点:

  • 这 无法举例卡片,除非您提供 1 个有效等级和 1 个有效花色。时期。只有一个构造函数可以生成 Card 对象,它要求您传入等级和花色,并且也不接受空值。
  • 如果您有一个键(例如,当您迭代地图的 entrySet() 并调用 .getKey() 时),而不是尝试将该字符串分解回各个组成部分这是相当复杂的,你可以......调用 .getRank().getSuit() 就可以了!那不是很好吗!您现在不需要这个并不重要。。也许你明天需要它)。
  • 现在,该声明读起来更加有用。 地图<字符串,类 enumMap 意味着几乎没有。如果我自己打印出来并参加一个 Java 会议并询问人们这张地图可能会做什么,他们显然根本不知道。即使我也打印出String的API。而如果我向他们展示: Map; ScoreValues;,我还向他们展示了 Card 的 API(即:它有 getRankgetSuit),然后就差不多了每个人都会告诉我:哦,我明白了。这可能是某种纸牌游戏,其中某些纸牌最终会对您的分数做出贡献或类似的东西。换句话说,更接近了。

注意:该片段使用 Project Lombok - 因为如果您使用特定类型(这需要制作大量类型),创建一个实际上“运行良好”的类型(例如,可以用作映射中的键),您需要大量样板文件:getters、构造函数、toString 和 equals/hashCode 方法,这很难做好。您的 IDE 可以生成它,但现在您有大量代码需要维护。龙目岛项目是一种出路。如果您使用的是较新版本的 java,对于像这样的简单情况,public record Card {CardSuitsuit; CardRankrank;} 可以提供帮助,尽管您必须添加自己的空检查代码,并且与 Project Lombok 不同,您无法轻松地为此类事情创建构建器。

免责声明:我是 Project Lombok 的核心贡献者。

Of course not.

But, the principle, of course yes. Java is very nominal. Types should accurately describe what they represent, and should be as specific as they can be.

Case in point: String is very general, and does not at all describe the notion of 'the concatenation of the name of an enum from type com.foo.raghavan.Type1 and com.foo.raghavan.Type2.

Conclusion: String is not correct here.

To achieve this ideal of having highly descriptive and specific type names, you must make your own types. A lot. Then this problem fixes itself!

Your names are too general to come up with good names, and good names are important. So, let's say that Type1 is CardSuit (and has values CLUBS, SPADES, etc), and Type2 is CardRank (with values TWO, KING, ACE, etc), then you'd make:

import lombok.Value;
import lombok.NonNull;

@Value
public class Card {
  @NonNull CardSuit suit;
  @NonNull CardRank rank;
}

Map<Card, Class<? extends InterfaceTest>> map;

This has all sorts of advantages:

  • It is simply impossible to make an instance of Card unless you supply 1 valid rank and 1 valid suit. Period. There is just one constructor that makes Card objects and it demands you pass in a rank and a suit, and won't accept null values either.
  • If you have a key (e.g. when you iterate over the map's entrySet() and call .getKey()), instead of trying to break that string back out into constituent parts which is quite convoluted, you can just.. call .getRank() and .getSuit() on it! Isn't that nice! It doesn't really matter that you don't need this right now. Maybe you need it tomorrow).
  • The statement now reads far more usefully. Map<String, Class<? extends Thingie> enumMap means almost nothing. If I print that out on its own and walk through a java conference and ask people what this map might do they, obviously, have no clue at all. Even if I also print out the API of String. Whereas if I show them: Map<Card, Integer> scoreValues;, and I also show them the API of Card (namely: It has getRank and getSuit), then just about everybody will tell me: Oh, I see. This probably is some sort of card game where certain cards contribute something to your score at the end or some such. Way closer, in other words.

NB: The snippet uses Project Lombok - because whilst java works way better if you use specific types (which requires making lots of types), making a type that actually 'works well' (can be used as keys in maps, for example), you need lots of boilerplate: getters, a constructor, toString, and equals/hashCode methods, which is tricky to do well. Your IDE can generate it but now you have tons of code to maintain. Project Lombok is one way out. If you're on a rather recent version of java, for simple cases such as this, public record Card {CardSuit suit; CardRank rank;} can help, though you'll have to add your own nullchecking code, and unlike Project Lombok you can't easily make builders for such things.

DISCLAIMER: I'm a core contributor to Project Lombok.

混吃等死 2025-01-26 07:20:53

为什么不使用 Map 而不是 Map> 呢?只要您在分组中首先指定 Type1,您就可以通过执行以下操作立即检查它是否是有效的对:

Type1 type1 = <some type one>
if (map.containsKey(type1)) {
   //if true it must contain a type2 mapping.
}

Instead of having a Map<String,...> why not have a Map<Type1, Map<Type2, ...>>? As long as you specify Type1 first in the groupings, you can immediately check if it is a valid pair by doing the following:

Type1 type1 = <some type one>
if (map.containsKey(type1)) {
   //if true it must contain a type2 mapping.
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文