【问题标题】:My comparator's compare method isn't working我的比较器的比较方法不起作用
【发布时间】:2020-06-05 04:56:40
【问题描述】:

我有一个 Customer 对象类,它有一些变量,并且已经针对这些变量之一实现了 Comparator。但是我需要为不同的变量 last_name 实现另一个比较器。

由于我的 Customer 类中不能有 2 个 compareTo() 方法,所以我决定在这里专门为此创建一个 Comparing 类

public class CompareByLastName implements Comparator<Customer> {

    private List<Purchase> purchases;
    private List<Customer> customers;

    public CompareByLastName(List<Purchase> purchases, List<Customer> customers) {
        this.purchases = purchases;
        this.customers = customers;
    }

    /**
     * @param descending
     * @return will be a sorted, in ascending, or descending, array of customer's according to their authors.
     */
    public List<Purchase> sortByLastName(boolean descending){

        List<Purchase> return_List = new LinkedList<Purchase>();

        Collections.sort(customers);

        if(descending == true) {
            Collections.reverse(customers);
        }

        for(Customer customer : customers) {
            for(Purchase purchase_info : purchases) {
                if(customer.getId() == purchase_info.getCustomer_id()) {
                    return_List.add(purchase_info);
                }
            }
        }

        return return_List;
    }

    @Override
    public int compare(Customer customer_1, Customer customer_2) {

        int result = customer_1.getLastName().compareTo(customer_2.getLastName());

        if(result < 0) {
            return -1;
        }
        else if(result > 0) {
            return 1;
        }
        else {
            return 0;
        }
    }   
}

但一旦点击 Collections.sort(customers);

它不会激活下面的公共 int compare(Customer customer_1, Customer customer_2)。

坦率地说,我不知道它在排序中用作比较器的是什么;有谁知道如何解决这个问题并按姓氏排序?

哦,一旦退货,如何设法从购买的 100(0-99) 件商品变为退货清单中的 103(0-102) 件商品?不知道这是怎么回事。

修复了这部分,我将 for 循环切换为“购买”,然后遍历所有客户的列表并找到匹配项,而不是反之亦然。

感谢任何帮助。

提前致谢。

【问题讨论】:

  • 您的比较器的 compare 方法不起作用,因为您没有将比较器的实例传递给 Collections.sort

标签: java sorting collections comparator


【解决方案1】:

您没有使用compare 方法。

    Collections.sort(customers);

上面的行按客户的自然顺序(由Customer.compareTo() 定义)对客户进行排序,而不是根据您的比较器。相反,您可以这样做:

    Collections.sort(customers, this);

现在您的CompareByLastName 将用作排序中的比较器。

几个旁白:

  • 您在比较器类中使用排序方法的设计非常规。不过,它应该可以工作。
  • 在您的 compare 方法中,您不需要 if-else 构造。以下更简单的实现就足够了:

       return customer_1.getLastName().compareTo(customer_2.getLastName());
    

【讨论】:

  • 谢谢 :D 我在 .sort() 中尝试了一堆第二个参数,但我从未想过 this 关键字会起作用。
  • @Mike_1234 解决方案对您来说并不明显的原因是您的整个设计违反直觉。您不应该将Comparator 实现与执行排序操作的代码混用。实际上,您不需要自己实现比较器。只需Collections.sort(customers, Comparator.comparing(Customer::getLastName)); 就可以了。或者更简单,customers.sort(Comparator.comparing(Customer::getLastName));。但实际上,这不是你想要的。您的目标是对购买清单进行排序,因此您应该这样做并避免执行 n×m 操作的嵌套循环
  • @Mike_1234 即public static List&lt;Purchase&gt; sortPurchaseByCustomersLastName(List&lt;Customer&gt; customers, List&lt;Purchase&gt; purchases, boolean descending) { List&lt;Purchase&gt; returnList = new ArrayList&lt;&gt;(purchases); Map&lt;Object,String&gt; idToName = customers.stream() .collect(Collectors.toMap(Customer::getId, Customer::getLastName)); Comparator&lt;Purchase&gt; c = Comparator.comparing(p -&gt; idToName.get(p.getCustomer_id())); if(descending) { c = c.reversed(); } returnList.sort(c); return returnList; }。也推荐阅读:When to use LinkedList over ArrayList?
猜你喜欢
  • 2018-06-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-02-01
  • 2013-12-29
  • 2016-12-26
  • 2013-09-16
  • 2013-11-28
相关资源
最近更新 更多