Найти самую последнюю дату в списке объектов в свойстве LocalDate, используя поток Java 8 - PullRequest
0 голосов
/ 11 декабря 2018

У меня есть список объектов, которые содержат несколько свойств, одним из которых является LocalDate.Я хотел бы найти объект с самой последней датой из этого списка.

Я довольно зеленый с Java 8 и использую потоки.Как и в большинстве программ, кажется, что у этой кошки есть более одного способа.Вот что у меня есть.

list.stream().filter( object -> object.getId() == id
&& object.getCancelDate() == null 
&& object.getEarliestDate() != null)
.min( Comparator.comparing( LocalDate::toEpochDay )
.get();

Это дает мне «Нестатический метод не может быть вызван из статического контекста» для функции Comparator.

Я рассматривал возможность создания карты только дат из отфильтрованных объектов, и до сих пор придумал что-то вроде этого.

list.stream().filter( object -> object.getId() == id
&& object.getCancelDate() == null 
&& object.getEarliestDate() != null)
.map( data -> data.getEarliestDate() )
.collect( Collectors.toList() )

и я недействительно уверен, куда идти от этого или если это будет даже работать.

Я знаю, что есть простой способ сделать это, но мой мозг просто не соединяет точки.

Обновление

Спасибо за ответ.Я обновил свой код Optional<YourObject> recentObject = list.stream().filter(object -> object.getId() == id && object.getCancelDate() == null && object.getEarliestDate() != null) .max(Comparator.comparing(s -> s.getEarliestDate().toEpochDay()));

Теперь я получаю ошибку компилятора Несовместимые типы.

Required:Optional<MyClass>
Found:Optional<capture<? extends MyClass>>

Метод расширяет MyClass, поэтому в объявлении типа для Optional мне нужно сделатьчто-то вроде MyClass.class?

Обновление 2 Спасибо @Hogen за помощь в исправлении ошибки компилятора путем добавления .map () в конце.Вот как это выглядело после изменения.

Optional<MyClass> date = 
list.stream().filter(object -> object.getId() == id &&
object.getCancelDate() == null &&
object.getEarliestDate() != null)
.max(Comparator.comparing( s -> s.getEarliestDate()
.toEpochDay())).map(Function.identity());

Однако после некоторой помощи мне удалось найти решение, которое переместит карту в другое место, чтобы я не столкнулся с проблемой.использования расширенного класса.

Optional<LocalDate> mostRecentDate = list.stream()
.filter(data -> data.getId() == id && data.getCancelDate() == null)
.map(MyObject::getEarliestDate)
.filter(Objects::nonNull)
.max(LocalDate::compareTo);

Ответы [ 2 ]

0 голосов
/ 12 декабря 2018

Положив это в ответ для наглядности.Основываясь на ответе @ nullpointer и предложении @ Holger, я смог предложить два следующих решения:

Решение 1

Optional<MyClass> mostRecentDate = list.stream()
    .filter(myObject -> myObject.getId() == id &&
     myObject.getCancelDate() == null && myObject.getEarliestDate() != null)
    .max(Comparator.comparing( s -> s.getEarliestDate()
    .toEpochDay())).map(Function.identity());

Решение 2

LocalDate mostRecentDate = list.stream()
    .filter(myObject -> myObject.getId() == id && myObject.getCancelDate() == null)
    .map(MyObject::getEarliestDate)
    .filter(Objects::nonNull)
    .max(LocalDate::compareTo)
    .orElse(null);

Оба решения работают, но второе решение, на мой взгляд, чище и менее неоднозначно.Он удаляет код .map (Function.identity ()), который на самом деле ничего не делает, на что указывал @Holgen при использовании новой ссылки на метод в Java 8 :: .Он также фильтрует список объектов и сопоставляет даты с новым списком, который затем использует .max () с методом compareTo () вместо пользовательской функции.Я рассматриваю пользовательскую функцию и бесполезный код как беспорядочные, и для любого, кто читает код, это может сделать его менее понятным.

Обратите внимание, что во втором решении я также удалил класс Optional.Использование .orElse () удовлетворяет возвращению фактического класса LocalDate вместо опции из потока.

Спасибо за помощь всем, и я надеюсь, что этот ответ поможет другим.

0 голосов
/ 11 декабря 2018

Вы в основном ищете:

Optional<YourObject> recentObject = list.stream()
        .filter(object -> object.getId() == id && object.getCancelDate() == null && object.getEarliestDate() != null)
        .max(Comparator.comparing(YourObject::getEarliestDate)); // max of the date for recency

С LocalDate.compareTo

Сравнивает эту дату с другой датой.Сравнение в основном основано на дате, от самой ранней до самой поздней .Это «соответствует равным», как определено Comparable.

...