การค้นหาคีย์ที่เกี่ยวข้องกับค่าสูงสุดในแผนที่ Java


148

วิธีที่ง่ายที่สุดในการรับคีย์ที่เชื่อมโยงกับค่าสูงสุดในแผนที่คืออะไร

ฉันเชื่อว่า Collections.max (someMap) จะส่งคืนคีย์สูงสุดเมื่อคุณต้องการคีย์ที่สอดคล้องกับค่าสูงสุด

คำตอบ:


141

โดยทั่วไปคุณจะต้องวนซ้ำชุดรายการของแผนที่โดยจำทั้ง "ค่าสูงสุดที่ทราบในปัจจุบัน" และคีย์ที่เกี่ยวข้อง (หรือแค่รายการที่มีทั้งสองอย่างแน่นอน)

ตัวอย่างเช่น:

Map.Entry<Foo, Bar> maxEntry = null;

for (Map.Entry<Foo, Bar> entry : map.entrySet())
{
    if (maxEntry == null || entry.getValue().compareTo(maxEntry.getValue()) > 0)
    {
        maxEntry = entry;
    }
}

41
+1: คุณสามารถมีได้มากกว่าหนึ่งคีย์ที่มีค่าสูงสุดเท่ากัน ลูปนี้จะให้คุณเป็นคนแรกที่พบ
Peter Lawrey

22
การเปลี่ยน> 0 เป็น> = 0 จะทำให้คุณพบคนสุดท้าย
Aaron J Lang

