Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/344.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 按多个属性对ArrayList排序_Java_Sorting_Arraylist_Comparator - Fatal编程技术网

Java 按多个属性对ArrayList排序

Java 按多个属性对ArrayList排序,java,sorting,arraylist,comparator,Java,Sorting,Arraylist,Comparator,我有一个玩家的ArrayList,属性为username,类型为string,属性为winratio,类型为long,它只是gameswon/gamesplayed*100的一个比率 我想通过用户名对ArrayList进行排序,我已经使用比较器类完成了这项工作,但是我还想创建另一种方法,根据winratio对玩家进行排序,如果他们的winratio相等,则根据用户名对他们进行排序。我不知道如何将这两个比较器组合在一起,并给它们一个层次结构,这样它就知道应该优先选择哪一种 谢谢 如果他们拥有相等的

我有一个玩家的
ArrayList
,属性为
username
,类型为string,属性为
winratio
,类型为long,它只是
gameswon/gamesplayed*100的一个比率

我想通过
用户名对
ArrayList
进行排序,我已经使用
比较器
类完成了这项工作,但是我还想创建另一种方法,根据
winratio
对玩家进行排序,如果他们的
winratio
相等,则根据
用户名
对他们进行排序。我不知道如何将这两个比较器组合在一起,并给它们一个层次结构,这样它就知道应该优先选择哪一种

谢谢

如果他们拥有相等的winratio,则可以根据用户名对其进行排序


这表明您应该使用用户名来实现
可比性
(自然排序)。对于winRatio,使用
比较器
,如果winRatio相等,还应检查其用户名。

计算
winRatio
中的差异,如果是
0
,则返回名称差异,例如

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

}
作为基础对象

另一个(奇怪的)想法可能是创建一个“链接的”
比较器
,允许您选择两个(或更多)比较器
,并将它们链接在一起,这样,当任何一个
比较器
的结果为
0
时,它将继续尝试将值与列表中的
比较器
进行比较

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

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

使用下面的代码内部比较方法可以实现您想要的

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);
   }
}
int比较(to1,to2){
如果(o1.winratio

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

您可以在单个comparator中完成这两项工作。只需将这两个内容添加到单个比较中的方法'@downvoter,您就可以在宝贵的downvote之前等待编辑完成。
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);
   }
}