0

I have the following list of objects of type Supplier and I want to sort them using the reverseOrder() method (so they will be in descending order). However, after reading whole day on the internet, I still can't get this working. I'm pretty sure that this is something really small that I am missing here. The natural order in ascending order works just fine.

Here is my Supplier class:

public class Supplier  {
    private String supplierName = "";
    private String representative = "";
    private String representativesPhoneNumber = "";

    private Map<Drug, Integer> listOfDrugs = new HashMap<Drug, Integer>();

    Supplier(String n, String rep, String repPhoneNum, String drugName, double drugPrice, int stock) {
        this.supplierName = n;
        this.representative = rep;
        this.representativesPhoneNumber = repPhoneNum;
        listOfDrugs.put(new Drug(drugName, drugPrice), stock);
    }

    public Map<Drug, Integer> getListOfDrugs() {
        return this.listOfDrugs;
    }

    public static Integer getKeyExtractor(Supplier supplier, Drug drug) {
        return Optional.ofNullable(Optional.ofNullable(supplier.getListOfDrugs())
                                   .orElseThrow(() -> new IllegalArgumentException("drugs is null")).get(drug))
                       .orElseThrow(() -> new IllegalArgumentException("the drug couldn't be found"));
    }
}

It has a Map if objects <Drug, Integer>. Here is my Drug class:

public class Drug {
    private String name = "";
    private double price = 0.0;

    Drug(String n, double p) {
        this.name = n;
        this.price = p;
    }

    @Override
    public int hashCode() {
        final int prime = 31;
        int result = 1;
        result = prime * result + ((name == null) ? 0 : name.hashCode());
        long temp;
        temp = Double.doubleToLongBits(price);
        result = prime * result + (int) (temp ^ (temp >>> 32));
        return result;
    }

    @Override
    public boolean equals(Object obj) {
        if (this == obj)
            return true;
        if (obj == null)
            return false;
        if (getClass() != obj.getClass())
            return false;
        Drug other = (Drug) obj;
        if (name == null) {
            if (other.name != null)
                return false;
        } else if (!name.equals(other.name))
            return false;
        if (Double.doubleToLongBits(price) != Double.doubleToLongBits(other.price))
            return false;
        return true;
    }
}

Most of the code is trimmed, for the sake of spam. :)

And my Orders class, where I actually do the sorting:

public class Orders {
    private Map <Drug, Integer> orderedDrugs = new HashMap <Drug, Integer>();
    private Vector<Supplier> suppliers = new Vector <Supplier>();   

    public void sort(Drug drug, List<Supplier> sortedSuppliers) {
        Collections.sort(suppliers, Comparator.comparing(s -> Supplier.getKeyExtractor(s, drug), Comparator.reverseOrder()));   
    }

    public List<Supplier> getSortedSuppliersByQuantity(Drug drug) {
        List <Supplier> sortedSuppliers = new ArrayList <Supplier>();
        for(Supplier s : suppliers) {
            for(Entry<Drug, Integer> entry : s.getListOfDrugs().entrySet()) {
                if(entry.getKey().getDrugsName().equals(drug.getDrugsName()));
                    sortedSuppliers.add(s);
            }
        }
        sort(drug, sortedSuppliers);
        return sortedSuppliers;
    }
}

The code is trimmed again, only displaying the needed methods for the actual problem.

So I've tried so far with:

  1. Collections.sort(suppliers, Comparator.comparing(s -> Supplier.getKeyExtractor(s, drug), Comparator.reverseOrder()));

  2. Collections.sort(suppliers, Collections.reverseOrder(Comparator.comparing(s -> Supplier.getKeyExtractor(s, drug))));

But both don't work. Do I need to implement compareTo() somewhere or am I missing some method? Since ascending order is working, but not descending.

Going with Collections.sort(suppliers, Comparator.comparing(s -> Supplier.getKeyExtractor(s, drug))); sorts them in ascending order and works.

Thank you for the help in advance and I'm sorry for the long post!

UPDATE:

I have also tried to implement compareTo in the Supplier class, but I get a NPE. :/

public int compareTo(Supplier a) {
    for(Entry<Drug, Integer> entry : listOfDrugs.entrySet()) {
        int result = listOfDrugs.get(entry.getKey()).compareTo(a.listOfDrugs.get(entry.getKey()));
        if(result != 0)
            return result;
    }
    return 0;
}
6
  • what do you mean by "both don't work"? Commented Nov 7, 2016 at 19:04
  • @NicolasFilotto, I mean that when I try with both of them I get the List in the original way - unordered. Commented Nov 7, 2016 at 19:05
  • 1
    please provide an example to allow us to reproduce easily Commented Nov 7, 2016 at 19:09
  • When I put Collections.sort(suppliers, Comparator.comparing(s -> Supplier.getKeyExtractor(s, drug))) in my sortmethod it works and it sorts the list in ascending order, but when I use the examples with reverseOrders() it doesn't sort the list at all. Commented Nov 7, 2016 at 19:12
  • I've updated my post. I tried to use compareTo but I get a NPE. Commented Nov 7, 2016 at 22:18

3 Answers 3

3

Try

Collections.sort(suppliers, 
                 Comparator.comparing((Supplier s) -> Supplier.getKeyExtractor(s, drug)).reversed());

I built a simplified version and this worked. I did not try it with you Supplier, etc classes.

Sign up to request clarification or add additional context in comments.

4 Comments

Reverse only reverses the list. See my update below.
@RavindraHV Comparator#reversed has nothing to do with any list. Read the javadocs -- it returns a comparator that imposes the reverse ordering of this comparator.
Thank you for the help @bradimus, but it doesn't work for me. :( I get the same list as the original one.
I have updated my post. I tried to use compareTo, but I get a NPE.
0

OK, I've found a workaround to the problem, since everything else didn't work for me. After I sort the list in ascending order, using the sort method, I just call: Collections.reverse(myList); and I get the sorted list in descending order. I know that this is probably lame, but it works for me.

Comments

-2

Yes you need to. Implement Comparator (and tweak it as required), and invoke the sort method.

Update : For doing it using lambda expressions, try as shown here.

Update #2:

Below is what I came up with. Hope it helps :

    /**
Input:[9, 9, 5, 1, 6, 3, 9, 4, 7, 1]
Reversed:[1, 7, 4, 9, 3, 6, 1, 5, 9, 9]
ReverseOrdered:[9, 9, 9, 7, 6, 5, 4, 3, 1, 1]
     */
    private static void testCollectionsSort() {

        List<Integer> integerList = new ArrayList<>();
        int size=10;
        Random random = new Random();
        for(int i=0;i<size;i++) {
            integerList.add(random.nextInt(size));
        }

        System.out.println("Input:"+integerList);
        List<Integer> integerListTwo = new ArrayList<>(integerList);
        Collections.reverse(integerListTwo);
        System.out.println("Reversed:"+integerListTwo);
        Comparator<Integer> integerComparator = (Integer a, Integer b) -> b.compareTo(a); // 'b' is compared to 'a' to enable reverse
        Collections.sort(integerList, integerComparator);

        System.out.println("ReverseOrdered:"+integerList);
    }

3 Comments

I'm sorry for what might seem noob queston, but I thought that Comparator.comparing(s -> Supplier.getKeyExtractor(s, drug), Comparator.reverseOrder()) is actually the comparator in Java-8 syntax?
Have updated answer with a new link. Reverse order reverses the list. It is not the same as sorting in descending order. I am new to lambda but all I can tell you is that you need to implement the compare-to and customize the logic - greater, equals, lesser.
Update : Reverse order does reverse the order ! I was looking at reverse-list.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.