迭代并比较相同地图中的值以查找最大值并从同一地图中删除其他值

时间:2014-05-07 17:55:40

标签: java map

我有

Map<Key,Integer> myMap= new HashMap<Key,Integer>();

假设我在地图中有元素,如

 myMap.put(k1,5);
 myMap.put(k2,20);
 myMap.put(k3,10);
 myMap.put(k4,15);

我应该尝试迭代和比较此映射中的值的代码,并且我希望map元素具有最大值,map也应仅包含该元素。

4 个答案:

答案 0 :(得分:0)

我会使用包装类:

public class MyMapWrapper<K, V extends Comparable> {

    private V maximum;
    private K maxKey;
    private final Map<K, V> map = new HashMap<>();
    private final Comparator<V> comp;

    public MyMapWrapper() {
        this(new Comparator<V>() {

            public int compareTo(V v1, V v2) {
                return (v1 == null) ? ((v2 == null) ? 0 : -1) : v1.compareTo(v2);
            }

        });
    }

    public MyMapWrapper(Comparator<V> comp) {
        if (comp == null) {
            //Comparator should not be null
            throw new IllegalArgumentException("Comparator cannot be null!");
        }
        this.comp = comp;
    }

    public V getMaximum() {
        return this.maximum;
    }

    public K getMaximumKey() {
        return this.maxKey;
    }

    public int put(K key, V value) {
        if (value == null) {
            //You don't want null comparables, can either throw an exception or ignore
            throw new IllegalArgumentException("No null values allowed!");
        }
        if (this.maximum == null || this.comp.compareTo(this.maximum, value) > 0) {
            this.maximum = value;
            this.maxKey = key;
        }
        return this.map.put(key, value);
    }

    public int remove(K key) {
        V back = this.map.remove(key);
        if (this.maximum.equals(back)) {
            K newKey = null;
            V newMax = null;
            //search map for new maximum
            for (Map.Entry<K, V> ent : this.map.entrySet()) {
                if (this.comp.compareTo(ent.getValue(), newMax) > 0) {
                    newMax = ent.getValue();
                    newKey = ent.getKey();
                }
            }
            this.maximum = newMax;
            this.maxKey = newKey;
        }
        return back;
    }

    public V get(K key) {
        return this.map.get(key);
    }

}

如果需要其他特定方法,您可以这样做,但这只需要使用一个“地图”:

MyMapWrapper<String, Integer> example = new MyMapWrapper<>();
example.put("test1", 14);
example.put("test2", 3450);
example.put("test4", -142);
System.out.println(String.format("Max key: %s, Max value: %d", example.getMaximumKey(), example.getMaximum());
//Max key: "test2", Max value: 3450

这也允许自定义比较器的值:

MyMapWrapper<String, Integer> example = new MyMapWrapper<>(new Comparator<Integer>() {

    public int compareTo(Integer v1, Integer v2) {
        return (v2 == null) ? ((v1 == null) ? 0 : -1) : v2.compareTo(v1);
    }

});
example.put("test1", 14);
example.put("test2", 3450);
example.put("test4", -142);
System.out.println(String.format("Max key: %s, Max value: %d", example.getMaximumKey(), example.getMaximum());
//Max key: "test4", Max value: -142

答案 1 :(得分:0)

简单的解决方案是使用并发hashmap。试试这个..

import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

public class Largest {

    public static void main(String[] args) {
        Map<Integer, Integer> myMap = new HashMap<Integer, Integer>();
        myMap.put(1, 5);
        myMap.put(2, 20);
        myMap.put(3, 10);
        myMap.put(4, 15);
        myMap.put(5, 20);

        System.out.println(myMap);

        Map<Integer, Integer> concurrentMap = new ConcurrentHashMap<Integer, Integer>(myMap);

        Integer maxKey = concurrentMap.keySet().iterator().next();
        Integer max = myMap.get(maxKey);

        for(Integer key : concurrentMap.keySet()){
            Integer currValue = concurrentMap.get(key);
            if(max > currValue){
                concurrentMap.remove(key);
            } else if(max < currValue) {
                concurrentMap.remove(maxKey);
                max = concurrentMap.get(key);
                maxKey = key;
            }
        }

        System.out.println(concurrentMap);
    }

}

答案 2 :(得分:0)

如果您只想使用定义的Entry获取Map使用Collections.max中的最大Comparator

Map<Key, Integer> myMap= new HashMap<Key,Integer>();
myMap.put(k1,5);
myMap.put(k2,20);
myMap.put(k3,10);
myMap.put(k4,15);

Entry<Key, Integer> maxEntry = Collections.max(myMap.entrySet(), 
    new Comparator<Entry<Key, Integer>>(){
        @Override public int compare(Entry<Key, Integer> e1, Entry<Key, Integer> e2) {
            return e1.getValue().compareTo(e2.getValue());
        }
    });

// outputs k2=20
System.out.print(maxEntry);

如果你真的想在最后有1个条目地图,你可以清除旧的地图并添加maxEntry

myMap.clear();
myMap.put(maxEntry.key(), maxEntry.value());

答案 3 :(得分:0)

如果你有java 8,你可以这样做:

<强> CODE

public class MapFiltering {

    public static void main(String[] args) {
        Random rnd = new Random();
        Map<String, Integer> myMap = new HashMap<>();
        int i = 1;
        for (int j = 0; j < 10; j++) {
            myMap.put("k" + j, rnd.nextInt(100));
        }
        System.out.println("BEFORE");
        printMap(myMap);
        filterMap(myMap);
        System.out.println("AFTER");
        printMap(myMap);
    }

    private static void printMap(Map<String, Integer> map) {
        map.entrySet().stream().forEach((e) -> {
            System.out.println("K=" + e.getKey() + " V=" + e.getValue());
        });
    }

    private static void filterMap(Map<String, Integer> map) {
        Map.Entry<String, Integer> get
                = map.entrySet()
                .stream()
                .max((Comparator<? super Map.Entry<String, Integer>>) new Comparator<Map.Entry<String, Integer>>() {

                    @Override
                    public int compare(Map.Entry<String, Integer> o1, Map.Entry<String, Integer> o2) {
                        return o1.getValue().compareTo(o2.getValue());
                    }
                }).get();
        map.clear();
        map.put(get.getKey(), get.getValue());
    }
}

示例输出

BEFORE
K=k0 V=66
K=k1 V=5
K=k2 V=34
K=k3 V=54
K=k4 V=52
K=k5 V=69
K=k6 V=34
K=k7 V=62
K=k8 V=73
K=k9 V=28
AFTER
K=k8 V=73