3

方法があります

<T> void f (Collection<T> c, T t)

残念ながら、 CollectionではなくCollection<P>を最初の引数として渡す必要がある場合があります。ここで、Pは T の前駆体です。つまり、 T返すPゲッターメソッドあります。では、 Collection<P>Collection<T>の両方で動作するようにメソッドを変更するにはどうすればよいでしょうか(後者の場合、getterが ID です)。

例えば、

<T> boolean f (Collection<T> c, T t) {
  for (T x : c) if (x.equals(t)) return true;
  return false;
}
class Z { String a, b; }

fを使用してCollection<Z>aまたはbで検索できるようにしたい:

f(Collection<Z> c1 ???searching by a???, "foo")
f(Collection<Z> c2 ???searching by b???, "bar")

TPの実装を制御することはできません。特に、PをTから継承させることはできません(そして、そうしたくありません: 上記のZのように、異なる時間に異なるフィールドで検索したい場合があります)。

マッピングによって中間Collection<T>を作成したくありません。

私は共通の:key Lisp キーワード引数のようなものが欲しいです。

4

2 に答える 2

2

述語の等価性をチェックするためのインターフェイスのようなものを使用するのはどうですか。例は次のとおりです。

interface Predicate<T> {
     public boolean test(T element);
}

次に、次の関数を使用します。

 public <T> boolean f(Collection<T> c, Predicate<T> p) {
     for (T x : c) if (p.test(x)) return true;
     return false;
 }

次に、次の方法で呼び出すことができます。

Collection<T> ts;
f(ts, new Predicate<T> () { 
            public boolean test(T element) { 
                      return element.equals("foo"); 
            }
 });

Collection<P> ps;
f(ps, new Predicate<P> () { 
            public boolean test(P element) { 
                      return element.getT().equals("foo"); 
            }
});

この構文は非常に冗長ですが、質問に合うはずです。ただし、ラムダ関数が登場すると、Java 8 でよりきれいになります。

于 2012-05-10T19:56:38.533 に答える
-1

「Holder」が前駆体クラスで「Stuff」が取得クラスであるとすると、次のようにできます。
編集: 乱雑な instanceof ステートメントに切り替えます。

public <H, T> boolean contains (Collection<H> c, T t) {
  if (c instanceof Collection<T>)
  {
    for (T x : c) if (x.equals(t)) return true;
    return false;
  }
  //else
  for (H x : c) if (x.getStuff().equals(t)) return true;
  return false;
}
于 2012-05-10T19:42:49.490 に答える