当前位置: 首页 > 知识库问答 >
问题:

如何从地图中获取按值排序然后按键排序的条目列表

龚凌
2023-03-14

我的问题是如何根据值和键对映射内容进行排序,并得到一个列表

首先,条目需要按值降序排序,如果值发生冲突,也要按键降序排序。

给定Map的示例:

Map<String,Integer> data = new HashMap();
data.put("a",10);
data.put("b",3);
data.put("c",10);

预期订单:

["c", 10], ["a",10], ["b",3]

共有3个答案

孔欣荣
2023-03-14

编写一个比较器

陶胤运
2023-03-14

为此,您需要定义一个比较器

为此,您可以使用静态方法,这些方法是作为Java8的增强添加到比较器Map. Entry接口的。

这两种方法都是映射的comparingByValue()comparingByKey()。输入接口将分别为值和键生成一个比较器。为了获得降序reversed()方法需要应用于它们。

这两个比较器是链接在一起的那么比较()方法。

Comparator<Map.Entry<String, Integer>> valDescThenKeyDesc =
       Map.Entry.<String, Integer>comparingByValue().reversed()
           .thenComparing(Map.Entry.<String, Integer>comparingByKey().reversed());

请注意,编译器无法仅根据比较器的结果类型推断比较ByValue()比较ByKey()的参数的正确类型。

因此,comparingByValue()comparingByKey()都需要显式地提供泛型类型信息

有关如何使用Java8方法构建比较器的详细信息,请参阅本教程

下一步是创建一个有序的条目列表。

为此,您可以通过将条目集传递给构造函数,然后在其上应用方法sort(),或者通过使用流API,手动创建条目的列表

为了用流实现它,首先,我们需要获得一个条目流。通过传递给定的比较器应用sorting()操作,并通过应用终端操作collect()将结果收集到列表中。

public static List<Map.Entry<String, Integer>> getMapEntryList(Map<String,Integer> data,
                                                               Comparator<Map.Entry<String, Integer>> comparator) {
    return data.entrySet().stream()
            .sorted(comparator)
            .collect(Collectors.toList());
}

main()

public static void main(String[] args) {
    Map<String,Integer> data = Map.of("a",10, "b",3,"c",10);

    Comparator<Map.Entry<String, Integer>> valDescThenKeyDesc =
            Map.Entry.<String, Integer>comparingByValue().reversed()
                    .thenComparing(Map.Entry.<String, Integer>comparingByKey().reversed());

    List<Map.Entry<String, Integer>> result = getMapEntryList(data, valDescThenKeyDesc);
    
    System.out.println(result);
}

输出

[c=10, a=10, b=3]

芮瑾瑜
2023-03-14

使用流api和自定义比较器。

    static int comparer(Map.Entry<String, Integer> e1, Map.Entry<String, Integer> e2) {
        //* 1000 here just to make sure value has higher priority
        // maybe *3 is already enough?
        // just want to avoid if else here
        return e2.getValue().compareTo(e1.getValue()) * 1000
                + e2.getKey().compareTo(e1.getKey());
    }

    public static void main(String args[]){
        Map<String, Integer> data = new HashMap();
        data.put("a", 10);
        data.put("b", 3);
        data.put("c", 10);
        data.entrySet().stream()
                .sorted((o1, o2) -> comparer(o1, o2))
                .forEach((kv -> System.out.println(
                        String.format("%s\t%s", kv.getKey(), kv.getValue()))));
//            c 10
//            a 10
//            b 3
        }
    }
 类似资料:
  • 我有一个类似于以下内容的HashMap: 有什么建议吗? 我首先比较值,只有在值重复的情况下才比较键。所以我同时使用键和值,而不仅仅是值。

  • 我有一个,我希望在其中返回字符串值的列表,但按int键的升序/降序排序。如果返回的是我也希望排序的迭代项,例如返回或列表,那么这将很容易,但是我想不出一种方法来做到这一点,除了在使用遍历整个映射并插入值以从映射键索引(如下面所示)之后手动创建一个列表,然后在该列表中嵌套另一个以消除任何空值之外。 请告诉我有更好更有效的方法吗?任何帮助都是非常感谢的!

  • 问题内容: 我正在使用map接口从文件中读取,然后将其中的值存储为键值对。文件格式如下 我将从该文件中读取数据并将其存储为键值对,然后将其显示给用户。我的要求是以这种格式显示结果 因此,我需要按值的降序对地图进行排序。这样我就可以将它们显示为我的结果..我已经阅读了有关此内容并找到了以下代码 我希望这将按升序对值进行排序,我只想知道此方法是否正确,或者其他有效方法对我有帮助? 问题答案: 由于您可

  • 问题内容: 我想在键和值上对地图进行排序。首先是关键,然后是价值。例如,这应该是结果; 有人对如何有效地实现这一目标有建议吗?我一直在看到人们使用TreeMap对键进行排序,但是我也需要值。 或者欢迎使用其他对键和值进行排序的方法。 问题答案:

  • 问题内容: 在发现了惊人的发现之后,我再次陷入了困境。 问题是我有一个形式的字典,我需要按其整数值的降序对其进行排序, 但是 如果两个元素的值相同,则按键的升序排列。 一个使它更清楚的例子: 经过研究后,我得出以下结论: 这是因为它对值和键都进行了反向排序。我需要不撤消的钥匙。 问题答案: 就像是

  • 问题内容: 我有一个带有数字值的字符串键数组,可用于具有每个标签出现次数的标签列表中,因此: 这是为了我可以按降序显示标签列表,因此: 我可以使用 arsort 通过出色的值进行反向排序,但是我还希望具有相同数字值的所有标签都按字母顺序排序,因此最终结果可以是: 有办法可以做到吗?我猜想 usort 可能是要走的路,但是我看了php.net上的示例,我的眼睛呆呆了!非常感谢!!! 问题答案: 看一