如何在Java中扁平化和排序具有ArrayList值的HashMap?

huangapple go评论101阅读模式
英文:

How to flatten and sort a HashMap with ArrayList values in Java?

问题

  1. 所以,我有一个哈希映射,其中键为字符串,值为ArrayList

static HashMap<String, ArrayList> scores = new HashMap<>();

  1. 然后我只是使用Scanner类请求输入:

Scanner sc = new Scanner(System.in);
String input = sc.nextLine();

String[] inputArr = input.split(" ");

  1. 然后,如果玩家存在,我只需将分数添加给他,如果不存在,它会创建一个新条目:

for (int i = 0; i < inputArr.length; i += 2) {

  1. String UID = inputArr[i];
  2. int score = Integer.parseInt(inputArr[i + 1]);
  3. if (!scores.containsKey(UID)) {
  4. ArrayList<Integer> list = new ArrayList<>();
  5. list.add(score);
  6. scores.put(UID, list);
  7. } else {
  8. scores.get(UID).add(score);
  9. }

}

  1. 所以,例如,如果我在控制台中输入`1 100 2 200 3 300 1 200`
  2. 我会得到`{1=[100, 200], 2=[200], 3=[300]}`
  3. 现在我需要这个哈希映射被“打开”,看起来像这样:`3 300 1 200 2 200 1 100`
  4. 请注意,输出按**值**降序排序。
  5. 我还尝试过不同的方法,如SortedTreeMapTreeBag,但似乎都不起作用。
英文:

So, I have a hashmap which has a String as key, and an Arraylist as Value.

  1. static HashMap&lt;String, ArrayList&lt;Integer&gt;&gt; scores = new HashMap&lt;&gt;();

Then I just request Input with the Scanner Class:

  1. Scanner sc = new Scanner(System.in);
  2. String input = sc.nextLine();
  3. String[] inputArr = input.split(&quot; &quot;);

And then I just add the score to the player if he exists, and if he doesn't it just creates a new entry

  1. for (int i = 0; i &lt; inputArr.length; i += 2) {
  2. String UID = inputArr[i];
  3. int score = Integer.parseInt(inputArr[i + 1]);
  4. if (!scores.containsKey(UID)) {
  5. ArrayList&lt;Integer&gt; list = new ArrayList&lt;&gt;();
  6. list.add(score);
  7. scores.put(UID, list);
  8. } else {
  9. scores.get(UID).add(score);
  10. }
  11. }

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&lt;Integer&gt;,形成多个StringInteger的条目流。然后,你可以使用你喜欢的比较器对条目进行排序。

  1. var result = scores.entrySet().stream()
  2. .flatMap(
  3. entry -&gt; entry.getValue().stream().map(v -&gt; Map.entry(entry.getKey(), v))
  4. )
  5. .sorted(
  6. Map.Entry.&lt;String, Integer&gt;comparingByValue().reversed()
  7. // if you would like to also break ties on the values by comparing the keys
  8. //.thenComparing(Map.Entry.comparingByKey())
  9. )
  10. .toList();

result是一个List&lt;Entry&lt;String, Integer&gt;&gt;。打印result会得到:

  1. [3=300, 1=200, 2=200, 1=100]

另外,请注意,将用户输入添加到地图的if语句可以简化为以下使用computeIfAbsent的形式:

  1. scores.computeIfAbsent(UID, x -&gt; new ArrayList&lt;&gt;()).add(score);

(注意:这是你的代码的翻译,不包括代码部分。)

英文:

You could do a flatMap on the map's entries, transforming each entry of String to List&lt;Integer&gt;, into a stream of multiple entries of String to Integer. Then you can just sort the entries with a comparator you prefer.

  1. var result = scores.entrySet().stream()
  2. .flatMap(
  3. entry -&gt; entry.getValue().stream().map(v -&gt; Map.entry(entry.getKey(), v))
  4. )
  5. .sorted(
  6. Map.Entry.&lt;String, Integer&gt;comparingByValue().reversed()
  7. // if you would like to also break ties on the values by comparing the keys
  8. //.thenComparing(Map.Entry.comparingByKey())
  9. )
  10. .toList();

result is a List&lt;Entry&lt;String, Integer&gt;&gt;. Printing result gives you

  1. [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:

  1. scores.computeIfAbsent(UID, x -&gt; new ArrayList&lt;&gt;()).add(score);

huangapple
  • 本文由 发表于 2023年3月7日 17:47:10
  • 转载请务必保留本文链接:https://go.coder-hub.com/75660305.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定