2015-08-20 55 views
7

我有一個要求,以獲得僱員人數,其中員工姓名包含「kumar」且年齡大於26歲。我正在使用Java 8流來迭代集合,能夠在上述條件下找到員工人數。在Java操作流內執行操作8

但是,在此期間,我需要打印員工詳細信息。

下面是使用Java 8流我的代碼:

public static void main(String[] args) { 

    List<Employee> empList = new ArrayList<>(); 

    empList.add(new Employee("john kumar", 25)); 
    empList.add(new Employee("raja", 28)); 
    empList.add(new Employee("hari kumar", 30)); 

    long count = empList.stream().filter(e -> e.getName().contains("kumar")) 
          .filter(e -> e.getAge() > 26).count(); 
    System.out.println(count); 
} 

傳統的方式:

public static void main(String[] args){ 
    List<Employee> empList = new ArrayList<>(); 

    empList.add(new Employee("john kumar", 25)); 
    empList.add(new Employee("raja", 28)); 
    empList.add(new Employee("hari kumar", 30)); 
    int count = 0; 
    for (Employee employee : empList) { 

     if(employee.getName().contains("kumar")){ 
      if(employee.getAge() > 26) 
      { 
       System.out.println("emp details :: " + employee.toString()); 
       count++; 
      } 
     } 
    } 
    System.out.println(count); 
} 

不管我用傳統的方式印刷我,我要實現使用流也一樣。

如何在使用流時在每次迭代中打印消息?

回答

14

你可以使用Stream.peek(action)方法記錄信息有關流的每個對象:

long count = empList.stream().filter(e -> e.getName().contains("kumar")) 
         .filter(e -> e.getAge() > 26) 
         .peek(System.out::println) 
         .count(); 

peek方法允許對消耗的流中的每個元素執行操作。該操作必須符合Consumer接口:採用T類型(流元素的類型)的單個參數t並返回void

+2

需要強調的是'peek'只對* processed *項目執行一個動作,所以如果你使用'findFirst'這樣的短路終端動作,它不一定會處理所有項目。此外,如果大小是可預測的,則「count()」可以完全跳過處理,例如,沒有'過濾器'。 Java 9的實現有這樣的優化... – Holger

+0

有沒有辦法控制peek()。在生產中,我想禁用peek()方法日誌,一種方法是在代碼中註釋,但它需要編譯代碼和部署。任何其他想法? – Krishna

+0

@Krishna這個想法並不是禁用'peek',而是使用一個日誌框架,它將在dev和production(基於配置文件)中記錄不同的日誌。看看'log4j'。 – Tunaki

2

不清楚,你真的想,但是這可能幫助什麼:
Lambda表達式(如您的Predicate)可以通過兩種方式來寫:
如果沒有括號是這樣的:e -> e.getAge() > 26

...filter(e -> { 
       //do whatever you want to do with e here 

       return e -> e.getAge() > 26; 
      })... 
+0

想要在傳遞到下一個操作流之前打印流1的輸出。 – Krishna