วิธีค้นหาวันที่ล่าสุดจากค่าแม็พที่กำหนดใน java


10

ฉันกำลังแฮชแผนที่ที่มีค่าด้านล่างในค่าที่ฉันเคยเป็นชนิดข้อมูลสตริง ฉันต้องการเปรียบเทียบวันที่ทั้งหมดที่มีอยู่ในแผนที่และดึงคีย์ - ค่าเดียวเท่านั้นที่มีวันที่ล่าสุด

ฉันอยากจะเปรียบเทียบกับค่าที่ไม่ใช่กุญแจ

ฉันได้รวมรหัสด้านล่าง

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

}

ผลลัพธ์ที่คาดหวังสำหรับอันนี้คือ:

คีย์ 4 ค่า 2014-09-09


เขาต้องการค่าที่มากที่สุดไม่สำคัญ
Mangusta


ข้อผิดพลาดในการออกแบบ อย่าใส่วันที่ลงในแผนที่เป็นสตริง ใส่LocalDateวัตถุ ส่วนที่เหลือของรหัสอาจจะเหมือนกันบันทึกการประกาศประเภทของแผนที่
Ole VV

ที่เกี่ยวข้อง: การค้นหาคีย์ของแผนที่ที่มีค่าสูงสุด (อาจเกิดความเสมอภาค) (ในการตรวจสอบรหัส Exchange Stack)
Ole VV

คำตอบ:


1

สิ่งนี้ควรให้วันที่ล่าสุด (aka ใหญ่ที่สุด) เมื่อเทียบกับวันอื่น ๆ

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

หากคุณต้องการคีย์ให้ทำเช่นนี้และส่งคืน Map.Entry ต้องการ 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());

สิ่งนี้จะถือว่าแผนที่ของคุณไม่ว่างเปล่า ถ้ามันว่างเปล่ามันจะส่งคืนค่าว่าง ทำงานร่วมกับ Java 8+

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

วิธีรับคีย์เป็นผลลัพธ์อย่างไร
เรียนรู้ groovy

ดูเพิ่มเติมของฉัน คิดว่าคุณแค่ต้องการคุณค่า แม่ Culpa
WJS

ฉันได้รับข้อผิดพลาดกับรหัสใหม่ของคุณ - Map.entry ("0", "0000-00-00") - ระบุว่าเมธอด map.entry ไม่ได้ถูกกำหนดสำหรับประเภทแผนที่ ..
เรียนรู้ groovy

คุณต้องใช้งานบางอย่างที่เก่ากว่า Java 9 (ซึ่งเป็นเวลาที่ถูกเพิ่มเข้ามา) ฉันจะเสนอทางเลือกและอธิบายให้
WJS


6

ใช้Collections.maxกับentrySet

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

หรือ

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

The Map.Entry.comparingByValue()is nifty (ตั้งแต่ Java 8)
Ole VV

4

ในการเหลียวมองครั้งแรกการใช้ตัวอักษรสตริงเพื่อแสดงวันที่ไม่ใช่วิธีการที่ดีและทำให้มีความเปราะบางและเกิดข้อผิดพลาดได้ง่ายขึ้น คุณควรจะใช้LocalDateตั้งแต่แรก อย่างไรก็ตามด้วยสมมติฐานที่ว่าคุณไม่สามารถควบคุมรูปแบบข้อมูลดังกล่าวได้ (ตัวอย่างเช่นมันมาจากระบบของบุคคลที่สาม) เรายังคงสามารถหาวิธีที่ช่วยแก้ปัญหาได้ นี่คือลักษณะที่ปรากฏ

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

LocalDate.parseจะใช้ในการแปลงแสดงสายของวันที่เป็นLocalDateซึ่งเป็นเทียบเคียง นั่นComparableคือการส่งผ่านแล้วเป็นกุญแจสำคัญในComparatorวิธีการก่อสร้าง และนี่คือคู่ของคีย์ - ค่าผลลัพธ์เมื่อการประมวลผลสำเร็จ:

4=2014-09-09

หากคุณสามารถแจกจ่ายโดยใช้การแทนค่าสตริงของวันที่ตามที่แนะนำข้างต้นคุณสามารถทำให้การแก้ปัญหาข้างต้นง่ายขึ้นและรวบรัดยิ่งขึ้น

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

3

สิ่งนี้น่าจะใช้ได้

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

ผลลัพธ์คือ Optional[4=2014-09-09]


ขอบคุณที่รัก .. แต่ฉันกำลังมองหาที่สำคัญในผล
เรียนรู้ groovy

1

คุณสามารถแยกสตริงลงในLocalDateและเรียงลำดับในลำดับย้อนกลับ

 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

คุณสามารถทำได้ทั้ง:

import java.util.Map.Entry;

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

หรือ :

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

ทั้งสองอย่างจะให้ผลลัพธ์เหมือนกัน


The Map.Entry.comparingByValue()is nifty (ตั้งแต่ Java 8)
Ole VV
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.