2017-02-08 6 views
-3

Я хочу фильтровать записи сотрудников из списка.Список фильтров объектов java stream

мой объект сотрудник выглядит

<pre>new Employee(EmpID, EmpName,"month-year",Transition) 

я могу иметь более одного объекта на одного сотрудника с различными перехода и месяц года, например, <pre>Hired , Bench, joinedproject,releasedproject,resign и соответствующие даты

Теперь я хочу принести месяц-год из первый и последний объект на одного сотрудника.

для например

<pre>new Employee(1, "alex","02-2016","Hired") 
new Employee(1, "alex","02-2016","Bench") 
new Employee(1, "alex","03-2016","Project") 
new Employee(1, "alex","12-2016","Resign") 
new Employee(1, "alex","01-2017","Exit") 

на примере выше, я бы получать даты как «02-2016» и «01-2017»

Я надеюсь, что мой вопрос ясен.

Любые указатели будут высоко оценены.

+1

Я полагаю, что ваш файл 'месяц year' является' String', всегда ли он в формате '00-00'? Является ли 0 или 1 января? И есть ли дата окончания или дата найма? – MikaelF

+0

Да, моя дата в String и его формат 1-2016. Январь - 1 – MKS

+0

еще несколько необходимых исправлений ... Когда вы говорите «3 месяца периода», что вы хотите точно? За последние три месяца? – MikaelF

ответ

1

Это должно работать для вашей проблемы:

List<Employee> list = ... 

DateTimeFormatter formatter = new DateTimeFormatterBuilder() 
    .appendPattern("MM-yyyy") 
    .parseDefaulting(ChronoField.DAY_OF_MONTH, 1) 
    .toFormatter(); 
list.removeIf(e -> LocalDate.parse(e.getHiringDate(), formatter) 
    .until(LocalDate.parse(e.getTerminationDate(), formatter)).getMonths() < 3); 

Длинный строитель вызов в начале, потому что LocalDate.parse не может без LocalDate создания экземпляра в день месяца, поэтому мы должны указать день по умолчанию (в этот случай 1).

ПРИМЕЧАНИЕ: Это не ясно из вашего вопроса, что структура вашего Employee класса, поэтому я предположил, что это соответствует образцу JavaBeans и обеспечивает добытчик для HiringDate и TerminationDate свойств. Тем не менее вы должны иметь возможность работать с этим решением в своем существующем коде, если ваша структура отличается от моей.

+0

Спасибо, сработало! – MKS

+0

Здравствуйте, я отформатировал и добавил подробный пример для моего вопроса. Попросите вас, пожалуйста, снова открыть мой вопрос. – MKS

+0

Если вам нужно разобрать поле year-month, почему бы просто не использовать 'YearMonth.parse (« 02-2016 »,« MM-uuuu »)'? Мне кажется более простым, не нужно беспокоиться о дне месяца. –

0

Чтобы получить только первый и последний месяц года строка для каждого сотрудника вы можете сделать (с Java 8 потоков):

String[][] monthYears = employeeTransitions.stream() 
      .collect(Collectors.groupingBy(Employee::getId)) 
      .values() 
      .stream() 
      .map(transList -> new String[]{ transList.get(0).getMonthYear(), 
        transList.get(transList.size() - 1).getMonthYear() }) 
      .toArray(String[][]::new); 

Я добавил еще Employee один в списке, new Employee(2, "mks", "02-2017", "Hired"), чтобы проверить его с более чем одним идентификатором сотрудника. Вышеприведенный код теперь дает:

[[02-2016, 01-2017], [02-2017, 02-2017]] 

Мы заметили две вещи здесь: Нет связи с идентификаторами сотрудника. Для сотрудника, которого я добавил только с одной записью в списке, я получаю ту же самую месячную строку, что и первая и последняя, ​​что, я полагаю, в порядке.

Чтобы иметь месяцы, связанные с работника ID не намного сложнее:

Map<Integer, List<String>> monthYearPerEmployee = employeeTransitions.stream() 
      .collect(Collectors.groupingBy(Employee::getId)) 
      .entrySet() 
      .stream() 
      .collect(Collectors.toMap(Map.Entry::getKey, entry -> { 
       List<Employee> transitionsForEmployee = entry.getValue(); 
       return Arrays.asList(transitionsForEmployee.get(0).getMonthYear(), 
         transitionsForEmployee.get(transitionsForEmployee.size() - 1).getMonthYear()); 
      })); 

Теперь мы получаем:

{1=[02-2016, 01-2017], 2=[02-2017, 02-2017]} 

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

  • Нет связанных вопросов^_^