The hierarchy goes like:
Class Drug - it has drugs name and price.
Class Supplier - it holds a Map of <Drug drug, int quantity>
.
Now I have a Vector<Suppliers>
(which holds, let's say 5 suppliers) and I want to sort in descending order of the quantity of an user inputted drugs name.
Is this even possible? I've tried using comparators but I can't get it working.
Ok, what I tried to do is put only the suppliers, that have the passed as parameter drug in a new List
and THEN perform the sort on the list. I think this is a good workaround, but then I need to change the 'sort' somehow.
Here is the method where I iterate over all suppliers and check if they have the drug, if they do -> add them in the new list and try to sort it in the end.
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;
}
Problem is that I get the NullPointerException
at the sort
line.
I think that the sort
method, that you suggested, needs to be changed to somehow act on the new List and not the old one?
Stacktrace for @Andrew
Exception in thread "main" java.lang.NullPointerException
at java.util.Objects.requireNonNull(Unknown Source)
at java.util.Optional.<init>(Unknown Source)
at java.util.Optional.of(Unknown Source)
at myapp.Supplier.getKeyExtractor(Supplier.java:22)
at myapp.Orders.lambda$0(Orders.java:89)
at java.util.Comparator.lambda$comparing$77a9974f$1(Unknown Source)
at java.util.TimSort.countRunAndMakeAscending(Unknown Source)
at java.util.TimSort.sort(Unknown Source)
at java.util.Arrays.sort(Unknown Source)
at java.util.ArrayList.sort(Unknown Source)
at java.util.Collections.sort(Unknown Source)
at myapp.Orders.sort(Orders.java:89)
at myapp.Orders.getSortedSuppliersByQuantity(Orders.java:106)
at myapp.main.main(main.java:22)
The following comparator performs the same actions like yours does, but in a shorter Java 8 form:
public void sort(Drug drug, Vector<Supplier> suppliers) {
Collections.sort(suppliers, Comparator.comparing(s -> s.getDrugs().get(drug)));
}
The problem is possible when either a map doesn't contain the given drag or a supplier doesn't have drugs to trade (NullPointerException
).
How to solve? Add null
checks or pass valid arguments to the method.
EDIT:
I wrote the getKeyExtractor
method which will throw an exception with a detailed message (if something bad happens) to know what is going on:
public void sort(Drug drug, Vector<Supplier> suppliers) {
Collections.sort(suppliers, Comparator.comparing(s -> Supplier.getKeyExtractor(s, drug)));
}
public static Integer getKeyExtractor(Supplier supplier, Drug drug) {
return Optional.ofNullable(Optional.ofNullable(supplier.getDrugs())
.orElseThrow(() -> new IllegalArgumentException("drugs is null")).get(drug))
.orElseThrow(() -> new IllegalArgumentException("the drug couldn't be found"));
}
P.S.
I would suggest you to use a List
in a pair with the ArrayList
here instead of a Vector
.