我的问题是如何根据值和键对映射
内容进行排序,并得到一个列表
?
首先,条目需要按值降序排序,如果值发生冲突,也要按键降序排序。
给定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]
编写一个比较器
为此,您需要定义一个比较器
。
为此,您可以使用静态方法,这些方法是作为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]
使用流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上的示例,我的眼睛呆呆了!非常感谢!!! 问题答案: 看一