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

lerne groovig
quelle
Er braucht den größten Wert, nicht den Schlüssel
Mangusta
1
OK, versuchen Sie stackoverflow.com/questions/109383/…
Scary Wombat
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);
WJS
quelle
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()));
        }
});
Bathudaide
quelle
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);
Ravindra Ranwala
quelle
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]

Rajkumar Natarajan
quelle
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
Totes Schwimmbad
quelle
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.

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