Reputation: 51
I have a problem with sorting the list, I did all of the tasks which are in a given exercise, but it doesn't quite make sense to me and I want to fix it. So I have a List of people who are waiting in the queue in, let's say, a pharmacy. People who are pregnant should have priority above everyone, the next priority has people with age >60. Everything works fine, except the fact the person with age >60 which came first is behind the people with age >60 who came later (I just need it to work with a FIFO rule, with the pregnant criteria it works as expected).
I sorted the list first with the compareTo()
method and then with the external comparator class I created.
public class Main {
public static void main(String[] args) {
List<Customer> pharmacyQueue = new ArrayList<>();
CustomerComparator customerComparator = new CustomerComparator();
pharmacyQueue.add(new Customer(25, false, "Przemek"));
pharmacyQueue.add(new Customer(35, true, "Anita"));
pharmacyQueue.add(new Customer(55, false, "Wiesława"));
pharmacyQueue.add(new Customer(25, true, "Maryja"));
pharmacyQueue.add(new Customer(85, false, "Halinka"));
pharmacyQueue.add(new Customer(55, false, "Stasia"));
pharmacyQueue.add(new Customer(20, true, "Marta"));
pharmacyQueue.add(new Customer(65, false, "Bożenka"));
pharmacyQueue.add(new Customer(75, false, "Paoasdo"));
Collections.sort(pharmacyQueue);
Collections.sort(pharmacyQueue, customerComparator);
System.out.println("Sorted queue: ");
for (Customer c : pharmacyQueue){
System.out.println(c);
}
}
}
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Customer implements Comparable<Customer> {
private int age;
private boolean isPregnant;
private String name;
public int compareTo(Customer o) {
if (this.age > 60){
return -1;
}else if (this.age < 60){
return 1;
}
return 0;
}
public class CustomerComparator implements Comparator<Customer> {
@Override
public int compare(Customer o1, Customer o2) {
if (o1.isPregnant() && !o2.isPregnant()){
return -1;
}
if (o1.isPregnant() && o2.isPregnant()){
return 1;
}
return 0;
}
}
The result:
Sorted queue:
Customer(age=35, isPregnant=true, name=Anita) //fine
Customer(age=25, isPregnant=true, name=Maryja) //fine
Customer(age=20, isPregnant=true, name=Marta) //fine
Customer(age=75, isPregnant=false, name=Paoasdo) //should be 6th
Customer(age=65, isPregnant=false, name=Bożenka) //should be 5th
Customer(age=85, isPregnant=false, name=Halinka) //should be 4th
Customer(age=25, isPregnant=false, name=Przemek) //fine
Customer(age=55, isPregnant=false, name=Wiesława) //fine
Customer(age=55, isPregnant=false, name=Stasia) //fine
Upvotes: 1
Views: 358
Reputation: 12440
For that, you essentially need two things:
Collections.sort()
is guaranteed to be stableUpvotes: 2
Reputation: 147154
As pointing out in the comments, sorting the list twice does the same thing as sorting with the second ordering only (only slower). Oh, and many sorts such as QuickSort are unstable (rearrange tied values), whilst other such as MergeSort are stable.
You want to combine the comparators (or comparator and comparable). Fortunately (since 1.8) this is really easy with these two methods in java.util.Comparator
static <T extends Comparable<? super T>> Comparator<T> naturalOrder()
default Comparator<T> thenComparing(Comparator<? super T> other)
Getting those the right way around is left as an exercise.
Upvotes: 0