根据列表值

时间:2016-08-31 08:52:16

标签: java sorting collections

我有一张如下地图:

Map<String, String> map1 = new HashMap<String, String>();

,内容如下:

ID_1 -> ID_2
------------
100 -> 10
200 -> 20
300 -> 30

根据ID_2的值,我必须查询oracle表并获取与每个条目对应的代码值:

ID_1 -> ID_2 -> code
--------------------
100 -> 10 -> 8
200 -> 20 -> 2
300 -> 30 -> 9

然后我将得到map1按代码值按升序排序,即结果应为:

200 -> 20
100 -> 10
300 -> 30

我曾考虑使用<ID_1, List<ID_2,code>>创建一个中间地图作为<K,V>,然后使用代码值进行排序,然后获得最终输出。

有没有更短的方法,比如不使用中间地图?

4 个答案:

答案 0 :(得分:1)

您可以尝试以下代码:我使用int[]数组而不是List

public class Test {

    public static void main(String[] args) throws Exception {
        Map<String, int[]> map = new HashMap<>();
        map.put("100", new int[]{10, 8});
        map.put("200", new int[]{20, 2});
        map.put("300", new int[]{30, 9});

        Map<String, int[]> sortByValue = sortByValue(map);
        for (Map.Entry<String, int[]> entry : sortByValue.entrySet()) {
            System.out.println(entry.getKey() +" -> "+ entry.getValue()[0]);
        }

    }

    private static Map<String, int[]> sortByValue( Map<String, int[]> map ) {
        List<Map.Entry<String, int[]>> list = new LinkedList<>(map.entrySet());
        Collections.sort(list, (o1, o2) -> Integer.compare(o1.getValue()[1], o2.getValue()[1]));
        Map<String, int[]> result = new LinkedHashMap<>();
        for (Map.Entry<String, int[]> entry : list) {
            result.put(entry.getKey(), entry.getValue());
        }
        return result;
    }
}

结果是:

200 -> 20
100 -> 10
300 -> 30

答案 1 :(得分:0)

基于map1,您可以构建新地图:

 Map<String, Pair<String, String> map2

其中key是来自oracle db的id。

由于您需要订购,您可以使用TreeMap和方法

Map.Entry<K,V> firstEntry();

答案 2 :(得分:0)

我会表达你的逻辑如下:

  1. 获取地图中的所有条目
  2. 影响每个人的得分(通过数据库通话)
  3. 根据步骤2
  4. 在最终地图中订购条目

    重要的是要注意很少的地图有排序约束。想到的基础实现是LinkedHashMap。此外&#34;重新排序现有地图&#34;似乎是一个奇怪的想法,没有Map 接口中的任何方法支持。所以简而言之,说你需要返回一个具有排序约束的Map似乎是一个糟糕/不完整的想法 - 但它肯定是可行的。

    我也反对使用TreeMap这是Comparator排序的地图,因为我没有看到你的排序值是唯一的约束。另外,您的排序取决于地图的值,而不是键。这样的比较器根本不是直截了当的。

    所以,简而言之,我要做的是

        LinkedHashMap<String, String> sorted = map.entrySet().stream()
            // This is your DB call
            .sorted(Comparator.comparing(entry -> getDBValue(entry)))
            // Now we have an ordered stream of key/value entries from the original map
            .collect(
                // We flush back to a Map
                Collectors.toMap(
                        // Keeping the original keys as is
                        Map.Entry::getKey, 
                        // Keeping the original values as is
                        Map.Entry::getValue, 
                        // This merge step should never be called, as keys are unique. Maybe you could assert that and fail if this is called
                        (v1, v2) -> v1,
                        // This is where you instanciate the Map that respects ordering of keys. Here, LinkedHashMap is iterable in the order of insertion, which is what we want.
                        LinkedHashMap::new
                      )
        );
    

答案 3 :(得分:0)

使用Java流,您可以在不使用任何其他集合的情况下实现此目的,这是一个实现。

维护订单已在收集器中使用LinkedHashMap

为了简单起见,我又花了一个地图来保存数据库值[你需要改变它来从数据库获取]

    Map<String, String> map1 = new HashMap<String, String>();
    map1.put("100", "10");
    map1.put("200", "20");
    map1.put("300", "30");

    Map<String, String> dbmap = new HashMap<String, String>();
    dbmap.put("10", "8");
    dbmap.put("20", "2");
    dbmap.put("30", "9");

    Comparator<String> comp = (k1, k2) -> dbmap.get(map1.get(k1)).compareTo(dbmap.get(map1.get(k2)));

    Map<String, String> queryMap = map1.keySet().stream().sorted(comp)
            .collect(toMap((String key) -> key, value -> (String) map1.get(value), (u, v) -> {
                throw new IllegalStateException(String.format("Duplicate key %s", u));
            }, LinkedHashMap::new));

    System.out.println(queryMap);

<强>输出继电器

{200=20, 100=10, 300=30}