R.S.
R.S.

Reputation: 377

In Java, can I make a predicate that applies a filter on more than one object?

I have a predicate that I use to filter a list of the same Entity Object:

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

I also have to apply the same filter, with the exact same condition on the exact same field, on a list of DTOs where the DTOS is built based on the entity from before:

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

Is it possible to achieve this without instancing two different predicates? If possible, I would like to achieve this by making only one Predicate.

Upvotes: 9

Views: 1892

Answers (4)

Ruslan
Ruslan

Reputation: 6300

Assuming getCompany() returns a String you could create Predicate<String>:

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

And then using it like:

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

But there is not much benefit since it requires almost the same code.

Upvotes: 5

Bentaye
Bentaye

Reputation: 9766

As suggested in the comments, the common interface would be the preferred solution.

I guess you could do something like this, but to be fair, it is ugly.

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);

Upvotes: 0

Vishwa Ratna
Vishwa Ratna

Reputation: 6420

I think you will need a Function<T,R> before using Predicate :

There are two concepts to Function. First is a java.util.function.Function which accepts one argument and produces a result. The second is stream intermediate operation map which converts each element in a stream into another object via the supplied function.

In your case the Function should look like :

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

I tried the basic Program as below with success:

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
  }

Upvotes: 0

ankur agnihotri
ankur agnihotri

Reputation: 1

If equality is only check then you can use static Predicate isEqual(Object targetRef). see java doc 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));


}

Upvotes: 0

Related Questions