Javaでは、複数のオブジェクトにフィルターを適用する述語を作成できますか?


8

同じエンティティオブジェクトのリストをフィルタリングするために使用する述語があります。

Predicate<DWHDeal> companyFilter = i -> i.getCompany().equals(company);

以前のエンティティに基づいてDTOSが構築されているDTOのリストに、まったく同じフィールドにまったく同じ条件で同じフィルターを適用する必要もあります。

Predicate<DWHDealDTO> companyFilterDTO = i -> i.getCompany().equals(company);

2つの異なる述語をインスタンス化せずにこれを達成することは可能ですか?できれば1つだけで実現したいPredicateです。


5
あるDWHDealDTODWHDeal関連?(同じクラスを拡張するようなもの)
ernest_k

1
getCompany()どちらの場合も同じ型を返しますか?
ルスラン

@ernest_kいいえ、残念ながらそれらは同じクラスを拡張しません。しかし、彼らはほとんど同じ分野を持っています。
LordGriffith

3
そして、共通のインターフェースを定義するのはどうですか?(つまり、両方のクラスによって実装されます)
Benoit

1
ルールは、たとえばPredicate、通常のクラスでを実装したり、DWHDealとの両方DWHDealDTOをパラメーターとして受け入れるメソッドを記述したりする場合と変わりません。これらのクラスに共通のインターフェースまたは共通のメソッドを宣言するスーパークラスがない場合、共通のメソッドはなく、たまたま同じ名前の2つの無関係なメソッドしかありません。
ホルガー

回答:


5

あなたが作成できるgetCompany()リターンを仮定すると:StringPredicate<String>

Predicate<String> predicate = s -> s.equals(company);

そしてそれを次のように使用します:

list.stream()
    .filter(dto -> predicate.test(dto.getCompany()))
    ...

しかし、ほとんど同じコードを必要とするため、あまりメリットはありません。


それにはメリットがあります。すべてのDTOに対して述語を作成する代わりに、このアプローチではすべてのDTOに対して1つの述語で十分です。これにより、コードの再利用性が向上します。記述されるコードが少ないほど、管理するコードが少なくなります。
Ketan R

1
@KetanRこれには、すべてのDTOに対する述語がまだあります。正確には、これにはさらに1つの述語があります。
ホルガー

0

等価がチェックのみの場合、静的な述語isEqual(Object targetRef)を使用できます。javaドキュメントを参照してくださいhttps://docs.oracle.com/javase/8/docs/api/java/util/function/Predicate.html#isEqual-java.lang.Object-

class StudentView{
    String name;

    public StudentView(String name) {
        this.name = name;
    }
}
class StudentDTO{
    String name;

    public StudentDTO(String name) {
        this.name = name;
    }
}

public void testPredicate(){
    StudentView studentView= new StudentView("John");
    StudentDTO studentDTO = new StudentDTO("Sam");
    Predicate p = Predicate.isEqual("John");
    System.out.println("Test for Student View "+ p.test(studentView.name));
    System.out.println("Test for Student DTO "+ p.test(studentDTO.name));


}

0

私はあなたがFunction<T,R>使用する前に必要になると思いますPredicate

関数には2つの概念があります。1 は、1つの引数java.util.function.Functionを受け入れ、結果を生成するです。2つ目は、ストリームの中間操作マップであり、提供された関数を介してストリーム内の各要素を別のオブジェクトに変換します。

あなたの場合、Functionは次のようになります:

Function<DWHDeal, DWHDealDTO> myFunction = new Function<DWHDeal, DWHDealDTO>() {
  public DWHDealDTO apply(DWHDeal t) {
    return ... ;
  }
};

私は成功して以下の基本的なプログラムを試しました:

static class DWHDeal{
    String name;

    public DWHDeal(String name) {
      this.name = name;
    }
  }
  static class DWHDealDTO{
    String name;

    public DWHDealDTO(String name) {
      this.name = name;
    }
  }

  static Predicate<DWHDealDTO> companyFilter = i -> i.name.equalsIgnoreCase("com");
  public static void main(String[] args) {
    Function<DWHDeal, DWHDealDTO> myFunction = new Function<DWHDeal, DWHDealDTO>() {
      public DWHDealDTO apply(DWHDeal t) {
        return new DWHDealDTO("com");
      }
    };
    DWHDeal newDWHDealDTOObj = new DWHDeal("com");
    System.out.println(companyFilter.test(myFunction.apply(newDWHDealDTOObj)));  //Works
  }

0

コメントで示唆されているように、共通のインターフェースが推奨されるソリューションです。

あなたはこのようなことをすることができると思いますが、公平を期すために、それは醜いです。

private String getCompany(Object o) {
    if(o instanceof DWHDeal)
        return ((DWHDeal) o).getCompany();
    else
        return ((DWHDealDTO) o).getCompany();
}

Predicate<Object> companyFilter = i -> getCompany(i).equals(company);
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.