【问题标题】:Comparing Using 2 Properties in Ascending and Descending Orders比较在升序和降序中使用 2 个属性
【发布时间】:2016-07-01 16:09:06
【问题描述】:

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

案例 1

  • propA - 正常
  • propB - 正常

案例 2

  • propA - Asc
  • propB - 正常

案例 3

  • propA - 描述
  • propB - 正常

你明白了。我正在使用Comparator 来执行此操作,到目前为止,当一个或两个值设置为Normal 时,我已经能够对其进行排序。我不确定的部分是当我选择通过这两种方法进行排序时该怎么做。例如,如果我想按 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
            }
    }
}

如何使用两个不同的字段进行排序,每个字段都有自己的排序顺序?

【问题讨论】:

  • 两个厘米。首先,当为两个字段指定 ASC/DESC 时,您将需要评估其中一个字段的比较(以“主要”为准)。如果这是非零,则返回该值。只有当第一个比较为零(即第一个属性相等)然后您才考虑第二个字段的比较。第二点,如果您使用case ASCcase DESC,那么default 将更自然地适合您的设置。

标签: java sorting comparator


【解决方案1】:

我对你的Comparator 有点困惑。什么开关触发什么事件并不容易理解。
不过,我将描述标准程序。

您需要对要比较的字段进行优先顺序。在您上面的示例中,我假设它首先必须按propA 排序,然后按propB
然后你首先按propA 排序。如果它返回“equals”(),那么您想按下一个字段,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;
    }
}

当然,如果您有多个字段,您也可以重复执行此操作,只要您指定了顺序(例如,通过在属性字段上使用有序列表)。

现在您需要将您的开关添加到此展示柜中:) 我建议您为此使用 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)
            }
    }
}

现在在上面使用它Comparator

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

我没有测试过,但我想你明白了:)

【讨论】:

  • 粘贴时忘记更改一些代码,例如切换条件。无论如何,我最终修改了代码的顶部并将其放到我缺少返回值的地方。现在像魅力一样工作(很多开销,可能会在异步任务中运行)。谢谢!
【解决方案2】:

创建 1 个comparator,按“第一个字段”排序。如果第一个字段的值相等,则按“第二个字段”排序。

if(object1.f1.equals(object2.f1)){

 object1.f2.compareTo(object2.f2);

} else {

  object1.f1.compareTo(object2.f1); 

}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-04-29
    • 2015-08-03
    • 2015-03-09
    • 2020-10-11
    • 1970-01-01
    • 2017-06-24
    • 2021-09-04
    • 2019-05-06
    相关资源
    最近更新 更多