【问题标题】:Java Comparator for Objects with multiple fields [closed]具有多个字段的对象的 Java 比较器 [关闭]
【发布时间】:2014-06-01 15:05:54
【问题描述】:

我有一个对象 Collection,有 5 个字段:

id;
entityType;
entityId;
brandId;
productId;

为了对Collection 中的ArrayList 进行排序,我编写了以下Comparaor

Comparator<Collection> collectionComparator = new Comparator<Collection>() {

    @Override
    public int compare(Collection collection1, Collection collection2) {
        if(collection1.getId().equals(collection2.getId())) {
            if(collection1.getEntityType().equals(collection2.getEntityType())) {
                if(collection1.getEntityId().equals(collection2.getEntityId())) {
                    if(collection1.getBrandId().equals(collection2.getBrandId())) {
                        return collection1.getProductId().compareTo(collection2.getProductId());
                    } else {
                        return collection1.getBrandId().compareTo(collection2.getBrandId());
                    }
                } else {
                    return collection1.getEntityId().compareTo(collection2.getEntityId());
                }
            } else {
                return collection1.getEntityType().compareTo(collection2.getEntityType());
            }
        } 

        return collection1.getId().compareTo(collection2.getId());
    }
};

这是在具有多个要比较的字段的对象上实现Comparator 的正确方法吗?

【问题讨论】:

  • “对”?你在问什么?为什么不只测试您的代码?
  • 这是错误的,因为 Collection 上没有 getId,除非你自己实现了它,这可能也是不必要的
  • 这个问题似乎跑题了,因为用户要求我们写测试用例,用户懒得自己写。
  • 它不是 Java 集合,而是时尚的集合?
  • @djechlin 很抱歉,但我必须说,您的回答对我没有帮助。我以错误的方式问了这个问题。我已经编辑过了。在说“用户要求我们写测试用例之前,用户懒得自己写”。您应该查看该用户的个人资料,看看他是否懒惰。

标签: java sorting object comparator


【解决方案1】:

您的方法可能是正确的,但效率低下(不必要地调用 equals)并且难以阅读。可以这样改写:

public int compare(Collection c1, Collection c2)
{
    int n;
    n = c1.id.compareTo(c2.id);
    if (n != 0) return n;
    n = c1.entityType.compareTo(c2.entityType);
    if (n != 0) return n;
    n = c1.brandId.compareTo(c2.brandId);
    if (n != 0) return n;
    return c1.productId.compareTo(c2.productId);
}

更好的是使用一个库方法来抽象所有这些逻辑,这样你就不必考虑它了。例如。使用apache.commons.lang CompareToBuilder

public int compare(Collection c1, Collection c2)
{
    return new CompareToBuilder()
            .append(c1.id, c2.id)
            .append(c1.entityType, c2.entityType)
            .append(c1.brandId, c2.brandId)
            .append(c1.productId, c2.productId)
            .toComparison();
}

【讨论】:

  • 另外,如果您需要对特定字段进行反向排序,请将 c2 中的字段与 c1 进行比较并追加,.append(c2.brandId, c1.brandId)
【解决方案2】:

首先,Collectionjava.util 包中的一个类,因此将自己的类命名为 Collection 可能不是最好的主意,尽管这当然是可能的。

其次,JDK8 有一些巧妙的方法来创建比较器,请查看:jdk8 comparators

尤其是第 6 节和第 9 节。

编辑:没有 JKD8:

当通过 5 个不同的属性进行比较时,我不会像这样对比较进行硬编码,您始终可以创建自己的比较器链接器(类似于上一个链接中的第 9 点)并将 5 个单独的比较器链接在一起。

【讨论】:

  • 我没有使用 Jdk8,Collection 与我的项目有关。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多