Как найти самую последнюю дату по заданному значению карты в Java - PullRequest
10 голосов
/ 08 октября 2019

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

Я хотел бы сравнить со значениями, а не ключами.

IНиже приведен код

import java.util.HashMap;
import java.util.Map;

public class Test {

  public static void main(String[] args) {

      Map<String, String> map = new HashMap<>();
      map.put("1", "1999-01-01");
      map.put("2", "2013-10-11");
      map.put("3", "2011-02-20");
      map.put("4", "2014-09-09");

      map.forEach((k, v) -> System.out.println("Key : " + k + " Value : " + v));
    }

}

Ожидаемый результат для этого:

Ключ 4 Значение 2014-09-09

Ответы [ 6 ]

5 голосов
/ 08 октября 2019

Использование Collections.max с entrySet

Entry<String, String> max = Collections.max(map.entrySet(), Map.Entry.comparingByValue());

или

Entry<String, String> max = Collections.max(map.entrySet(),
    new Comparator<Entry<String, String>>() {
        @Override
        public int compare(Entry<String, String> e1, Entry<String, String> e2) {
            return LocalDate.parse(e1.getValue()).compareTo(LocalDate.parse(e2.getValue()));
        }
});
4 голосов
/ 08 октября 2019

На первый взгляд использование строковых литералов для представления даты не является хорошим подходом и делает его более хрупким и подверженным ошибкам. Вы бы предпочли использовать LocalDate в первую очередь. Однако, исходя из предположения, что вы не имеете никакого контроля над этим форматом данных (например, он поступает из другой сторонней системы), мы все же можем разработать подход, который решает проблему под рукой. Вот как это выглядит.

Entry<String, String> maxEntry = map.entrySet().stream()
    .max(Comparator.comparing(e -> LocalDate.parse(e.getValue())))
    .orElseThrow(IllegalArgumentException::new);

LocalDate.parse используется для преобразования строкового представления даты в LocalDate, который является сопоставимым. Затем Comparable передается как ключ к методу построения Comparator. И вот пара выходных ключ-значение при успешном выполнении:

4=2014-09-09

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

Entry<String, LocalDate> maxEntry = map.entrySet().stream()
    .max(Map.Entry.comparingByValue())
    .orElseThrow(IllegalArgumentException::new);
3 голосов
/ 08 октября 2019

Это должно работать

    Optional<Map.Entry<String, String>> result = map.entrySet().stream().max(Comparator.comparing(Map.Entry::getValue));
    System.out.println(result);

вывод равен Optional[4=2014-09-09]

1 голос
/ 08 октября 2019

Вы можете сделать либо:

import java.util.Map.Entry;

Entry<String, String> maxEntry = map.entrySet()
                                    .stream()
                                    .max(Entry.comparingByValue());
                                    .orElseThrow(NoSuchElementException::new);   

или:

Entry<String, String> max = Collections.max(map.entrySet(), Entry.comparingByValue());

Оба будут давать одинаковый результат.

1 голос
/ 08 октября 2019

Вы можете разобрать строку в LocalDate и отсортировать ее в обратном порядке

 Entry<String, String> res = map.entrySet()
                                .stream()
                                .sorted(Comparator.comparing((Entry<String, String> entry)->LocalDate.parse(entry.getValue())).reversed())
                                .findFirst()
                                .orElse(null);  // if not present return null or empty Entry
1 голос
/ 08 октября 2019

Это должно обеспечить самую новую (или самую большую) дату по сравнению с другими.

      String max = map.values().stream().reduce("0000-00-00",
            (a, b) -> b.compareTo(a) >= 0 ? b
                  : a);

Если вам также нужен ключ, то сделайте это и верните Map.Entry. Требуется Java 9 +

         Entry<String, String> ent =
            map.entrySet().stream().reduce(Map.entry("0", "0000-00-00"),
                  (a, b) -> b.getValue().compareTo(a.getValue()) >= 0 ? b
                        : a);

         System.out.println(ent.getKey() + " -> " ent.getValue());

Предполагается, что ваша карта не пуста. если он пуст, он возвращает ноль. Работает с Java 8 +

        Entry<String, String> ent = map.entrySet().stream().reduce(
            (a, b) -> b.getValue().compareTo(a.getValue()) >= 0 ? b
                  : a).orElseGet(() -> null);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...