我应该如何在 Java 中实现字符串到方法的映射?
我在类中有一个 XML 标签列表和每个标签的方法,将该标签作为参数并执行其工作。因此,所有方法都获得相同的输入,我想循环遍历标签列表,每次调用适当的方法。
在Python中,我用字符串(标签名称)的散列到lambdas(self.methodName())来实现它,我想将其转换为Java。
现在在 Java 中,我不能(?)进行这样的哈希,甚至不能在 switch 语句中使用字符串(标记名称)(每个分支调用某个方法)。使用 10 个左右的后续 if 的可能性看起来非常丑陋,我正在寻找一种更好的方法来编码。
I have a list of XML tags and a method for each of them inside my class, getting that tag as an argument and doing its work. So all the methods get the same input and I want to loop through the list of tags, calling appropriate method each time.
In Python I've made it with a hash of strings (names of tags) to lambdas (self.methodName()) and I want to translate it to Java.
Now in Java, I can't (?) make such a hash and even can't use strings (tag names) in a switch statement (with each branch calling a certain method). The possibility of using 10 or so subsequent ifs seems horribly ugly and I'm looking for a better way to code that.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
通过实例化类并将它们保存(可能在散列中)将字符串映射到类实例。当然,所有类都必须实现相同的接口。
您会发现,如果您以这种方式编码,您的代码中就会开始出现更好的结构 - 例如,您可能会发现以前您可能使用 2、3 或 10 个类似的方法来执行略有不同的操作,但现在事实是您可以将数据传递到构造函数中,这样您就可以使用一两个不同的类来完成这一切。
这个接口和实现它的类(至少对我来说)几乎总是演变成我一直需要但可能无法识别的功能齐全的类集。
不知何故,我似乎从不后悔以“困难”的方式编写代码,但当我选择更简单的方式时几乎总是后悔。
Map string to a class instance by instantiating classes and saving them (probably in a hash). All the classes must implement the same interface of course.
You'll find that if you code this way a better structure starts to emerge from your code--for instance you might find that where before you might have used 2, 3 or 10 similar methods to do slightly different things, now the fact that you can pass data into your constructor allows you to do it all with one or two different classes instead.
This interface and the classes that implement it (for me at least) nearly always evolve into a full-featured set of classes that I needed all along but might not have recognized otherwise.
Somehow I never seem to regret writing code the "Hard" way, but nearly always regret when I choose the easier path.
人们对此有何看法?
优点是简洁高效(至少在本例中)。缺点是它不太适合混合大小写标签和带有 Java 非标识符字符的标签;例如“-”。 (您要么必须滥用已接受的枚举成员标识符的 Java 样式约定,要么必须向枚举声明中添加显式的字符串到枚举转换方法。)
在某些人的书中,使用 switch 语句进行调度是邪恶的。但在这种情况下,你需要比较你得到的和你失去的。如果多态调度在可扩展性和可维护性方面比 switch 语句具有显着优势,我会感到惊讶。
What do people think of this?
The upside is that this is concise and efficient (at least in this case). The downside is that it is not so good with mixed case tags and tags with Java non-identifier characters in them; e.g. "-". (You either have to abuse accepted Java style conventions for the enum member identifiers, or you have to add an explicit String-to-enum conversion method to the enum declaration.)
Using a switch statement for dispatching is evil in some peoples' book. But in this case, you need to compare what you are gaining with what you are loosing. And I'd be surprised if polymorphic dispatching would give a significant advantage over a switch statement in terms of extensibility and maintainability.
我会采纳 Bill K 关于实现相同接口的建议。但是,如果您有想要调用不同名称的方法的问题,您可以尝试使用 reflection 并执行以下操作:
I'd go with what Bill K suggested in regards to implementing the same interface. But if you have the issue of wanting to call methods with different names you could try using reflection and do something like this:
您可以使用反射调用该方法:
Class.getMethod
因此您不需要开关或一组 if。
you can invoke the method using reflection:
Class.getMethod
therefore you don't need a switch or a set of ifs.
这是 Bill K 提案的一个例子(如果我没理解错的话)
Here is an example of the proposal of Bill K (if I understood it right)
间接答案:XML 通常表示数据,而不是指令。因此,将解析器处理映射到字段上可能更有用。这就是 JAXB 所做的事情。我建议使用 JAXB 或类似的。
除非您有大量工作要做,否则我强烈建议不要使用静态类型语言进行反射。字符串
} else if (tag.equals("blah")) {
(或者使用实习,} else if (tag == "blah") {
is'你甚至可以将字符串映射到它们的同名枚举上,但这在 JDK7 中应该是有一点反射的。An indirect answer: XML typically represents data, not instructions. So it is probably more useful to map parser handling onto fields. This is what JAXB does. I suggest using JAXB or similar.
Unless you have a huge amount to do, I would strongly advise against reflection in a statically typed language. A string of
} else if (tag.equals("blah")) {
(or with interning,} else if (tag == "blah") {
isn't going to kill you. You can even map strings onto their enum namesakes, but that is a little reflectiony. Switch-on-string should be with us in JDK7.