【问题标题】:Method expected to compare by two fields with comparator but orders just by one方法应按两个字段与比较器进行比较,但仅按 1 排序
【发布时间】:2017-12-02 09:46:09
【问题描述】:

我正在寻找一种方法来实现比较器,以便按名称和价格比较产品。我在这里找到了很多有用的信息How to sort by two fields in Java? 并实现了我的比较器。

它可以正确比较产品名称,但价格顺序不正确。 我希望名称按字母顺序排列,价格按升序排列。 怎么可能做到这一点?我在这里错过了什么?

这是我目前所做的:

按名称和价格进行比较的方法

public static List<BaseProduct> compareNamesAndPrices(List<BaseProduct> baseProducts) {
    Comparator<BaseProduct> productComparator = Comparator.comparing(BaseProduct::getProductName)
            .thenComparing(Comparator.comparing(BaseProduct::getPrice));
    return baseProducts.stream()
            .sorted(productComparator)
            .collect(Collectors.toList());
}

测试方法

List<BaseProduct> sortedProductsList = StaticUtils.compareNamesAndPrices(products);
for (BaseProduct product : sortedProductsList) {
    System.out.println(String.format("Product name: %s  -> Price: %s", product.getProductName(), product.getPrice().toString()));
}

我得到以下输出:

Product name: Bananas  -> Price: 45
Product name: Galaxy 7 phone  -> Price: 400
Product name: Xiaomi Mi5  -> Price: 370

【问题讨论】:

  • 输出应该是什么?你分享的输出是逻辑,我看不出问题出在哪里
  • 但是输出是按名称和价格排序的!按价格排序仅适用于同名产品。
  • 我希望名称按字母顺序排列,价格按升序排列。
  • 如果您按两个字段排序,则仅在第一个字段相等时才查看第二个字段(即第一个比较产生 0)。您的输入绝不是这种情况,因为您首先按名称排序,并且所有名称都不同
  • 显示预期输出并解释它与当前输出的区别。

标签: java lambda collections java-stream


【解决方案1】:

当您在前一个比较器之上使用thenComparing 组合比较器时,只有当且仅当前一个比较器通过给定的排序键找到至少两个相等的元素时,才会考虑它。

查看您的输出,没有同名的产品,因此根本不考虑价格。

考虑到你提到的:

我希望名称按字母顺序排列,价格在 升序。

简单的事实是,这样做不能不丢失产品名称的顺序或奖品的顺序。

您可以做的最好的事情是在适当的时候按名称或奖品对产品进行排序。

【讨论】:

    猜你喜欢
    • 2021-05-02
    • 1970-01-01
    • 1970-01-01
    • 2017-02-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-12-25
    相关资源
    最近更新 更多