Java 按升序和降序使用2个属性进行比较
我有一个具有多个属性的对象,其中两个属性用户可以选择按其排序,两个属性都可以是升序、降序或两者都不是(正常),并且它们彼此独立。因此,我的案例是: 案例1Java 按升序和降序使用2个属性进行比较,java,sorting,comparator,Java,Sorting,Comparator,我有一个具有多个属性的对象,其中两个属性用户可以选择按其排序,两个属性都可以是升序、降序或两者都不是(正常),并且它们彼此独立。因此,我的案例是: 案例1 普罗帕-正常 propB-正常 案例2 propA-Asc propB-正常 案例3 propA-Desc propB-正常 你明白了。我正在使用一个比较器来实现这一点,到目前为止,我已经能够在一个或两个值都设置为正常值时对其进行排序。我不确定的是,当我选择两种方法进行排序时,该怎么办。例如,如果我想按propA升序和propB降
- 普罗帕-正常
- propB-正常
- propA-Asc
- propB-正常
- propA-Desc
- propB-正常
比较器来实现这一点,到目前为止,我已经能够在一个或两个值都设置为正常值时对其进行排序。我不确定的是,当我选择两种方法进行排序时,该怎么办。例如,如果我想按propA升序和propB降序排序,它应该看起来有点像这样
propA propB
A Z
A D
B M
B A
R Q
Z Z
Z A
这是我现在的分类方式
@Override
public int compare(Field lhs, Field rhs) {
switch (growerSort) {
case NORMAL:
switch (fieldSort) {
case NORMAL:
return ((Integer) lhs.getID()).compareTo(rhs.getID());
case ASC:
return lhs.getPropB().toLowerCase().compareTo(rhs.getPropB().toLowerCase());
default:
return rhs.getPropB().toLowerCase().compareTo(lhs.getPropB().toLowerCase());
}
case ASC:
switch (fieldSort) {
case NORMAL:
return lhs.getPropA().toLowerCase().compareTo(rhs.getPropA().toLowerCase());;
case ASC:
return 0; // 0 used as placeholder
default:
return 0; // 0 used as placeholder
}
default:
switch (fieldSort) {
case NORMAL:
return rhs.getPropA().toLowerCase().compareTo(lhs.getPropA().toLowerCase());
case ASC:
return 0; // 0 used as placeholder
default:
return 0; // 0 used as placeholder
}
}
}
如何使用两个不同的字段进行排序,每个字段都有自己的排序顺序?创建一个在“第一个字段”上排序的比较器。如果第一个字段的值相等,则按“第二个字段”排序
我对您的比较器有点困惑。很难理解是什么开关触发了什么事件。
但是,我将描述标准程序
您需要对要比较的字段设置优先级顺序。在上面的示例中,我假设它首先必须按propA
排序,然后按propB
排序
然后首先按propA
排序。如果它返回“equals”(zero),则需要按下一个字段进行排序,propB
,依此类推
让我给你举个例子:
@Override
public int compare(final Field lhs, final Field rhs) {
int firstCompareValue = lhs.getPropA().compareTo(rhs.getPropA());
if (firstCompareValue == 0) {
// lhs and rhs are equals in propA, use propB
int secondCompareValue = lhs.getPropB().compareTo(rhs.getPropB());
return secondCompareValue;
} else {
return firstCompareValue;
}
}
当然,如果您有多个字段,只要您指定了顺序(例如,通过在属性字段上使用有序列表),也可以执行此迭代
现在您需要将交换机添加到此showcase:)我建议您为此做一个PropertyComparator
public final class PropertyComparator extends Comparator<Comparable<?>> {
private final boolean mUseDscOrder = false;
public void setUseDscOrder(final boolean useDscOrder) {
mUseDscOrder = useDscOrder;
}
public int compare(final Comparable<?> o1, final Comparable<?> o2) {
if (!mUseDscOrder) {
return o1.compareTo(o2);
} else {
// Reverses the logic, results in DscOrder
return o2.compareTo(o1)
}
}
}
我还没有测试过它,但我想你明白了:)两条评论。首先,当为两个字段指定ASC/DESC时,您需要评估其中一个字段的比较(以“主要”字段为准)。如果该值非零,则返回该值。只有当第一个比较为零(即第一个属性相等)时,你才考虑第二个字段的比较。第二点是,如果您使用case ASC
和case DESC
,则default
将更自然地适应您的设置。粘贴此项时,我忘记更改一些代码,例如切换条件。无论如何,我最终修改了代码的顶部,并将其放到了缺少返回值的地方。现在工作起来很有魅力(开销很大,可能要在异步任务中运行)。谢谢
public final class PropertyComparator extends Comparator<Comparable<?>> {
private final boolean mUseDscOrder = false;
public void setUseDscOrder(final boolean useDscOrder) {
mUseDscOrder = useDscOrder;
}
public int compare(final Comparable<?> o1, final Comparable<?> o2) {
if (!mUseDscOrder) {
return o1.compareTo(o2);
} else {
// Reverses the logic, results in DscOrder
return o2.compareTo(o1)
}
}
}
@Override
public int compare(final Field lhs, final Field rhs, final boolean firstUseDscOrder, final boolean secondUseDcsOrder) {
PropertyComparator firstComparator = new PropertyComparator();
firstComparator.setUseDscOrder(firstUseDscOrder);
int firstCompareValue = firstComparator.compare(lhs.getPropA(), rhs.getPropA());
if (firstCompareValue == 0) {
// lhs and rhs are equals in propA, use propB
PropertyComparator secondComparator = new PropertyComparator();
secondComparator.setUseDscOrder(secondUseDscOrder);
int secondCompareValue = secondComparator.compare(lhs.getPropB(), rhs.getPropB());
return secondCompareValue;
} else {
return firstCompareValue;
}
}