繁体   English   中英

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

[英]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 中,我创建了一个 map,然后我将结果放入 map 中,我希望根据时间对结果进行排序。 如您所见,我在 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;

    if(counterSekundaThis<counterSekundaV)
        return -1;
    else if(counterSekundaThis==counterSekundaV)
        return 0;
    else
        return 1;
}

我建议不要将其存储在 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);
}

或者您甚至可以在Vysledek class 中的sort()方法中对其进行排序,而无需在SerazenySeznam class 中实现Comparable 但是您需要公开hodina, minuta, sekunda属性或设置 getter。

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);

暂无
暂无

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

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