我正在编写一个程序,用于在嵌套的树形图中存储有关足球队的数据。它看起来像这样:
TreeMap<[team name], TreeMap<[team wins], [opponents]>>
[团队名称]和[对手]是字符串,[团队胜利]是int。 我目前的目标是按团队胜利的顺序打印数据。它必须看起来像:
Liverpool: //map key
wins: <wins> //nested map key
opponents: <opponents>
我的想法是订购嵌套的map entry()然后迭代它,同时打印数据,但我无法做到这一点,因为从我读到的我需要TreeSet和map.entry()只返回Set我需要我的地图是TreeMap,因为当两个团队获得相同的胜利时,我需要按字母顺序打印。如果我不清楚,打印TreeMap的好方法是什么,按嵌套的TreeMap键排序?
答案 0 :(得分:1)
TreeMap&#39;(as the documentation states)自然按您使用的键排序。因此,如果您想按胜利数量打印数据,那么您需要将获胜次数作为主键。
由于您希望辅助排序基于团队名称,因此您希望将其作为辅助密钥。
因此TreeMap<[wins], TreeMap<[team name], [opponents]>>
是正确的方法。
此外,由于对手会暗示不止一个对手你可能想让它稍微复杂一点,并在需要时将其更改为以下内容:
TreeMap<[wins], TreeMap<[team name], ArrayList<[opponent]>>>
希望这能指向正确的方向。请记住,在您的情况下,自然顺序将是外部TreeMap的DESCENDING顺序,即[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;
}
}
}
答案 1 :(得分:1)
我创建一个名为sortedKeys的TreeMap<Integer, String>
,然后迭代原始KeyMap的所有团队,并使用wins作为键并将TreeMap中的键作为值,将它们添加到sortedKeys中。
然后,您可以迭代sortedKeys以按排序顺序获取键,从而您也可以按排序顺序获得结果。
编辑:由于键不能是唯一的,因此另一种解决方案是使用您自己的比较器创建一对树组,当键相等时,比较值。然后你会得到这样的东西:
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总是只有一个条目,因此应该只是一对。