如何对 Java 中地图内的列表进行排序?

How can I sort a list that inside a map in Java?

我创建了一个 class 来存储比赛结果,例如每个车手的姓名和时间,我已确定我希望根据时间比较结果。

public class Vysledek implements Comparable<Vysledek>{
private String jmeno;
private int hodina;
private int minuta;
private int sekunda;
    
public Vysledek(String jmeno, int h, int m, int s){
    if(jmeno==null)
        throw new IllegalArgumentException("Zadejte jméno prosím");
    this.setJmeno(jmeno);
    if(h==0||m==0||s==0)
        throw new IllegalArgumentException("Zadejte čas prosím");
    this.setCas(h, m, s);
}

public String getJmeno(){
    return jmeno;
}

public void setJmeno(String jmeno){
    this.jmeno = jmeno;
}

public void setCas(int h, int m, int s){
    this.hodina=h;
    this.minuta=m;
    this.sekunda=s;
}

public void getVysledek(){
    System.out.println(this.toString());
}

@Override
public int compareTo(Vysledek v){
    if(this.hodina<v.hodina && this.minuta<v.minuta && this.sekunda<v.sekunda)
        return -1;
    else if(this.hodina==v.hodina && this.minuta==v.minuta && this.sekunda==v.sekunda)
        return 0;
    else
        return 1;
}

@Override
public String toString(){
    return this.getJmeno()+", "+hodina+":"+minuta+"."+sekunda;
}
}

然后我有一个 class 来创建一个列表并将结果存储在那里。

public class SerazenySeznam<Vysledek extends Comparable<Vysledek>>{
    private java.util.List<Vysledek> vysledek = new java.util.ArrayList();
    
public void add(Vysledek v){
    if(v==null)
        throw new IllegalArgumentException("Vložte platný prvek");
    vysledek.add(v);
}

public void sort(){
    java.util.Collections.sort(vysledek);
    System.out.println(vysledek);
}

@Override
public String toString(){
    return vysledek.toString();
}
}

主要class我创建了一个地图,然后将结果放入地图中,我希望根据时间对结果进行排序。如您所见,我在 class 中创建了一个方法 sort() 来创建最少,但它不对任何内容进行排序。

public static void main(String[] args) {
        // TODO code application logic here
        java.util.Map<SerazenySeznam, Integer> mapa=new java.util.HashMap();
        
        SerazenySeznam<Vysledek> Monaco= new SerazenySeznam();
        
        Monaco.add(new Vysledek("Alain Prost",1,20,557));
        Monaco.add(new Vysledek("Michael Schmacher",1,21,190));
        Monaco.add(new Vysledek("Ayrton Senna",1,21,552));
        Monaco.add(new Vysledek("Érik Comas",1,23,246));
        Monaco.add(new Vysledek("Michael Andretti",1,22,994));
        Monaco.add(new Vysledek("Karl Wendlinger",1,22,477));
        Monaco.add(new Vysledek("Gerhard Berger",1,22,394));
        Monaco.add(new Vysledek("Riccardo Patrese",1,22,117));
        Monaco.add(new Vysledek("Jean Alesi",1,21,948));
        Monaco.add(new Vysledek("Damon Hill",1,21,825));
        
        Monaco.sort();
        
        mapa.put(Monaco, 1993);
        
        for(SerazenySeznam s : mapa.keySet())
            System.out.println(s);
    }

你能告诉我如何根据他们在比赛中的时间对这些结果进行排序吗?我希望我已经清楚了,但如果有什么不清楚的地方,请告诉我,我可以改进我的问题。提前致谢。

将小时与小时、分钟与分钟、秒与秒进行比较以找出哪种 HH:MM:SS 组合最快并不是一个好主意。可能存在像 04:50:56 < 05:00:00 这样的情况,在您原来的 compareTo() 方法中评估效果不佳。

试试这个代码:

public int compareTo(Vysledek v){
    Integer counterSekundaThis = this.sekunda + this.minuta*60 +this.hodina*3600;
    Integer counterSekundaV = v.sekunda + v.minuta*60 + v.hodina*3600;

    return counterSekundaThis.compareTo(counterSekundaV);
}

我建议不要将其存储在您的 class

private int hodina;
private int minuta;
private int sekunda;

您将 LocalTime 用于此目的,因为它是 Java 的 API 来管理时间。您可以使用 LocalTime.of(hodina, minuta, sekunda) 创建它的一个实例。 LocalTime 已经实现了 compareTo 按时间排序。

您的 class 可能看起来像这样:

private static class Vysledek implements Comparable<Vysledek> {
    private String jmeno;
    private LocalTime time;

    public Vysledek(String jmeno, int h, int m, int s) {
      if (jmeno == null) {
        throw new IllegalArgumentException("Zadejte jméno prosím");
      }
      this.setJmeno(jmeno);
      time = LocalTime.of(h, m, s);
    }

    .
    .
    .
   
    @Override
    public int compareTo(Vysledek v) {
      return this.time.compareTo(v.time);
    }
  }

在你的 Vysledek class

中替换这个
@Override
public int compareTo(Vysledek v){
    if(this.hodina<v.hodina && this.minuta<v.minuta && this.sekunda<v.sekunda)
        return -1;
    else if(this.hodina==v.hodina && this.minuta==v.minuta && this.sekunda==v.sekunda)
        return 0;
    else
        return 1;
}

有了这个

@Override
public int compareTo(Vysledek v) {
        return Integer.compare(this.sekunda + this.minuta*60000 + this.hodina*60000*60, v.sekunda + v.minuta*60000 + v.hodina*60000*60);
}

或者您甚至可以在 SerazenySeznam class 中使用 sort() 方法对其进行排序,而无需在 Vysledek class 中实现 Comparable。但是你需要制作 hodina, minuta, sekunda 属性 public 或者制作 getters.

public void sort(){
    vysledek.sort(new Comparator<Vysledek>() {
        @Override
        public int compare(Vysledek v1, Vysledek v2) {
            return Integer.compare(v1.sekunda + v1.minuta*60000 + v1.hodina*60000*60, v2.sekunda + v2.minuta*60000 + v2.hodina*60000*60);
        }
    });
}

PS:根据你的测试数据,sekunda 属性 应该命名为 milisekunda,这个答案将其视为毫秒。如果你想把它当作秒,用这个替换之前的:

Integer.compare(this.sekunda + this.minuta*60 + this.hodina*3600, v.sekunda + v.minuta*60+ v.hodina*3600);