我有各种Node
,Token
和其他类。每个类都有自己的Type
枚举。
我有节点列表,令牌列表和其他内容列表。
我经常想查看列表中是否有特定Type
的项目。
例如,要查看令牌列表中是否有任何关键字,我会循环遍历它们:
Token found = null;
for(Token token: statement)
if(token.type == Token.Type.KEYWORD &&
(token.token.equals("static") ||
(token.token.equals("final")) {
found = token;
break;
}
if(found != null) {
....
如果我写小帮手,我可以整理我的代码(因为我想弄清楚列表中的内容):
Token any(Collection<Token> haystack,Token.Type type,String... needles) {
for(Token straw: haystack)
if(straw.type == type)
for(String needle: needles)
if(needle.equals(straw.token))
return straw;
return null;
}
然后,在其他地方,我可以:
if((found = any(statement,Token.Type.KEYWORD,"static","final")) != null)
...
有没有办法对Node
和其他变量进行概括,对于非字符串的比较和字段不同,命名方式不同?
使用C ++模板,您可以使用鸭子类型;使用Java,我很难看到如何做到这一点,虽然使类可以与他们自己的类型相媲美等等可能是一种前进的方式?
答案 0 :(得分:3)
您将使用duck typing的东西通常可以通过java中的接口来完成。考虑一下这个界面:
public interface Typed<T extends Enum<T>> {
T getType();
String getToken();
}
然后,您可以将any
方法更改为仅使用实现此接口的类型:
public <A extends Enum<A>, B extends Typed<A>> B any(Collection<B> haystack, A type, String... needles) {
for (B straw : haystack)
if (straw.getType().equals(type))
for (String needle : needles)
if (needle.equals(straw.getToken()))
return straw;
return null;
}
答案 1 :(得分:1)
您可以在Java中使用鸭子类型反射,但很可能是
我建议你坚持最简单的写作和理解。
FOUND: {
for(Token token: statement)
if(token.type == Token.Type.KEYWORD &&
(token.token.equals("static") ||
(token.token.equals("final")) {
// handle token here
break FOUND;
}
// handle not found here
}
而不是使用标签,您可以创建方法并在找到匹配项时返回。
我怀疑KEYWORD检查在这里是多余的,因为我假设你不能拥有static
或final
而且它不是关键字。一种更有效的方法就是这样。
static final List<String> KEYWORDS_TO_MATCH = Arrays.asList("static", "final");
FOUND: {
for(Token token: statement)
if(KEYWORDS_TO_MATCH.contains(token.token)) {
// handle token here
break FOUND;
}
// handle not found here
}