2015-08-20 2 views
7

У меня есть требование получить количество сотрудников, в которых имя сотрудника содержит «kumar», а возраст больше, чем 26. Я использую потоки Java 8 для перебора по коллекции, m, чтобы найти счетчик сотрудников с вышеуказанным условием.Выполнение действия внутри потока операции в 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' выполняет только действия над * обработанными * элементами, поэтому, если вы используете короткозамкнутое действие терминала, например' findFirst', оно не обязательно будет обрабатывать все элементы. Кроме того, 'count()' может полностью пропустить обработку, если размер предсказуем, например. без «фильтра». Реализация Java 9 имеет такую ​​оптимизацию ... – Holger

+0

Есть ли способ контролировать peek(). В производстве я хочу отключить журналы методов peek(), один из способов - комментировать код, но ему нужна компиляция кода и развертывания. Любая другая идея ?. – Krishna

+0

@ Krishna Идея состоит в том, чтобы отключить 'peek', но использовать фреймворк регистрации, который будет записывать по-разному в dev и production (на основе файла конфигурации). Взгляните на 'log4j'. – Tunaki

2

Скорее неясно, что вы на самом деле хотите, но это может помочь:
Лямбда (как ваш Predicate) можно записать двумя способами:
без скобок, как это: e -> e.getAge() > 26 или

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

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

Хотите распечатать вывод потока один перед переходом к следующему потоку операции. – Krishna

Смежные вопросы