简体   繁体   English

在java中排序2d数据结构

[英]sorting a 2d data structure in java

I need to sort a 2d key/value pair by the value. 我需要按值对2d键/值对进行排序。 I have read many references about this on the web and have ended up writing my own class to do this using HashMaps(see below). 我已经在网上阅读了很多关于这个的参考资料,并且最终编写了我自己的类来使用HashMaps(见下文)。 I put the code into a condensed working class that reproduces the problem with the minimum amount of code so that you can just cut and paste it into your IDE for quick diagnostics. 我将代码放入一个精简的工作类中,用最少量的代码重现问题,这样您就可以将其剪切并粘贴到IDE中以进行快速诊断。

As you can see, the method that I wrote is correctly sorting the values before they are entered into sortedMap. 正如您所看到的,我编写的方法是在将值输入sortedMap之前正确对值进行排序。 However, for some reason, they values are then again unordered in a different way when I try to subsequently iterate through sortedMap. 但是,出于某种原因,当我尝试随后迭代sortedMap时,它们的值再次以不同的方式排序。

Can anyone show me how to fix the code below so that I iterate through a resulting 2D data object that gives me my data in descending order? 任何人都可以告诉我如何修复下面的代码,以便迭代生成的2D数据对象,以降序为我提供数据?


EDIT: Re-wrote using TreeMaps, and am still getting a similar problem. 编辑:使用TreeMaps重写,我仍然遇到类似的问题。 Here is the re-written code: 这是重写的代码:

import java.util.*;

public class HashMapDemo {
    public static void main(String args[]) {

        // Code that creates and populates the unordered HashMap:
        TreeMap<Integer, Double> unSortedMap = new TreeMap<Integer, Double>();
        unSortedMap.put(1343, 0.521851);
        unSortedMap.put(1950, -0.301208);
        unSortedMap.put(3667, -0.0280762);
        unSortedMap.put(3879, 0.154724);
        unSortedMap.put(4124, 0.022583);

        // Code that calls the ordering method:
        TreeMap<Integer, Double> sortedMap = new TreeMap<Integer, Double>(
                sortTreeMap(unSortedMap));

        // Code that iterates through the "sorted" hashmap.
        System.out.println("now iterate through sortedMap: ");
        for (Integer key : sortedMap.keySet()) {
            System.out.println("key, sortedMap.get(key) are:  " + key + ", "
                    + sortedMap.get(key));
        }
    }

    // Code for the ordering method. Note that the println tests indicate that
    // this method is correctly sorting the key/value pairs in the hashmap:
    private static TreeMap<Integer, Double> sortTreeMap(
            TreeMap<Integer, Double> input) {

        System.out
                .println("input.size() upon entering sortHasMap() function is: "
                        + input.size());
        int startSize = input.size();

        // create a hashmap to store sorted output
        TreeMap<Integer, Double> sortedMap = new TreeMap<Integer, Double>();

        // repeat the following process once for every key/value pair in the
        // hashmap
        for (int i = 0; i < startSize; i++) {
            int mySize = input.size();
            System.out.println("mySize is: " + mySize);
            double maxVal = Double.NEGATIVE_INFINITY;
            int maxKey = 0;

            // iterate through each key in hashmap to find key/value of max
            // value
            for (Integer key : input.keySet()) {
                if (maxVal < input.get(key)) {
                    maxVal = input.get(key);
                    maxKey = key;
                }
            }

            // add key/value of max of that iteration to sorted map and remove
            // from input before next iteration
            sortedMap.put(maxKey, maxVal);

            input.remove(maxKey);

            System.out.println("sortedMap.put(maxKey, maxVal) are: " + maxKey
                    + ", " + maxVal);
        }
        return sortedMap;
    }
}

You need only two lines to achieve what you want. 需要两条线来实现你想要的。 Here are those two lines: 以下是这两行:

    Map<Integer, Double> sortedMap = new TreeMap<Integer, Double>(new Comparator<Integer>() {
        public int compare(Integer o1, Integer o2) {
            return map.get(o2).compareTo(map.get(o1)); // reverse order of values
        }
    });
    sortedMap.putAll(map);

Here's the complete runnable code: 这是完整的可运行代码:

public static void main(String[] args) {
    final Map<Integer, Double> map = new HashMap<Integer, Double>();
    map.put(1343, 0.521851);
    map.put(1950, -0.301208);
    map.put(3667, -0.0280762);
    map.put(3879, 0.154724);
    map.put(4124, 0.022583);
    Map<Integer, Double> sortedMap = sortMap(map);

    for (Map.Entry<Integer, Double> entry : sortedMap.entrySet()) {
        System.out.println(entry.getKey() + ", " + entry.getValue());
    }
}

public static Map<Integer, Double> sortMap(final Map<Integer, Double> map) {
    Map<Integer, Double> sortedMap = new TreeMap<Integer, Double>(new Comparator<Integer>() {
        public int compare(Integer o1, Integer o2) {
            return map.get(o2).compareTo(map.get(o1));
        }
    });
    sortedMap.putAll(map);
    return sortedMap;
}

Output: 输出:

1343, 0.521851
3879, 0.154724
4124, 0.022583
3667, -0.0280762
1950, -0.301208

Notes: You specify how you want entries ordered in a TreeSet by passing the Comparator you want to use into the constructor. 注意:您可以指定要通过传递您要使用到构造的比较在一个TreeSet排序项。 The TreeSet implementation does the rest. TreeSet实现完成剩下的工作。

Other notes: 其他说明:

  • The best way to iterate over the keys/values of a map is by iterating over Map.entrySet() 迭代地图的键/值的最佳方法是迭代Map.entrySet()
  • Always use the abstract type for your variables - eg Map<?, ?> myMap not the concrete implementation (ie HashMap<?, ?> myMap ) 总是使用抽象类型作为变量 - 例如Map<?, ?> myMap 而不是具体的实现(即HashMap<?, ?> myMap

Here's the generic version of the sortMap method that will sort any suitable map based on the reverse order of the values: 这是sortMap方法的通用版本,它将根据值的相反顺序对任何合适的映射进行排序:

public static <K, V extends Comparable<V>> Map<K, V> sortMap2(final Map<K, V> map) {
    Map<K, V> sortedMap = new TreeMap<K, V>(new Comparator<K>() {
        public int compare(K o1, K o2) {
            return map.get(o2).compareTo(map.get(o1));
        }
    });
    sortedMap.putAll(map);
    return sortedMap;
}

Use a TreeMap . 使用TreeMap Its a SortedMap that uses the natural ordering of keys. 它是一个使用键的自然排序的SortedMap In your case, it will order by the Integer key. 在您的情况下,它将按Integer键排序。

It does the sorting for you. 它为您排序。

java.util.HashMap is unordered. java.util.HashMap是无序的。

This class makes no guarantees as to the order of the map; 这个类不保证地图的顺序; in particular, it does not guarantee that the order will remain constant over time. 特别是,它不保证订单会随着时间的推移保持不变。

EDIT After reading the question correctly EDIT 正确阅读问题后

Use a Comparator for the TreeMap constructor that compares the values. 比较器用于比较值的TreeMap构造函数。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM