Cách tìm ngày mới nhất từ ​​giá trị bản đồ đã cho trong java


10

Tôi đang có bản đồ băm với các giá trị dưới đây, trong các giá trị tôi đã hẹn hò dưới dạng kiểu dữ liệu chuỗi. Tôi muốn so sánh tất cả các ngày có sẵn trên bản đồ và chỉ trích xuất một khóa-giá trị có một ngày rất gần đây.

Tôi muốn so sánh với các giá trị không phải là khóa.

Tôi đã bao gồm mã dưới đây

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

}

Đầu ra dự kiến ​​cho cái này là:

Khóa 4 Giá trị 2014-09-09


anh ta cần giá trị lớn nhất, không phải chìa khóa
mangusta


Lỗi thiết kế. Đừng đặt ngày của bạn vào bản đồ của bạn dưới dạng chuỗi. Đặt LocalDateđồ vật. Phần còn lại của mã có thể sẽ giống nhau, lưu khai báo loại bản đồ.
Ole VV

Câu trả lời:


1

Điều này sẽ cung cấp ngày mới nhất (còn gọi là lớn nhất) so với những ngày khác.

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

Nếu bạn cũng muốn khóa, hãy làm điều này và trả lại Map.Entry. Yêu cầu 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());

Điều này giả định bản đồ của bạn là không trống. nếu nó trống, thì nó trả về null. Hoạt động với Java 8+

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

Làm thế nào để có được chìa khóa như là kết quả?
tìm hiểu Groovy

Xem bổ sung của tôi. Nghĩ rằng bạn chỉ muốn giá trị. Mea Culpa.
WJS

Tôi đang gặp lỗi với mã mới của mình - Map.entry ("0", "0000-00-00") - nó nói Phương thức map.entry không được xác định cho loại Bản đồ ..
tìm hiểu Groovy

Bạn phải chạy một cái gì đó cũ hơn Java 9 (đó là khi nó được thêm vào). Tôi sẽ đưa ra một giải pháp thay thế và giải thích nó.
WJS

Có, tôi đang sử dụng Java 8
tìm hiểu Groovy

6

Sử dụng Collections.max với entryset

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

hoặc là

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

Đây Map.Entry.comparingByValue()là tiện lợi (kể từ Java 8).
Ole VV

4

Thoạt nhìn, sử dụng chuỗi ký tự chuỗi để biểu thị Ngày không phải là một cách tiếp cận tốt và làm cho nó dễ bị hỏng và dễ bị lỗi hơn. Bạn muốn sử dụng LocalDateở nơi đầu tiên. Tuy nhiên, với giả định rằng bạn không có bất kỳ quyền kiểm soát nào đối với định dạng dữ liệu đó (ví dụ: nó đến từ hệ thống bên thứ ba khác), chúng tôi vẫn có thể đưa ra cách tiếp cận giải quyết vấn đề trong tay. Đây là vẻ ngoài của nó.

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

Cái LocalDate.parsenày được sử dụng để chuyển đổi chuỗi đại diện của ngày thành một LocalDatecái có thể so sánh được. Điều Comparableđó sau đó được thông qua như là một chìa khóa cho Comparatorphương pháp xây dựng. Và đây là cặp khóa-giá trị đầu ra khi thực hiện thành công:

4=2014-09-09

Nếu bạn chỉ có thể phân phối với chuỗi đại diện ngày như được đề xuất ở trên, thì bạn có thể làm cho giải pháp trên đơn giản và ngắn gọn hơn nhiều.

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

3

Điều này sẽ làm việc

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

đầu ra là Optional[4=2014-09-09]


Cảm ơn, thân yêu .. nhưng tôi đang tìm kiếm chìa khóa trong kết quả
tìm hiểu Groovy

1

Bạn có thể phân tích chuỗi thành LocalDatevà sắp xếp nó theo thứ tự ngược lại

 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

Bạn có thể làm một trong hai:

import java.util.Map.Entry;

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

hoặc là :

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

Cả hai sẽ tạo ra kết quả như nhau.


Đây Map.Entry.comparingByValue()là tiện lợi (kể từ Java 8).
Ole VV
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.