I have various Node, Token and other classes. Each class has its own Type enum.
I have lists of nodes, and lists of tokens, and lists of other things.
And I often want to see if there are any items of a particular Type in a list.
For example, to see if there are any keywords in a list of tokens, I’d loop over them:
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) {
....
If I write little helpers, I can tidy up my code a lot (as I want to work out what’s in lists a lot):
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;
}
Then, elsewhere, I can:
if((found = any(statement,Token.Type.KEYWORD,"static","final")) != null)
...
Is there any way to generalise this for Node and other variables, and for comparisons that are not strings and where the fields are different, and named differently?
With C++ templates you can duck type; with Java, I’m struggling to see how to do this although making classes comparable to their own types and so on might be a way forward?
Things that you would use duck typing for can usually be accomplished with interfaces in java. Consider this interface:
Then you can change your
anymethod to use only types that implement this interface: