3

以下の関数を、再利用できるジェネリック関数に作成することはできますか?

コレクションを渡し、オブジェクト内の特定のプロパティのリストを返したい。

これまでの例で私はこれを持っています:

   private List<Integer> getPropertyABCIdsFromSomeObject(List<SomeObject> someObjects) {
        List<Integer> ids = new ArrayList<Integer>();
        for(SomeObject so : someObjects) {
            ids.add(so.getPropertyABCId());
        }
        return ids;
    }

したがって、このメソッドはタイプSomeObjectに対してのみ機能し、PropertyABCIdのリストを返します。

他のプロパティのリストが必要な場合は、ほとんど変更を加えずにこの関数を複製する必要があります。

ジェネリックはここでその日を救うことができますか?

4

2 に答える 2

3

インターフェースが必要ですが、そうです:

interface HasProperty<T> {
    T getProperty();
}

public static <T> List<T> getProperties(List<? extends HasProperty<T>> items) {
    List<T> properties = new ArrayList<T>();
    for (HasProperty<T> item : items) {
        properties.add(item.getProperty());
    }
    return properties;
}
于 2012-11-18T19:39:49.627 に答える
2

テンプレートベースのソリューション

次のようなテンプレートを定義します。

public class ConvertListTemplate<A, B>
{
  public List<B> convert( List<A> list ) {
    List<B> result = new ArrayList<B>();
    for( A a : list ) {
      result.add(convertElement(a));
    }
    return result;
  }

  public abstract B convertElement(A element);
}

次に、コードでこれを行います。

List<Integer> result = new ConvertListTemplate<SomeObject, Integer>() {
  public Integer convertElement(SomeObject element) {
    return element.getPropertyABCId();
  }
}.convert(source);

戦略ベースのソリューション

次のような方法を使用します。

public <A, B> List<B> getProperties(
        List<A> list,
        GetPropertyStrategy<? super A, ? extends B> strategy
) {
  List<B> result = new ArrayList<B>();
  for( A a : list ) {
    result.add(strategy.getProperty(a));
  }
  return result;
}

戦略のためのインターフェース付き:

public interface GetPropertyStrategy<A, B>
{
  public B getProperty(A toConvert);
}

次に、次のようにメソッドを呼び出します。

List<Integer> result = getProperties(source, new GetPropertyStrategy<SomeObject, Integer>() {
  public Integer getProperty(SomeObject element) {
    return element.getPropertyABCId();
  }
});
于 2012-11-18T20:13:49.017 に答える