使用Java中的Comparator对List进行排序

时间:2013-10-31 13:57:34

标签: java sorting comparator

我有两个班级

public class PopularSports {    
    public int Rank;    
    public String Sport;
}

public class Medals {
    public String Sport    
    public String Medal    
    public int Year    
    public String Game    
    public String Athlete
}

当我尝试引导他们的csv并在每个类的List中获得结果时,我想按照以下顺序对它们进行排序。

PopularSports类应按以下顺序排序:

  1. 等级
  2. 运动
  3. 奖牌类应按以下顺序排序:

    1. 运动
    2. 奖章
    3. 游戏
    4. 运动员
    5. 我已经创建了像这样的压缩器

      Collections.sort(medalReportList, new Comparator<Medals >() {
        @Override
        public int compare(Medals o1, Medals o2) {
         return getRankOfSportBySportName(o1.getSport()) > getRankOfSportBySportName(o2.getSport())
                ? +1
                : getRankOfSportBySportName(o1.getSport()) < getRankOfSportBySportName(o2.getSport())
                ? -1
                : o1.getAthlete().compareToIgnoreCase(o2.getAthlete());
          }
        });
      

      但它没有实现它,它对运动员的名字进行了分类。

4 个答案:

答案 0 :(得分:2)

您需要嵌套这些支票。我会写出PopularSports方法并留给对方。

我建议你学习Java编码标准,并使这些类名单数:PopularSportMedal。我将在下面演示:

public int compareTo(PopularSport other) {
    if (this.rank < other.rank) return -1;
    else if (this.rank > other.rank) return +1;
    else {
        // This is where the nesting happens to break the ties.
        if (this.sport.compareTo(other.sport) < 0) return -1;
        else if (this.sport.compareTo(other.sport) > 0) return +1;
        else return 0;  // You'll have deeper nesting for the other values in Medal.
    }
}

您选择的顺序决定首先检查哪些。你嵌套在else子句中以打破关系。

答案 1 :(得分:0)

我会简化你的逻辑。

public int compare(Medals o1, Medals o2) {
  int rankDifference = getRankOfSportBySportName(o1.getSport()) 
                             - getRankOfSportBySportName(o2.getSport());
  return rankDifference != 0 
      ? rankDifference
      : o1.getAthlete().compareToIgnoreCase(o2.getAthlete());
  }

答案 2 :(得分:0)

其他人已经为您提供了三元运算符的解决方案。另一方面,我不鼓励你在复杂的情况下使用它 - 它根本不可读且难以维护。

要么使用if / else块(对于那么多要比较的字段看起来会很糟糕),或者更好的是,使用第三方库。在Guava中,您可以像这样使用ComparisionChain

new Comparator<Medals>() {
    @Override
    public int compare(Medals m1, Medals m1) {
        return ComparisonChain.start()
         .compare(m1.getSport(), m2.getSport())
         .compare(m1.getMedal(), m2.getMedal())
         .compare(m1.getYear(), m2.getYear())
         .compare(m1.getGame(), m2.getGame())
         .compare(m1.getAthlete(), m2.getAthlete(), String.CASE_INSENSITIVE_ORDER)
         .result();
    }
}

这不是更具可读性吗?!

答案 3 :(得分:-1)

排序第一个列表对您没有问题。如果你想对sportName进行排序,那么根据奖牌进行排序,如果奖牌名称相同,则根据年份排序,然后解决方案是:

最佳方式:

public void sortAccordingToAboveRequirement(List<Medal> medals){

 Collections.sort(medals,myComparator);

 }


  static Comparator<Medal> myComparator=new Comparator<Medal>() {
    @Override
        public int compare(Medal medal1, Medal medal2) {
        int value=0;
        value=medal1.getSport().compareTo(medal2.getSport());
        if(value!=0) return value;
        value=medal1.getMedal().compareTo(medal2.getMedal());
        if(value!=0) return value;
        value=medal1.getYear().compareTo(medal2.getYear());
        if(value!=0) return value;
        value=medal1.getGame().compareTo(medal2.getGame());
        if(value!=0) return value;
        value=medal1.getAthlete().compareTo(medal2.Athlete());
        return value;
    }
};

如果您愿意,请使用compareToIgnoreCase():)