按多个属性对 ArrayList 进行排序
Sorting ArrayList by multiple properties
我有一个 ArrayList
的玩家,其属性为 username
类型的字符串和 winratio
类型的 long 只是 gameswon/gamesplayed*100
的比率。
我想按 username
对 ArrayList
进行排序,我已经使用 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
链接在一起,这样当结果任何一个 Comparator
是 0
,它将继续尝试将值与列表中的 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 接口来处理默认排序情况...
我有一个 ArrayList
的玩家,其属性为 username
类型的字符串和 winratio
类型的 long 只是 gameswon/gamesplayed*100
的比率。
我想按 username
对 ArrayList
进行排序,我已经使用 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
链接在一起,这样当结果任何一个 Comparator
是 0
,它将继续尝试将值与列表中的 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 接口来处理默认排序情况...