Java 按升序和降序使用2个属性进行比较

Java 按升序和降序使用2个属性进行比较,java,sorting,comparator,Java,Sorting,Comparator,我有一个具有多个属性的对象,其中两个属性用户可以选择按其排序,两个属性都可以是升序、降序或两者都不是(正常),并且它们彼此独立。因此,我的案例是: 案例1 普罗帕-正常 propB-正常 案例2 propA-Asc propB-正常 案例3 propA-Desc propB-正常 你明白了。我正在使用一个比较器来实现这一点,到目前为止,我已经能够在一个或两个值都设置为正常值时对其进行排序。我不确定的是,当我选择两种方法进行排序时,该怎么办。例如,如果我想按propA升序和propB降

我有一个具有多个属性的对象,其中两个属性用户可以选择按其排序,两个属性都可以是升序、降序或两者都不是(正常),并且它们彼此独立。因此,我的案例是:

案例1

  • 普罗帕-正常
  • propB-正常
案例2

  • propA-Asc
  • propB-正常
案例3

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