Java Streams для зацикливания дважды по одному и тому же списку - PullRequest
0 голосов
/ 02 июля 2018

Я новичок в Java 8, и у меня есть проблемы с пониманием потоков по какой-то причине. Допустим, у нас есть список объектов List , где MyObject имеет 2 поля: Long Id, Date insertTime, и я хотел бы удалить элементы с таким же идентификатором и более ранним временем.

С 2 для циклов это что-то вроде этого:

for(MyObject object : myObjects) {
   for(MyObject tmpObject : myObjects) {
      if(object.getId() == tmpObject.getId()) {
         if(object.getInsertDate().after(tmpObject.getInsertDate())) 
           myObjects.remove(tmpObject);
         else 
           myObjects.remove(object);
      }
   }
}

Как бы это выглядело при использовании потоков?

@ Майкл, мой плохой. Чем мне понадобится другой список или массив для хранения данных ответа.

Допустим, у меня есть

  1. 1234: 25/5/1991
  2. 1235: 25/5/1995
  3. 1234: 25/5/1999

Так что мне нужно в результате

  1. 1235: 25/5/1995
  2. 1234: 25/5/1999

Спасибо всем.

Ответы [ 2 ]

0 голосов
/ 02 июля 2018

Вы можете сделать это так,

List<MyObject> latestObjects = myObjects.stream()
    .collect(Collectors.collectingAndThen(
        Collectors.groupingBy(MyObject::getId,
            Collectors.maxBy(Comparator.comparing(MyObject::getInsertTime))),
        map -> map.values().stream().map(op -> op.orElse(null)).collect(Collectors.toList())));

Сначала сгруппируйте объекты по их значению Id, затем уменьшите его, чтобы сохранить только последний объект для каждого значения Id, и, наконец, соберите их в List.

Обновление

Это может быть улучшено в соответствии с комментарием ниже. Вот расширенная версия.

List<MyObject> latestObjects = myObjects.stream()
        .collect(Collectors.collectingAndThen(
                Collectors.toMap(MyObject::getId, Function.identity(),
                        BinaryOperator.maxBy(Comparator.comparing(MyObject::getInsertTime))),
                map -> new ArrayList<MyObject>(map.values())));
0 голосов
/ 02 июля 2018

сгруппируйте по идентификатору, а затем для каждого идентификатора выберите тот, который имеет наибольшую дату добавления Вы можете заменить Sample на MyObject.

    Map<Long, List<Sample>> map = list.stream().collect(Collectors.groupingBy(Sample::getId));
    map.values().stream()
            .map(samples -> Collections.max(
                    samples, Comparator.comparing(Sample::getInsertDate)))
            .collect(Collectors.toList());
...