So finden Sie das neueste Datum aus dem angegebenen Kartenwert in Java


10

Ich habe eine Hash-Map mit den folgenden Werten, in Werten, die ich als String-Datentyp datiert habe. Ich möchte alle Daten vergleichen, die in der Karte verfügbar sind, und nur einen Schlüsselwert extrahieren, der ein sehr aktuelles Datum hat.

Ich möchte mit Werten vergleichen, nicht mit Schlüsseln.

Ich habe den folgenden Code eingefügt

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));
    }

}

Die erwartete Ausgabe für diese ist:

Schlüssel 4 Wert 2014-09-09


Er braucht den größten Wert, nicht den Schlüssel
Mangusta


Konstruktionsfehler. Fügen Sie Ihre Daten nicht als Zeichenfolgen in Ihre Karte ein. Put - LocalDateObjekte. Der Rest des Codes wird wahrscheinlich der gleiche sein, außer der Deklaration des Kartentyps.
Ole VV

Verwandte Themen : Suchen der Schlüssel der Karte mit den höchsten Werten (Gleichheit kann auftreten) (bei der Überprüfung des Stapelaustauschcodes).
Ole VV

Antworten:


1

Dies sollte das neueste (auch bekannt als das größte) Datum im Vergleich zu den anderen liefern.

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

Wenn Sie auch den Schlüssel möchten, tun Sie dies und geben Sie einen Map.Entry zurück. Benötigt 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());

Dies setzt voraus, dass Ihre Karte nicht leer ist. Wenn es leer ist, gibt es eine Null zurück. Funktioniert mit Java 8+

        Entry<String, String> ent = map.entrySet().stream().reduce(
            (a, b) -> b.getValue().compareTo(a.getValue()) >= 0 ? b
                  : a).orElseGet(() -> null);

Wie bekomme ich den Schlüssel als Ergebnis?
lernen groovy

Siehe meinen Zusatz. Ich dachte du wolltest nur den Wert. Mea Culpa.
WJS

Ich bin einen Fehler mit Ihrem neuen Code bekommen - Map.Entry ( „0“, „0000-00-00“) - es sagt Methode Map.Entry für die Art Map .. nicht definiert ist
lernen groovy

Sie müssen etwas älteres als Java 9 ausführen (als das hinzugefügt wurde). Ich werde eine Alternative anbieten und sie erklären.
WJS

Ja, ich benutze Java 8
lerne groovy

6

Verwenden Sie Collections.max mit entrySet

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

oder

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()));
        }
});

Das Map.Entry.comparingByValue()ist geschickt (seit Java 8).
Ole VV

4

Auf den ersten Blick ist die Verwendung von String-Literalen zur Darstellung von Datum kein guter Ansatz und macht es anfälliger und fehleranfälliger. Sie würden lieber LocalDatein erster Linie verwenden. Unter der Annahme, dass Sie keine Kontrolle über dieses Datenformat haben (z. B. von einem anderen System eines Drittanbieters), können wir dennoch einen Ansatz entwickeln, der das vorliegende Problem löst. So sieht es aus.

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

Mit LocalDate.parsewird die Zeichenfolgendarstellung des Datums in LocalDateeine vergleichbare Darstellung konvertiert . Das Comparablewird dann als Schlüssel zur ComparatorBauweise übergeben. Und hier ist das Ausgabe-Schlüssel-Wert-Paar bei erfolgreicher Ausführung:

4=2014-09-09

Wenn Sie lediglich auf die oben vorgeschlagene Zeichenfolgendarstellung des Datums verzichten können, können Sie die obige Lösung viel einfacher und prägnanter gestalten.

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

3

Das sollte funktionieren

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

Ausgabe ist Optional[4=2014-09-09]


Danke, Liebes ... aber ich suche nach dem Schlüssel zum Ergebnis
lerne groovy

1

Sie können die Zeichenfolge analysieren LocalDateund in umgekehrter Reihenfolge sortieren

 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

Sie können entweder:

import java.util.Map.Entry;

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

oder :

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

Beide führen zum gleichen Ergebnis.


Das Map.Entry.comparingByValue()ist geschickt (seit Java 8).
Ole VV
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.