我有一个班级
public class User {
String country;
Double rating;
Double status;
}
我需要根据两个条件对这个类的List进行排序。
在列表的开头需要是具有国家特定值的用户。这些用户对评级进行排序。如果评级相同,则比较状态。
如果用户有国家/地区的其他值,则只需对其进行排序。
我尝试了很多尝试,这是最近的尝试:
final String country = me.getCountry();
Collections.sort(usersArray, new Comparator<User>() {
@Override
public int compare(User lhs, User rhs) {
User user1 = lhs.getUser();
String country1 = user1.getCountry();
int result = country.equals(country1) ? 1 : 0;
if (result == 0) {
result = Double.compare(lhs.rating, rhs.rating);
if (result == 0) {
return Double.compare(lhs.status, rhs.status);
} else
return result;
}
return Double.compare(lhs.rating, rhs.rating);
}
});
答案 0 :(得分:0)
具有其他国家/地区值的用户,而不是我的 - 位于顶部的
这是因为如果国家相等,你会返回1;否则你检查评级/状态。如果这些比较中的一个返回1,那么您的比较器也返回1.因此国家不相等但来自非您所在国家的用户具有更高的评级并且比较器返回1.这就是列表未正确排序的原因。
int result = country.equals(country1) ? 1 : 0; // DEBUG result = 0
if (result == 0) { # DEBUG enter
result = Double.compare(lhs.rating, rhs.rating); // DEBUG result = 1
if (result == 0) {
result = Double.compare(lhs.status, rhs.status);
} else
return result; // this could be omitted
}
return result; // DEBUG method return 1.
修改后:
您必须指定所有可能的情况:
如果我计算得当(概率不是我最强的一面),你就有18种情况。
答案 1 :(得分:0)
考虑使用CompareToBuilder中的Apache Commons Lang。你告诉它哪些字段要比较哪个顺序,剩下的就是它。也没有更少的代码。
return new CompareToBuilder()
.append(lhs.country, rhs.country)
.append(lhs.rating, rhs.rating)
.append(lhs.status, rhs.status)
.toComparison();
}
答案 2 :(得分:0)
使用Java 8中的流,您可以这样做:
Arrays.stream(usersArray)
.sorted((lhs, rhs) -> Double.compare(lhs.status, rhs.status))
.sorted((lhs, rhs) -> Double.compare(lhs.rating, rhs.rating))
.toArray(size -> new User[size])
因为来自数组的结果流是有序,所以Java保证排序稳定。这意味着当等级相等时,状态的顺序保持稳定。这就是为什么我首先对状态进行排序,然后对评级进行排序。
顺便说一下,这种方法不会改变原始数组的顺序。它返回一个新的。