繁体   English   中英

Java按有序值打印TreeMap

[英]Java print TreeMap by ordered values

我正在编写一个程序,将有关足球队的数据存储在嵌套的树形图中。 看起来像这样:

TreeMap<[team name], TreeMap<[team wins], [opponents]>>

其中[team name]和[opponents]是字符串,[team wins]是int。 我当前的目标是按团队胜利降序打印数据。 它必须看起来像:

Liverpool: //map key
wins: <wins>  //nested map key
opponents: <opponents> 

我的想法是在打印数据时对嵌套的地图entrySet()进行排序,然后对其进行迭代,但是我无法做到这一点,因为从我的读取中我需要TreeSet和map.entry()仅返回Set。我需要我的地图成为TreeMap,因为当两支球队获得相等的胜利时,我需要按字母顺序打印。 如果不清楚,按嵌套TreeMap键排序的打印TreeMap的好方法是什么?

TreeMap的( 根据文档说明 )自然按照您使用的键排序。 因此,如果要按获胜次数打印数据,则需要将获胜次数作为主键。

由于您希望辅助排序基于团队名称,因此您希望将其作为辅助密钥。

因此, TreeMap<[wins], TreeMap<[team name], [opponents]>>将是正确的方法。

此外,由于对手意味着不止一个对手,因此您可能希望使其稍微复杂一些,并在需要时将其更改为以下内容:

TreeMap<[wins], TreeMap<[team name], ArrayList<[opponent]>>>

希望这为您指明正确的方向。 请记住,在您的情况下,自然排序是外部TreeMap的降序(即[wins]降序[wins]因此请确保Comparable的compareTo函数执行正确的工作。

import java.util.ArrayList;
import java.util.Comparator;
import java.util.Random;
import java.util.TreeMap;

public class SO36799415 {

    public static Random random = new Random();

    public static void main(String[] args) {
        TreeMap<Integer, TreeMap<String, ArrayList<String>>> map = new TreeMap(new Comparator<Integer>() {
            @Override
            public int compare(Integer o1, Integer o2) {
                return -Integer.compare(o1, o2);
            }
        });
        int teams = random.nextInt(20) + 1;
        for (int i = 0; i < teams; i++) {
            addToMap(map);
        }
        for (Integer wins : map.keySet()) {
            TreeMap<String, ArrayList<String>> tmp = map.get(wins);
            for (String team : tmp.keySet()) {
                System.out.println(team);
                System.out.println("Wins: " + wins);
                System.out.println(tmp.get(team));
                System.out.println();
            }
        }
    }

    private static void addToMap(TreeMap<Integer, TreeMap<String, ArrayList<String>>> map) {
        String name = randomName();
        int wins = random.nextInt(10);
        int opponents = random.nextInt(10) + 1;
        Team team = new Team(name);
        team.setWins(wins);
        for (int i = 0; i < opponents; i++) {
            team.addOpponent(randomName());
        }
        if (map.containsKey(wins)) {
            map.get(wins).put(name, team.opponents);
        } else {
            TreeMap<String, ArrayList<String>> tmp = new TreeMap<>();
            tmp.put(name, team.opponents);
            map.put(wins, tmp);
        }
    }

    private static String randomName() {
        StringBuffer sb = new StringBuffer();
        int len = random.nextInt(10) + 1;
        for (int i = 0; i < len; i++) {
            sb.append((char) ('a' + random.nextInt(26)));
        }
        return sb.toString();
    }

    private static class Team {
        String name;
        ArrayList<String> opponents;
        int wins;

        public Team(String name) {
            this.name = name;
            this.opponents = new ArrayList<>();
            this.wins = 0;
        }

        public boolean addOpponent(String opponent) {
            return this.opponents.add(opponent);
        }

        public void setWins(int wins) {
            this.wins = wins;
        }
    }
}

我将创建一个名为sortedKeys的TreeMap<Integer, String> ,然后遍历原始KeyMap的所有团队,并使用wins作为键并将TreeMap中的键作为值将它们添加到sortedKeys中。
然后,您可以遍历sortedKeys以获得按排序顺序排列的键,从而也可以按排序顺序获取结果。

编辑:由于键不能唯一,另一个解决方案是使用您自己的比较器创建一个成对的TreeSet,当键相等时,改为比较值。 然后,您将获得如下内容:

TreeSet<Pair<String,Pair<Integer,String>>> sortedSet = new TreeSet(new Comparator<Pair<String,Pair<Integer,String>>>() {
    @Override
    public int compare(Pair<String,Pair<Integer,String>> a, Pair<String,Pair<Integer,String>> b) {
        int res = b.getValue().getKey() - a.getValue().getKey();
        if (res == 0) {
            return a.getKey().compareTo(b.getKey());
        } else {
            return res;
        }
    }
});
teams.forEach(new BiConsumer<String,Pair<Integer,String>>() {
    @Override
    public void accept(String k, Pair<Integer,String> v) {
        sortedSet.add(new Pair(k, v));
    }
});

我对您的初始数据结构进行了一些修改,因为您声明团队只有一个获胜值,这意味着嵌套的TreeMap始终只有一个条目,因此应该是一对。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM