Tìm khóa được liên kết với Giá trị tối đa trong Bản đồ Java


137

Cách dễ nhất để lấy khóa được liên kết với giá trị tối đa trong bản đồ là gì?

Tôi tin rằng Collections.max (someMap) sẽ trả về Khóa tối đa, khi bạn muốn khóa tương ứng với giá trị tối đa.

Câu trả lời:


136

Về cơ bản, bạn cần lặp lại bộ nhập của bản đồ, ghi nhớ cả "mức tối đa được biết hiện tại" và khóa được liên kết với nó. (Hoặc chỉ là mục chứa cả hai, tất nhiên.)

Ví dụ:

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

40
+1: Bạn có thể có nhiều hơn một khóa có cùng giá trị tối đa. Vòng lặp này sẽ cung cấp cho bạn cái đầu tiên mà nó tìm thấy.
Peter Lawrey

21
Thay đổi> 0 thành> = 0 sẽ cung cấp cho bạn cái cuối cùng mà nó tìm thấy
Aaron J Lang

1
Việc sử dụng luồng Java 8 sẽ giúp đơn giản hóa việc này nữa? ví dụ: map.forEach ((k, v) -> ...
zkarthik

3
@zkarthik: Sử dụng maxvới một bộ so sánh tùy chỉnh có lẽ sẽ đơn giản hơn.
Jon Skeet

112

Để cho đầy đủ, đây là một cách làm

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

hoặc là

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

hoặc là

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

3
(entry1, entry2) -> entry1.getValue() - entry2.getValue()nhỏ gọn hơn cho bộ so sánh.
JustABit

5
Phải làm gì nếu tôi muốn tất cả các khóa khớp với giá trị tối đa?
Mouna

4
Nhỏ gọn nhưng khó hiểu.
Lluis Martinez

1
Bạn cũng có thể sử dụng phương thức so sánh được cung cấp bởi lớp IntegercountMap.entrySet().stream().max((entry1, entry2) -> Integer.compare(entry1.getValue(), entry2.getValue())).get().getKey();
Rui Filipe Pedro

3
Hoặc bạn có thể sử dụng Map.Entry.comparingByValue()thay thế
Alexey Grigorev

54

Mã này sẽ in tất cả các khóa có giá trị tối đa

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

    }
}

47

Một lớp lót đơn giản sử dụng Java-8

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


3
Giải pháp thanh lịch và tối giản nhất. Cảm ơn
Daniel Hári

@Samir, Vui lòng kiểm tra phiên bản Java của bạn. Sleiman Jneid đã đề cập rõ ràng rằng nó sẽ hoạt động với Java 8
Vaibs

@Vaibs Tôi đã sử dụng Java 8. Không còn quan trọng nữa, câu trả lời của Hilikus đã có hiệu quả với tôi.
Samir

Nó hoạt động với tôi như thế này: String max_key = Collections.max(map.entrySet(), Map.Entry.comparingByValue()).getKey();
Timur Nurlygayanov

8

Dưới đây là cách thực hiện trực tiếp (không có vòng lặp phụ rõ ràng) bằng cách xác định thích hợp 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

Câu trả lời trả về Tùy chọn vì bản đồ có thể không có giá trị tối đa nếu nó trống: map.entrySet().stream().max(Map.Entry.comparingByValue()).map(Map.Entry::getKey);


4

Java 8 cách để có được tất cả các khóa có giá trị tối đa.

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

Ngoài ra, bạn có thể song song nó bằng cách sử dụng parallelStream()thay vìstream()


4

Tôi có hai phương thức, sử dụng méthod này để lấy khóa với giá trị tối đa:

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

Như một ví dụ gettin Entry với giá trị tối đa bằng phương thức:

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

Sử dụng Java 8, chúng ta có thể nhận được một đối tượng chứa giá trị tối đa:

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

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

Phiên bản java 8 đơn giản nhưng hiệu quả! Làm việc tốt
Catbuilts

3

1. Sử dụng luồng

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. Sử dụng Collections.max () với Biểu thức Lambda

    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. Sử dụng Stream với tham chiếu phương thức

    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. Sử dụng 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. Sử dụng phép lặp đơn giản

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

Đã xem qua Baldung.com baeldung.com/java-find-map-max
Ngài Montes

2

Đơn giản để hiểu. Trong mã Dưới đây, maxKey là khóa giữ giá trị tối đa.

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

1

Giải pháp này có ổn không?

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

Phần tử đa số / phần tử tối đa trong bản đồ:

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

     } 
}

1

bản đồ đã cho

HashMap abc = HashMap mới <> ();

nhận được tất cả các mục bản đồ với tối đa các giá trị.

bạn có thể sử dụng bất kỳ phương pháp nào dưới đây trong bộ lọc để nhận các mục nhập bản đồ tương ứng cho các bộ giá trị tối thiểu hoặc tối đa

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

nếu chỉ muốn lấy các phím cho bản đồ lọc

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

nếu bạn muốn lấy các giá trị cho bản đồ được lọc

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

nếu bạn muốn nhận tất cả các khóa như vậy trong danh sách:

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

nếu bạn muốn nhận tất cả các giá trị như vậy trong danh sách:

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

0

Đối với dự án của tôi, tôi đã sử dụng một phiên bản sửa đổi một chút của giải pháp của Jon và Fathah. Trong trường hợp có nhiều mục có cùng giá trị, nó sẽ trả về mục cuối cùng mà nó tìm thấy:

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
Các câu trả lời chỉ có mã thường được tán thành trên diễn đàn này. Vui lòng chỉnh sửa câu trả lời của bạn để bao gồm một lời giải thích về mã của bạn. Làm thế nào để giải quyết vấn đề của OP?
mypetlion

-2

bạn có thể làm như thế

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");
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.