按多个属性对 ArrayList 进行排序

Sorting ArrayList by multiple properties

我有一个 ArrayList 的玩家,其属性为 username 类型的字符串和 winratio 类型的 long 只是 gameswon/gamesplayed*100 的比率。

我想按 usernameArrayList 进行排序,我已经使用 Comparator class 对 ArrayList 进行了排序,但是我还想制作另一种方法来对基于 winratio 的玩家,如果他们 winratio 相等,则根据他们的 username 对他们进行排序。我不确定如何将两个比较器组合在一起并给它们一个层次结构,以便它知道优先于另一个。

谢谢

if they have equal winratio to order them in terms of their username

这表示您应该使用 userName 来实现 comparable(用于自然排序)。对于 winRatio,使用 comparator,如果 winRatio 相等 - 还要检查他们的用户名。

计算winRatio的差异,如果是0,return名字的差异,例如...

public class MultiComparator implements Comparator<Player> {

    @Override
    public int compare(Player o1, Player o2) {
        int result = (int) (o1.getWinRatio() - o2.getWinRatio());
        if (result == 0) {
            result = o1.getUserName().compareTo(o2.getUserName());
        }
        return result;
    }

}

因为我没有事情可做,所以我用了这个

public interface Player {
    public String getUserName();
    public long getWinRatio();
}

作为基础对象

另一个(奇怪的)想法可能是创建一个 "chained" Comparator,允许您将两个(或更多)Comparator 链接在一起,这样当结果任何一个 Comparator0,它将继续尝试将值与列表中的 Comparator 进行比较...

public class RatioComparator implements Comparator<Player> {

    @Override
    public int compare(Player o1, Player o2) {
        return (int) (o1.getWinRatio() - o2.getWinRatio());
    }

}

public class NameComparator implements Comparator<Player> {

    @Override
    public int compare(Player o1, Player o2) {
        return o1.getUserName().compareTo(o2.getUserName());
    }

}

public class ChainedComparator implements Comparator<Player> {

    private Comparator<Player>[] comparators;

    public ChainedComparator(Comparator<Player>... comparators) {
        this.comparators = comparators;
    }

    @Override
    public int compare(Player o1, Player o2) {
        int result = -1;
        for (Comparator<Player> proxy : comparators) {
            result = proxy.compare(o1, o2);
            if (result != 0) {
                break;
            }
        }
        return result;
    }
}

你可以使用类似...

Collections.sort(list, new ChainedComparator(new RatioComparator(), new NameComparator()));

这是未经测试的,只是一个粗略的想法;)

你想要的可以在比较方法中使用下面的代码来实现,

int compare(T o1, T o2){
   if(o1.winratio < o2.winratio){
      return -1;
   }else if(o1.winratio < o2.winratio){
      return +1;
   }else{
     return o1.userName.compareTo(o2.userName);
   }
}

这应该可行,我建议实现 Comparable 接口来处理默认排序情况...