Cara menemukan tanggal terbaru dari nilai peta yang diberikan di java

10

Saya memiliki peta hash dengan nilai-nilai di bawah ini, dalam nilai yang saya kencani sebagai tipe data string. Saya ingin membandingkan semua tanggal yang tersedia di peta dan mengekstrak hanya satu nilai kunci yang memiliki tanggal yang sangat baru.

Saya ingin membandingkan dengan nilai bukan kunci.

Saya sudah memasukkan kode di bawah ini

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

}

Output yang diharapkan untuk yang satu ini adalah:

Nilai 4 Kunci 2014-09-09

belajar asyik
sumber
ia membutuhkan nilai terbesar, bukan kunci
mangusta
1
OK, coba stackoverflow.com/questions/109383/...
Scary Wombat
Kesalahan desain. Jangan cantumkan tanggal Anda di peta sebagai string. Letakkan LocalDatebenda. Sisa kode mungkin akan sama, simpan pernyataan jenis peta.
Ole VV
Terkait: Menemukan kunci peta dengan nilai-nilai tertinggi (kesetaraan mungkin terjadi) (pada Tinjauan Kode Stack Exchange).
Ole VV

Jawaban:

1

Ini harus memberikan tanggal terbaru (alias terbesar) dibandingkan dengan yang lain.

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

Jika Anda juga menginginkan kunci, lakukan ini dan kembalikan Peta. Coba. Membutuhkan 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());

Ini menganggap peta Anda tidak kosong. jika kosong, maka mengembalikan nol. Bekerja dengan Java 8+

        Entry<String, String> ent = map.entrySet().stream().reduce(
            (a, b) -> b.getValue().compareTo(a.getValue()) >= 0 ? b
                  : a).orElseGet(() -> null);
WJS
sumber
Bagaimana cara mendapatkan kunci?
belajar asyik
Lihat tambahan saya. Kupikir kau hanya menginginkan nilainya. MEA Culpa.
WJS
Saya mendapatkan kesalahan dengan kode baru Anda - Map.entry ("0", "0000-00-00") - ia mengatakan Metode map.entry tidak terdefinisi untuk tipe Peta ..
pelajari groovy
Anda harus menjalankan sesuatu yang lebih lama dari Java 9 (saat itulah ditambahkan). Saya akan menawarkan alternatif dan menjelaskannya.
WJS
Ya saya menggunakan Java 8
belajar asyik
6

Gunakan Collections.max dengan entrySet

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

atau

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
sumber
Ini Map.Entry.comparingByValue()bagus (sejak Java 8).
Ole VV
4

Pada pandangan pertama, menggunakan String literals untuk mewakili Date bukanlah pendekatan yang baik dan membuatnya lebih rapuh dan rentan kesalahan. Anda lebih suka menggunakannya LocalDatedi tempat pertama. Namun, dengan asumsi bahwa Anda tidak memiliki kendali atas format data tersebut (misalnya, itu berasal dari sistem pihak ketiga lain), kami masih dapat menyusun suatu pendekatan yang menyelesaikan masalah yang ada. Begini tampilannya.

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

Ini LocalDate.parsedigunakan untuk mengubah representasi string dari tanggal menjadi suatu LocalDateyang Sebanding. Itu Comparablekemudian disahkan sebagai kunci Comparatormetode konstruksi. Dan inilah pasangan nilai kunci output pada eksekusi yang sukses:

4=2014-09-09

Jika Anda hanya dapat membuang representasi String dari tanggal seperti yang disarankan di atas, maka Anda dapat membuat solusi di atas jauh lebih sederhana dan ringkas.

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

Ini seharusnya bekerja

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

output adalah Optional[4=2014-09-09]

Rajkumar Natarajan
sumber
Terima kasih, sayang .. tapi saya sedang mencari kunci hasilnya
pelajari asyik
1

Anda dapat menguraikan string ke dalam LocalDatedan mengurutkannya dalam urutan terbalik

 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
Kolam kematian
sumber
1

Anda dapat melakukannya:

import java.util.Map.Entry;

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

atau :

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

Keduanya akan menghasilkan hasil yang sama.

ETO
sumber
Ini Map.Entry.comparingByValue()bagus (sejak Java 8).
Ole VV