英文:
How to flatten and sort a HashMap with ArrayList values in Java?
问题
所以,我有一个哈希映射,其中键为字符串,值为ArrayList。
static HashMap<String, ArrayList
然后我只是使用Scanner类请求输入:
Scanner sc = new Scanner(System.in);
String input = sc.nextLine();
String[] inputArr = input.split(" ");
然后,如果玩家存在,我只需将分数添加给他,如果不存在,它会创建一个新条目:
for (int i = 0; i < inputArr.length; i += 2) {
String UID = inputArr[i];
int score = Integer.parseInt(inputArr[i + 1]);
if (!scores.containsKey(UID)) {
ArrayList<Integer> list = new ArrayList<>();
list.add(score);
scores.put(UID, list);
} else {
scores.get(UID).add(score);
}
}
所以,例如,如果我在控制台中输入`1 100 2 200 3 300 1 200`,
我会得到`{1=[100, 200], 2=[200], 3=[300]}`
现在我需要这个哈希映射被“打开”,看起来像这样:`3 300 1 200 2 200 1 100`。
请注意,输出按**值**降序排序。
我还尝试过不同的方法,如SortedTreeMap或TreeBag,但似乎都不起作用。
英文:
So, I have a hashmap which has a String as key, and an Arraylist as Value.
static HashMap<String, ArrayList<Integer>> scores = new HashMap<>();
Then I just request Input with the Scanner Class:
Scanner sc = new Scanner(System.in);
String input = sc.nextLine();
String[] inputArr = input.split(" ");
And then I just add the score to the player if he exists, and if he doesn't it just creates a new entry
for (int i = 0; i < inputArr.length; i += 2) {
String UID = inputArr[i];
int score = Integer.parseInt(inputArr[i + 1]);
if (!scores.containsKey(UID)) {
ArrayList<Integer> list = new ArrayList<>();
list.add(score);
scores.put(UID, list);
} else {
scores.get(UID).add(score);
}
}
So for example, if I Input 1 100 2 200 3 300 1 200 into the console,
I receive {1=[100, 200], 2=[200], 3=[300]}
Now what I need is this Hashmap to be "opened up" and look like this: 3 300 1 200 2 200 1 100.
Note that the Output is sorted descending by value.
I also tried different methods, like a SortedTreeMap or a TreeBag, but none of them seem to work
答案1
得分: 2
你可以在地图的条目上执行flatMap操作,将每个String条目转换为List<Integer>,形成多个String到Integer的条目流。然后,你可以使用你喜欢的比较器对条目进行排序。
var result = scores.entrySet().stream()
.flatMap(
entry -> entry.getValue().stream().map(v -> Map.entry(entry.getKey(), v))
)
.sorted(
Map.Entry.<String, Integer>comparingByValue().reversed()
// if you would like to also break ties on the values by comparing the keys
//.thenComparing(Map.Entry.comparingByKey())
)
.toList();
result是一个List<Entry<String, Integer>>。打印result会得到:
[3=300, 1=200, 2=200, 1=100]
另外,请注意,将用户输入添加到地图的if语句可以简化为以下使用computeIfAbsent的形式:
scores.computeIfAbsent(UID, x -> new ArrayList<>()).add(score);
(注意:这是你的代码的翻译,不包括代码部分。)
英文:
You could do a flatMap on the map's entries, transforming each entry of String to List<Integer>, into a stream of multiple entries of String to Integer. Then you can just sort the entries with a comparator you prefer.
var result = scores.entrySet().stream()
.flatMap(
entry -> entry.getValue().stream().map(v -> Map.entry(entry.getKey(), v))
)
.sorted(
Map.Entry.<String, Integer>comparingByValue().reversed()
// if you would like to also break ties on the values by comparing the keys
//.thenComparing(Map.Entry.comparingByKey())
)
.toList();
result is a List<Entry<String, Integer>>. Printing result gives you
[3=300, 1=200, 2=200, 1=100]
Also note that your if statement for adding the user input into the map can be simplified to the following using computeIfAbsent:
scores.computeIfAbsent(UID, x -> new ArrayList<>()).add(score);
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。


评论