Java'da verilen harita değerinden en son tarih nasıl bulunur?


10

Dize veri türü olarak tarih değerlerde, aşağıdaki değerleri ile karma harita yaşıyorum. Haritadaki tüm tarihleri ​​karşılaştırmak ve çok yakın tarihli bir anahtar / değer çiftini ayıklamak istiyorum.

Anahtarlarla değil değerlerle karşılaştırmak istiyorum.

Aşağıdaki kodu ekledim

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

}

Bunun için beklenen çıktı:

Anahtar 4 Değeri 2014-09-09


en büyük değere ihtiyacı var, anahtar değil
mangusta


Tasarım hatası. Tarihlerinizi haritanıza dize olarak koymayın. LocalDateNesneleri koy . Kodun geri kalanı muhtemelen aynı olacaktır, haritanın türünün bildirimini kaydedin.
Ole VV

Yanıtlar:


1

Bu, diğerlerine kıyasla en yeni (en büyük aka) tarihi sağlamalıdır.

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

Anahtarı da istiyorsanız, bunu yapın ve bir Map.Entry döndürün. Java 9+ gerekir

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

Bu, haritanızın boş olmadığını varsayar. boşsa, null değerini döndürür. Java 8+ ile çalışır

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

Sonuç olarak anahtar nasıl alınır?
harika öğrenmek

Eklememe bakın. Sadece değeri istediğini sanıyordum. Mea Culpa.
WJS

Yeni kodunuzla ilgili bir hata alıyorum - Map.entry ("0", "0000-00-00") - Yöntem map.entry Harita türü için tanımsız olduğunu söylüyor ..
groovy

Java 9'dan daha eski bir şey çalıştırıyor olmanız gerekir (bu eklendiğinde). Bir alternatif sunacağım ve açıklayacağım.
WJS

Evet Java 8 kullanıyorum
harika öğrenmek

6

EntrySet ile Collections.max öğesini kullanın

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

veya

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

Map.Entry.comparingByValue()Şık olduğu (Java 8 olduğundan).
Ole VV

4

İlk bakışta, Date'i temsil etmek için String değişmezlerini kullanmak iyi bir yaklaşım değildir ve daha kırılgan ve hataya eğilimli hale getirir. LocalDateİlk etapta kullanmayı tercih edersiniz . Bununla birlikte, bu veri formatı üzerinde herhangi bir kontrole sahip olmadığınız varsayımıyla (örneğin, başka bir üçüncü taraf sisteminden geliyorsa), yine de sorunu çözen bir yaklaşım tasarlayabiliriz. İşte böyle görünüyor.

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

LocalDate.parseBir içine tarih dize gösterimine dönüştürmek için kullanılan LocalDatebir Karşılaştırılabilir olan. Bu Comparabledaha sonra Comparatorinşaat yönteminin anahtarı olarak geçirilir . Ve başarılı yürütme sonrasında çıkış anahtar / değer çifti:

4=2014-09-09

Yalnızca yukarıda önerildiği gibi tarihin Dize temsili ile dağıtım yapabiliyorsanız, yukarıdaki çözümü çok daha basit ve özlü hale getirebilirsiniz.

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

3

Bu çalışmalı

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

çıktı Optional[4=2014-09-09]


Teşekkürler canım .. ama sonuçta anahtarı arıyorum
harika öğrenin

1

Dizeyi ayrıştırabilir ve LocalDatetersine sıralayabilirsiniz

 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

Şunlardan birini yapabilirsiniz:

import java.util.Map.Entry;

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

veya:

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

Her ikisi de aynı sonucu verecektir.


Map.Entry.comparingByValue()Şık olduğu (Java 8 olduğundan).
Ole VV
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.