2

私はさまざまなNodeTokenおよび他のクラスを持っています。各クラスには独自の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では、クラスを独自の型と比較できるようにするなど、これを行う方法を理解するのに苦労していますか?

4

2 に答える 2

4

ダックタイピングを使用することは、通常、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;
}
于 2012-12-03T19:15:33.357 に答える
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 チェックはここでは冗長であると思われます。これは、キーワードを使用できないstaticfinal、キーワードではないことを前提としているためです。これを行うより効率的な方法は、次のようなものです。

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
}
于 2012-12-03T19:08:04.293 に答える