Trong Java, tôi có thể tạo một vị từ áp dụng bộ lọc cho nhiều hơn một đối tượng không?


8

Tôi có một vị từ mà tôi sử dụng để lọc danh sách cùng một Đối tượng thực thể:

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

Tôi cũng phải áp dụng cùng một bộ lọc, với cùng một điều kiện trên cùng một trường chính xác, trên một danh sách các DTO nơi DTOS được xây dựng dựa trên thực thể từ trước:

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

Có thể đạt được điều này mà không cần điều chỉnh hai vị từ khác nhau? Nếu có thể, tôi muốn đạt được điều này bằng cách chỉ làm một Predicate.


5
Được DWHDealDTODWHDealcó liên quan? (như mở rộng cùng một lớp)
ernest_k

1
getCompany()trả lại cùng loại trong cả hai trường hợp?
Ruslan ngày

@ernest_k Không, họ không mở rộng các lớp giống nhau một cách đáng tiếc. Nhưng họ có hầu hết các lĩnh vực giống nhau.
LordGriffith

3
Và những gì về việc xác định một giao diện phổ biến? (tức là được thực hiện bởi cả hai lớp)
Benoit

1
Các quy tắc không khác nhau, ví dụ như thực hiện Predicatevới một lớp thông thường hoặc cố gắng viết một phương thức chấp nhận cả hai DWHDealDWHDealDTO, như là tham số. Nếu các lớp này không có giao diện chung hoặc siêu lớp khai báo một phương thức chung, thì chúng không có một phương thức chung, chỉ có hai phương thức không liên quan có cùng tên.
Holger

Câu trả lời:


5

Giả sử getCompany()trả về một Stringbạn có thể tạo Predicate<String>:

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

Và sau đó sử dụng nó như:

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

Nhưng không có nhiều lợi ích vì nó yêu cầu gần như cùng một mã.


Nó có một lợi ích. Thay vì tạo Dự đoán cho mọi DTO, chỉ một Dự đoán là đủ với phương pháp này cho tất cả các DTO. Vì vậy, điều này dẫn đến khả năng sử dụng lại mã tốt hơn. Ít mã được viết có nghĩa là ít mã hơn để quản lý.
Ketan R

1
@KetanR điều này vẫn có một vị từ cho mỗi DTO, nói chính xác, điều này thậm chí còn có thêm một vị ngữ nữa.
Holger

0

Nếu đẳng thức chỉ là kiểm tra thì bạn có thể sử dụng tĩnh Dự đoán isEqual (Object targetRef). xem tài liệu java https://docs.oracle.com/javase/8/docs/api/java/util/feft/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

Tôi nghĩ bạn sẽ cần một Function<T,R>trước khi sử dụng Predicate:

Có hai khái niệm về Hàm. Đầu tiên là một java.util.function.Functionchấp nhận một đối số và tạo ra một kết quả . Thứ hai là sơ đồ hoạt động trung gian luồng chuyển đổi từng phần tử trong luồng thành đối tượng khác thông qua chức năng được cung cấp.

Trong trường hợp của bạn, nó Functionsẽ trông như:

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

Tôi đã thử chương trình cơ bản như dưới đây với thành công:

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

Theo đề xuất trong các ý kiến, giao diện chung sẽ là giải pháp ưa thích.

Tôi đoán bạn có thể làm một cái gì đó như thế này, nhưng công bằng mà nói, nó thật xấu xí.

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);
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.