2016-04-27 30 views
-1

我有像這樣使用Java8具有多個屬性篩選,只有當他們不爲空

public class Organization { 

    private List<Employee> employees; 

    public static class Employee { 
    private String department; 
    private String designation; 
    } 
} 

我有需要在Map<String, Object>搜索方法的對象。該地圖可以包含部門或指定的關鍵值或兩者。

{department -> "cs"} or 
{designation -> "engineer"} or 
{department -> "cs", designation -> "engineer"} 

這是我需要做的。如果部門密鑰存在,我需要退回該部門的所有員工。如果存在部門和指定密鑰,則需要返回符合兩個條件的所有員工。我該怎麼做呢?

因爲地圖是動態的,我如何過濾員工?

+0

那你試試? – agilob

+0

從你說的看起來部門總是存在的。它唯一的名稱是可選的? –

回答

1

最好的辦法可能是運行多個過濾器:

Stream<Employee> employeeStream = employees.stream(); 
if (filter.get("department") != null) 
    employeeStream = employeeStream.filter(e -> filter.get("department").equals(e.getDepartment())); 
if (filter.get("designation") != null) 
    employeeStream = employeeStream.filter(e -> filter.get("designation").equals(e.getDesignation())); 
List<Employee> result = employeeStream.collect(Collectors.toList()); 

另一種方法是使用單個過濾器並檢查過濾拉姆達鍵的存在:

List<Employee> result = employees.stream() 
    .filter((Employee e) -> { 
     return 
      (filter.get("department") == null || filter.get("department").equals(e.getDepartment())) && 
      (filter.get("designation") == null || filter.get("designation").equals(e.getDesignation())); 
    }) 
    .collect(Collectors.toList()); 

編輯:正如評論中所討論的,考慮將filter.get()的結果存儲到臨時變量中,並直接在過濾lambda中使用。

+0

程序邏輯正常,但你應該避免多餘的'get'調用... – Holger

+0

@Holger:你說得對,這將是值得的。我想避免將代碼過多地分配給新的變量,因此概念部分仍然簡單易懂。 –

0

我寧願去一個或條件的過濾器:

employees.stream() 
    .filter(e -> !filter.containsKey("department") || filter.get("department").equals(e.getDepartment())) 
    .filter(e -> !filter.containsKey("designation") || filter.get("designation").equals(e.getDesignation())) 
    .collect(Collectors.toList()); 
相關問題