Java HashMap :键是两个 Enum 值的组合。是否有任何内置函数可以检查是否确实是两个枚举的连接
我想在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应该默认抛出错误或异常。
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
当然不是。
但是,原则当然是的。 Java 非常名义上。类型应该准确地描述它们所代表的内容,并且应该尽可能具体。
举个例子:
String
非常笼统,根本没有描述“来自类型com.foo 的枚举名称的串联”的概念。 raghavan.Type1 和 com.foo.raghavan.Type2。
结论:此处的字符串不正确。
为了实现具有高度描述性和特定类型名称的理想,您必须创建自己的类型。很多。然后这个问题就解决了!
你的名字太笼统,想不出好名字,而好名字很重要。因此,假设
Type1
是CardSuit
(并且具有 CLUBS、SPADES 等值),Type2
是CardRank
> (使用值TWO
、KING
、ACE
等),那么您可以:具有各种优点:
卡片
,除非您提供 1 个有效等级和 1 个有效花色。时期。只有一个构造函数可以生成 Card 对象,它要求您传入等级和花色,并且也不接受空值。entrySet()
并调用.getKey()
时),而不是尝试将该字符串分解回各个组成部分这是相当复杂的,你可以......调用.getRank()
和.getSuit()
就可以了!那不是很好吗!您现在不需要这个并不重要。。也许你明天需要它)。地图<字符串,类 enumMap
意味着几乎没有。如果我自己打印出来并参加一个 Java 会议并询问人们这张地图可能会做什么,他们显然根本不知道。即使我也打印出String
的API。而如果我向他们展示:Map; ScoreValues;
,我还向他们展示了Card
的 API(即:它有getRank
和getSuit
),然后就差不多了每个人都会告诉我:哦,我明白了。这可能是某种纸牌游戏,其中某些纸牌最终会对您的分数做出贡献或类似的东西。换句话说,更接近了。注意:该片段使用 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 typecom.foo.raghavan.Type1
andcom.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
isCardSuit
(and has values CLUBS, SPADES, etc), andType2
isCardRank
(with valuesTWO
,KING
,ACE
, etc), then you'd make:This has all sorts of advantages:
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.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).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 ofString
. Whereas if I show them:Map<Card, Integer> scoreValues;
, and I also show them the API ofCard
(namely: It hasgetRank
andgetSuit
), 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.
为什么不使用
Map
而不是Map>
呢?只要您在分组中首先指定Type1
,您就可以通过执行以下操作立即检查它是否是有效的对:Instead of having a
Map<String,...>
why not have aMap<Type1, Map<Type2, ...>>
? As long as you specifyType1
first in the groupings, you can immediately check if it is a valid pair by doing the following: