0

I was looking for a way to implement a Comparator for comparing products by name and price. I've found a lot of useful information here How to sort by two fields in Java? and have implemented my comparator.

It compares product names correctly but the prices are not in the right order. I'm expecting to have names in alphabetical order and prices in ascending order. How is it possible to achieve that? What am I missing here?

Here is what I've made so far:

A method to compare by name and price

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());
}

Testing the method

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()));
}

And I'm getting the following output:

Product name: Bananas  -> Price: 45
Product name: Galaxy 7 phone  -> Price: 400
Product name: Xiaomi Mi5  -> Price: 370
Ousmane D.
  • 54,915
  • 8
  • 91
  • 126
samba
  • 2,821
  • 6
  • 30
  • 85
  • 2
    what the output should be? The output you share are logic, i don't see where is the problem here – Youcef LAIDANI Dec 02 '17 at 09:48
  • 2
    But the output is sorted by name and price! The sorting by price is only relevant for products with the same name. – Harald Gliebe Dec 02 '17 at 09:49
  • I'm expecting to have names in alphabetical order and prices in ascending order. – samba Dec 02 '17 at 09:50
  • 1
    If you sort by two fields then the second field is only looked at if the first is equal (i.e. the first compare yields 0). This is never the case with your inputs, since you sort by name first and all names differ – Jeroen Steenbeeke Dec 02 '17 at 09:50
  • Show expected output and explain the difference between it and the current output. – user1803551 Dec 02 '17 at 16:17

1 Answers1

1

When you compose comparators with thenComparing on top of the previous comparator, it will only ever be considered if and only if the previous comparator finds at least two equal elements by the given sort key.

Looking at your output there are no products which have the same name, for that reason the prices are not considered at all.

Considering you've mentioned:

I'm expecting to have names in alphabetical order and prices in ascending order.

the simple matter of fact is, this cannot be done without losing the ordering of the Product names or the ordering of the Prizes.

The best you can do is to sort the Products either by name or by prizes when appropriate.

Ousmane D.
  • 54,915
  • 8
  • 91
  • 126