1
การใช้งานสตรีม Java 8 จะช่วยให้สิ่งนี้ง่ายขึ้นอีกต่อไปหรือไม่? เช่น map.forEach ((k, v) -> ...
zkarthik

3
@zkarthik: การใช้maxตัวเปรียบเทียบแบบกำหนดเองน่าจะง่ายกว่า
Jon Skeet

121

เพื่อความสมบูรณ์นี่คือ วิธีการทำ

countMap.entrySet().stream().max((entry1, entry2) -> entry1.getValue() > entry2.getValue() ? 1 : -1).get().getKey();

หรือ

Collections.max(countMap.entrySet(), (entry1, entry2) -> entry1.getValue() - entry2.getValue()).getKey();

หรือ

Collections.max(countMap.entrySet(), Comparator.comparingInt(Map.Entry::getValue)).getKey();

3
(entry1, entry2) -> entry1.getValue() - entry2.getValue()มีขนาดกะทัดรัดกว่าสำหรับตัวเปรียบเทียบ
JustABit

5
จะทำอย่างไรถ้าฉันต้องการคีย์ทั้งหมดที่ตรงกับค่าสูงสุด?
Mouna

4
กะทัดรัด แต่เข้าใจยาก
Lluis Martinez

1
นอกจากนี้คุณยังสามารถใช้วิธีการเปรียบเทียบที่จัดทำโดยคลาส IntegercountMap.entrySet().stream().max((entry1, entry2) -> Integer.compare(entry1.getValue(), entry2.getValue())).get().getKey();
Rui Filipe Pedro

3
หรือจะใช้Map.Entry.comparingByValue()แทนก็ได้
Alexey Grigorev

57

รหัสนี้จะพิมพ์คีย์ทั้งหมดที่มีค่าสูงสุด

public class NewClass4 {
    public static void main(String[] args)
    {
        HashMap<Integer,Integer>map=new HashMap<Integer, Integer>();
        map.put(1, 50);
        map.put(2, 60);
        map.put(3, 30);
        map.put(4, 60);
        map.put(5, 60);
        int maxValueInMap=(Collections.max(map.values()));  // This will return max value in the Hashmap
        for (Entry<Integer, Integer> entry : map.entrySet()) {  // Itrate through hashmap
            if (entry.getValue()==maxValueInMap) {
                System.out.println(entry.getKey());     // Print the key with max value
            }
        }

    }
}

51

หนึ่งซับง่ายๆโดยใช้ Java-8

Key key = Collections.max(map.entrySet(), Map.Entry.comparingByValue()).getKey();


3
โซลูชันที่หรูหราและเรียบง่ายที่สุด ขอบคุณ
Daniel Hári

@ Samir โปรดตรวจสอบเวอร์ชัน Java ของคุณ Sleiman Jneid ได้กล่าวไว้อย่างชัดเจนว่าจะทำงานร่วมกับ Java 8
Vaibs

@Vaibs ฉันใช้ Java 8 มันไม่สำคัญอีกต่อไปคำตอบของ Hilikus ใช้ได้กับฉัน
กลั้วคอ

1
จะเป็นอย่างไรถ้ามี 2 คีย์ที่เป็น max? มันจะส่งคืนอาร์เรย์ของค่าคีย์ดังกล่าวได้อย่างไร
Sophie

9

ต่อไปนี้เป็นวิธีดำเนินการโดยตรง (โดยไม่ต้องมีลูปพิเศษที่ชัดเจน) โดยกำหนดสิ่งที่เหมาะสมComparator:

int keyOfMaxValue = Collections.max(
                        yourMap.entrySet(), 
                        new Comparator<Entry<Double,Integer>>(){
                            @Override
                            public int compare(Entry<Integer, Integer> o1, Entry<Integer, Integer> o2) {
                                return o1.getValue() > o2.getValue()? 1:-1;
                            }
                        }).getKey();

6

คำตอบที่ส่งกลับตัวเลือกเนื่องจากแผนที่อาจไม่มีค่าสูงสุดหากว่างเปล่า: map.entrySet().stream().max(Map.Entry.comparingByValue()).map(Map.Entry::getKey);


4

Java 8 วิธีรับคีย์ทั้งหมดที่มีค่าสูงสุด

Integer max = PROVIDED_MAP.entrySet()
            .stream()
            .max((entry1, entry2) -> entry1.getValue() > entry2.getValue() ? 1 : -1)
            .get()
            .getValue();

List listOfMax = PROVIDED_MAP.entrySet()
            .stream()
            .filter(entry -> entry.getValue() == max)
            .map(Map.Entry::getKey)
            .collect(Collectors.toList());

System.out.println(listOfMax);

นอกจากนี้คุณสามารถขนานได้โดยใช้parallelStream()แทนstream()


4

ฉันมีสองวิธีโดยใช้méthodนี้เพื่อรับคีย์ที่มีค่าสูงสุด:

 public static Entry<String, Integer> getMaxEntry(Map<String, Integer> map){        
    Entry<String, Integer> maxEntry = null;
    Integer max = Collections.max(map.values());

    for(Entry<String, Integer> entry : map.entrySet()) {
        Integer value = entry.getValue();
        if(null != value && max == value) {
            maxEntry = entry;
        }
    }
    return maxEntry;
}

ดังตัวอย่างการเริ่มรายการที่มีค่าสูงสุดโดยใช้วิธีการ:

  Map.Entry<String, Integer> maxEntry =  getMaxEntry(map);

การใช้Java 8เราจะได้รับวัตถุที่มีค่าสูงสุด:

Object maxEntry = Collections.max(map.entrySet(), Map.Entry.comparingByValue()).getKey();      

System.out.println("maxEntry = " + maxEntry);

เวอร์ชัน java 8 นั้นเรียบง่าย แต่มีประสิทธิภาพ! ทำได้ดีมาก
Catbuilts

4

1. การใช้สตรีม

public <K, V extends Comparable<V>> V maxUsingStreamAndLambda(Map<K, V> map) {
    Optional<Entry<K, V>> maxEntry = map.entrySet()
        .stream()
        .max((Entry<K, V> e1, Entry<K, V> e2) -> e1.getValue()
            .compareTo(e2.getValue())
        );

    return maxEntry.get().getKey();
}

2. การใช้ Collections.max () กับ Lambda Expression

    public <K, V extends Comparable<V>> V maxUsingCollectionsMaxAndLambda(Map<K, V> map) {
        Entry<K, V> maxEntry = Collections.max(map.entrySet(), (Entry<K, V> e1, Entry<K, V> e2) -> e1.getValue()
            .compareTo(e2.getValue()));
        return maxEntry.getKey();
    }

3. การใช้สตรีมด้วยการอ้างอิงวิธีการ

    public <K, V extends Comparable<V>> V maxUsingStreamAndMethodReference(Map<K, V> map) {
        Optional<Entry<K, V>> maxEntry = map.entrySet()
            .stream()
            .max(Comparator.comparing(Map.Entry::getValue));
        return maxEntry.get()
            .getKey();
    }

4. การใช้ Collections.max ()

    public <K, V extends Comparable<V>> V maxUsingCollectionsMax(Map<K, V> map) {
        Entry<K, V> maxEntry = Collections.max(map.entrySet(), new Comparator<Entry<K, V>>() {
            public int compare(Entry<K, V> e1, Entry<K, V> e2) {
                return e1.getValue()
                    .compareTo(e2.getValue());
            }
        });
        return maxEntry.getKey();
    }

5. ใช้การทำซ้ำอย่างง่าย

public <K, V extends Comparable<V>> V maxUsingIteration(Map<K, V> map) {
    Map.Entry<K, V> maxEntry = null;
    for (Map.Entry<K, V> entry : map.entrySet()) {
        if (maxEntry == null || entry.getValue()
            .compareTo(maxEntry.getValue()) > 0) {
            maxEntry = entry;
        }
    }
    return maxEntry.getKey();
}

เข้าครอบครอง Baldung.com baeldung.com/java-find-map-max
Sir Montes

3

เข้าใจง่าย ในโค้ดด้านล่าง maxKey คือคีย์ที่ถือค่าสูงสุด

int maxKey = 0;
int maxValue = 0;
for(int i : birds.keySet())
{
    if(birds.get(i) > maxValue)
    {
        maxKey = i;
        maxValue = birds.get(i);
    }
}

2

แผนที่กำหนด

HashMap abc = HashMap ใหม่ <> ();

รับรายการแผนที่ทั้งหมดที่มีค่าสูงสุด

คุณสามารถใช้วิธีการใดก็ได้ด้านล่างในตัวกรองเพื่อรับรายการแผนที่ตามลำดับสำหรับชุดค่าต่ำสุดหรือสูงสุด

Collections.max(abc.values())
Collections.min(abc.values())
Collections.max(abc.keys())
Collections.max(abc.keys())

abc.entrySet().stream().filter(entry -> entry.getValue() == Collections.max(abc.values()))

หากต้องการรับคีย์สำหรับแผนที่ตัวกรองเท่านั้น

abc.entrySet()
       .stream()
       .filter(entry -> entry.getValue() == Collections.max(abc.values()))
       .map(Map.Entry::getKey);

หากคุณต้องการรับค่าสำหรับแผนที่ที่กรอง

abc.entrySet()
      .stream()
      .filter(entry -> entry.getValue() == Collections.max(abc.values()))
      .map(Map.Entry::getvalue)

หากคุณต้องการรับคีย์ดังกล่าวทั้งหมดในรายการ:

abc.entrySet()
  .stream()
  .filter(entry -> entry.getValue() == Collections.max(abc.values()))
  .map(Map.Entry::getKey)
  .collect(Collectors.toList())

หากคุณต้องการรับค่าดังกล่าวทั้งหมดในรายการ:

abc.entrySet()
  .stream()
  .filter(entry -> entry.getValue() == Collections.max(abc.values()))
  .map(Map.Entry::getvalue)
  .collect(Collectors.toList())

1

วิธีนี้ใช้ได้หรือไม่?

int[] a = { 1, 2, 3, 4, 5, 6, 7, 7, 7, 7 };
Map<Integer, Integer> map = new HashMap<Integer, Integer>();
for (int i : a) {
Integer count = map.get(i);
map.put(i, count != null ? count + 1 : 0);
}
Integer max = Collections.max(map.keySet());
System.out.println(max);
System.out.println(map);

1

องค์ประกอบส่วนใหญ่ / องค์ประกอบสูงสุดในแผนที่:

public class Main {
     public static void main(String[] args) {
     int[] a = {1,3,4,3,4,3,2,3,3,3,3,3};
     List<Integer> list = Arrays.stream(a).boxed().collect(Collectors.toList());
     Map<Integer, Long> map = list.parallelStream()
             .collect(Collectors.groupingBy(Function.identity(),Collectors.counting()));
     System.out.println("Map => " + map);
     //{1=1, 2=1, 3=8, 4=2}
     map.entrySet()
     .stream()
     .max(Comparator.comparing(Entry::getValue))//compare the values and get the maximum value
     .map(Entry::getKey)// get the key appearing maximum number of times
     .ifPresentOrElse(System.out::println,() -> new RuntimeException("no such thing"));

     /*
      * OUTPUT : Map => {1=1, 2=1, 3=8, 4=2} 
      * 3
      */
     // or in  this way 
     System.out.println(".............");
     Integer maxAppearedElement = map.entrySet()
             .parallelStream()
             .max(Comparator.comparing(Entry::getValue))
             .map(Entry::getKey)
             .get();
     System.out.println(maxAppearedElement);

     } 
}

0

สำหรับโครงการของฉันฉันใช้โซลูชันของจอนและฟาธาห์เวอร์ชันที่ปรับเปลี่ยนเล็กน้อย ในกรณีที่มีหลายรายการที่มีค่าเดียวกันจะส่งกลับรายการสุดท้ายที่พบ:

public static Entry<String, Integer> getMaxEntry(Map<String, Integer> map) {        
    Entry<String, Integer> maxEntry = null;
    Integer max = Collections.max(map.values());

    for(Entry<String, Integer> entry : map.entrySet()) {
        Integer value = entry.getValue();

        if(null != value && max == value) {
            maxEntry = entry;
        }
    }

    return maxEntry;
}

0
int maxValue = 0;
int mKey = 0;
for(Integer key: map.keySet()){
    if(map.get(key) > maxValue){
        maxValue = map.get(key);
        mKey = key;
    }
}
System.out.println("Max Value " + maxValue + " is associated with " + mKey + " key");

2
โดยทั่วไปคำตอบที่ใช้รหัสเท่านั้นในฟอรัมนี้ โปรดแก้ไขคำตอบของคุณเพื่อรวมคำอธิบายรหัสของคุณ วิธีแก้ปัญหาของ OP
mypetlion

-2

คุณสามารถทำเช่นนั้นได้

HashMap<Integer,Integer> hm = new HashMap<Integer,Integer>();
hm.put(1,10);
hm.put(2,45);
hm.put(3,100);
Iterator<Integer> it = hm.keySet().iterator();
Integer fk = it.next();
Integer max = hm.get(fk);
while(it.hasNext()) {
    Integer k = it.next();
    Integer val = hm.get(k);
    if (val > max){
         max = val;
         fk=k;
    }
}
System.out.println("Max Value "+max+" is associated with "+fk+" key");
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.