我首先尝试按 car make 排序,然后按汽车年度排序,然后按汽车里程排序。所有字段都是字符串。
这是我到目前为止所尝试的内容:
class Sorter implements Comparator<Car> {
@Override
public int compare(Car o1, Car o2) {
if(o1.getMake().compareToIgnoreCase(o2.getMake()) == 0 && Integer.parseInt(o1.getYear()) != Integer.parseInt(o2.getYear())){
if(Integer.parseInt(o1.getYear()) > Integer.parseInt(o2.getYear())){
return -1;
}else{
return 1;
}
}
if(o1.getMake().compareToIgnoreCase(o2.getMake()) == 0 && Integer.parseInt(o1.getYear()) == Integer.parseInt(o2.getYear())){
if(Integer.parseInt(o1.getMileage()) > Integer.parseInt(o2.getMileage())){
return 1;
}else{
return -1;
}
}
return o1.getMake().compareToIgnoreCase(o2.getMake());
}
}
我正在尝试构建一个类似于excel的算法,您可以按一列然后另一列然后另一列进行排序。
答案 0 :(得分:1)
一般方法称为lexicographic ordering,这是我们用来对单词进行排序的方法。假设我们要按字段C
,f1
... f2
对类fn
的两个对象进行排序,我们按以下步骤操作:
f1
字段;如果它们不同,则比较结果是最终结果,否则在代码中(注意 - 未编译):
class Sorter implements Comparator<Car> {
@Override
public int compare(Car o1, Car o2) {
int res = o1.getMake().compareToIgnoreCase(o2.getMake());
if ( res != 0 )
return res;
res = o1.getYear().compareTo(o2.getYear());
if ( res != 0 )
return res;
return Integer.parseInt(o1.getMileage()).compareTo(Integer.parseInt(o2.getMileage()));
}
}
答案 1 :(得分:1)
如果某个类有多个重要字段,那么您的顺序 比较它们是至关重要的你必须从最重要的开始 领域和工作你的方式。如果比较产生任何结果 除了零(代表平等)之外,你已经完成了;回来吧 结果。如果最重要的字段相等,则继续比较 下一个最重要的字段,依此类推。如果所有字段都相等, 对象是平等的;返回零..(有效的Java)。
public int compare(Car car1, Car car2) {
// compare make
int makeDiff = car1.getMake().compare(car2.getMake());
if ( makeDiff != 0 )
return makeDiff;
// compare year
int yearDiff = car1.getYear().compare(car2.getYear());
if ( yearDiff != 0 )
return yearDiff;
// compare mileage
int mileageDiff = car1.getMileage().compare(car2.getMileage());
if ( mileageDiff != 0 )
return mileageDiff;
return 0;
}
答案 2 :(得分:0)
我会写一个MultiComparator
,如下所示:
class MultiComparator<T> implements Comparator<T> {
private final List<Comparator<T>> comparators = new ArrayList<Comparator<T>>();
public MultiComparator(final List<Comparator<T>> comps) { ... }
@Override int compareTo(T t1, T t2) {
for (Comparator<T> c: comparators) {
int d = c.compareTo(t1, t2);
if (d != 0) return d;
}
return 0;
}
}
然后用3个独立的比较器实例化MultiComparator<T>
,每个比较器只比较你说的一个字段。然后你会得到你想要的结果。
答案 3 :(得分:0)
我试图先按汽车制造排序然后按汽车年排序然后排序 乘车里程。所有字段都是字符串。
A)你应该改变你的设计。年份应为int,里程数应为int,float或由其中一个和一个单元组成的对象。字符串不是正确的表示。此外,如果您在比较器中使用它们,则每次比较至少需要将它们转换为适当的类型,这非常低效,
b)为了实现比较器,您可能想要使用外部库。 Guava和Commons / Lang都非常擅长。在下面的例子中,我假设Year和Mileage都是数字。
public int compare(Car o1, Car o2) {
return ComparisonChain.start()
.compare(o1.getYear(), o2.getYear())
.compare(o1.getMileage(), o2.getMileage())
.compare(o1.getMake(), o2.getMake())
.getResult();
}
Commons / Lang(CompareToBuilder
):
public int compare(Car o1, Car o2) {
return new CompareToBuilder()
.append(o1.getYear(), o2.getYear())
.append(o1.getMileage(), o2.getMileage())
.append(o1.getMake(), o2.getMake())
.toComparison();
}
正如您所看到的,两个版本非常相似,而且比您自己编码要容易得多。
答案 4 :(得分:0)
查看Apache Commons Collection中的ComparatorChain 在以下网站上,我有一个教程:Sorting Objects By Multiple Attributes