2015-07-08 33 views
6

Hãy xem xét một lớp Parent chỉ chứa một thuộc tính Integer. Tôi đã tạo 6 đối tượng của lớp cha và các giá trị thuộc tính là 100, 20, 300, 400, 500, null.Xử lý một thuộc tính null bằng cách sử dụng các luồng java 8 và sắp xếp bằng cách sử dụng các biểu thức lambda

Bây giờ tôi đã thêm tất cả các đối tượng vào danh sách (Tên danh sách là danh sách). Sau đó, tôi muốn lấy các đối tượng có giá trị thuộc tính lớn hơn 100. Tôi đã sử dụng các luồng Java 8 cho mục đích này.

Predicate<Entity> predicate = e -> e.getParentId() < 100; 
result = list.stream().filter(predicate).collect(Collectors.toList()); 

Tôi cũng muốn sắp xếp danh sách theo thứ tự giảm dần. Tôi đã sử dụng đoạn mã sau cho mục đích này.

Comparator<Entity> comp = (d1,d2) -> d2.getId().compareTo(d1.getId()); 
list.sort(comp); 

Trong cả hai trường hợp, tôi nhận được NullPointerException.

Làm cách nào để xử lý việc này?

+1

bản sao có thể có của [Cách chúng tôi quản lý luồng jdk8 cho giá trị null] (http://stackoverflow.com/questions/17081063/how-should-we-manage-jdk8-stream-for-null-values) – alfasin

+2

I 'không rõ ràng ... là nó 'e' đó là' null', hoặc 'e.getParentId()'? Nếu 'e.getParentId()' được khai báo là 'Integer' (kiểu được đóng), nó có thể là null. Nhưng sau đó khi nó được chuyển thành một 'int' để so sánh nó với 100, kết quả sẽ là' NullPointerException' nếu nó là 'null'. – ajb

Trả lời

5

Hãy thử trước khi lọc chỉ không null parentId giá trị:

result = list.stream().filter(e -> e.getParentId() != null).filter(predicate).collect(Collectors.toList()); 

[sửa] Chỉ cần thấy, rằng thuộc tính (e.parentId) vẻ như một là null. Trong trường hợp đó, điều thứ hai, sắp xếp, phá vỡ. Bạn đang sắp xếp danh sách gốc, không phải danh sách được lọc. Hãy thử result.sort(comp), sau đó bạn nên tránh NPE.

+4

Điều này sẽ hoạt động. Bạn cũng có thể làm '.filter (Objects :: nonNull)' – alfasin

+0

Vấn đề là đối tượng không phải là null, nhưng thuộc tính là null, nếu tôi chứa 100 thuộc tính, và tôi đã tạo danh sách các đối tượng đó, trong đó nhiều thuộc tính có thể có null giá trị trong một số các đối tượng trong danh sách, làm thế nào tôi nên xử lý này. –

1

Bạn có thể làm:

Predicate<Entity> predicate = e -> e.getParentId() < 100; 
Predicate<Entity> nonNull = e -> e != null; 
result = list.stream().filter(nonNull) 
         .filter(predicate) 
         .collect(Collectors.toList()); 

Tất nhiên, bạn có thể kết hợp các vị từ thành một, nhưng tôi đã giới thiệu một một giây để có thể đọc tốt hơn. Ngoài ra, bạn có thể thay đổi thuộc tính nonNull để kiểm tra toàn bộ thực thể hoặc chỉ thuộc tính id (hoặc thậm chí cả hai). Chỉ cần chơi một chút với nó. :)

4

Bạn có thể làm điều đó tất cả trong một Suối đường ống:

List<Entity> result = 
    list.stream() 
     .filter(e -> e.getParentId()!=null) // it's not clear if the null 
              // is the Entity object itself 
              // (in which case it should be e!=null) 
              // or just the ParentId member 
     .filter(predicate) 
     .sorted(comp) 
     .collect(Collectors.toList()); 

BTW, theo nội dung của câu hỏi của bạn, vị từ ban đầu nên là:

Predicate<Entity> predicate = e -> e.getParentId() > 100; // not < 100 
+2

Sẽ không lọc các phần tử 'e.getParentId() == null' này? Anh ta đang nói về 'e' là vô giá trị. – Codebender

+2

@Codebender Tôi có thể đang đọc sai câu hỏi, nhưng dường như OP tạo ra các đối tượng có ID cha là '100,20,300,400,500, null', vì vậy tôi giả sử null được gọi là ParentId. Tôi có thể sai. – Eran

+0

@Codebender không rõ ràng. Tôi nghĩ rằng anh ta đang nói về parentId là null, có thể nếu nó là một 'Integer'. – ajb

2

Khai thác sức mạnh của tài liệu tham khảo phương pháp để làm cho mã trở nên nhỏ gọn hơn:

List<Entity> result = 
      list.stream() 
        .filter(Objects::nonNull) 
        .filter(predicate) 
        .sorted(comp) 
        .collect(Collectors.toList()); 
13

Tất cả các câu trả lời ở đây xoay quanh "vứt bỏ các phần tử xấu, những phần tử có giá trị rỗng là getParentId()". Đó có thể là câu trả lời, nếu họ thực sự là xấu. Nhưng có một lựa chọn khác: Comparators.nullsFirst (hoặc cuối cùng.) Điều này cho phép bạn so sánh những thứ xử lý một giá trị rỗng nhỏ hơn (hoặc lớn hơn) tất cả các giá trị không null, vì vậy bạn không phải ném các phần tử với một parentId rỗng xa.

Comparator<Entity> cmp = nullsLast(comparing(Entity::getParentId)); 
List<Entity> list = list.stream().sorted(cmp).collect(toList()); 

Bạn có thể thực hiện việc tương tự để lọc; xác định vị ngữ của bạn như:

Predicate<Entity> predicate = e -> e.getParentId() != null 
             && e.getParentId() < 100; 
5

Hình như bạn đang tìm kiếm cái gì đó như:

list.sort(Comparator.comparing(Entity::getParent, 
           Comparator.nullsLast(Integer::compareTo))); 

Tất cả các yếu tố với null phụ huynh sẽ được đặt ở cuối và phần còn lại sẽ được sắp xếp theo cha mẹ của họ.

+1

giải pháp này làm việc cho tôi. Bởi vì tôi không muốn lọc các giá trị null. – omerhakanbilici

Các vấn đề liên quan