How to sort duplicate rows using a comparator?

Let's say I have a list in which there are workers, each employee has 3 fields: his name, the department in which he works (there may be only the name of the department or an object from the class department) and his salary.

Elvis Software Engineering 1000 Samba Mechanical Engineering 2000 Bamba Industrial Engineering 3000 Bisli Medical Engineering 4000 Kinder Electrical Engineering 1000 Elvis Software Engineering 9999 

Now I want to sort them by their names and put the result in the queue. and put the queue on the card, ordered from the bottom up so the result that I want after sorting:

 Bamba Industrial Engineering 3000 Bisli Medical Engineering 4000 Elvis Software Engineering 1000 Elvis Software Engineering 9999 Samba Mechanical Engineering 2000 Kinder Electrical Engineering 1000 

I am not allowed to use Collection.sort (), so I use a comparator that sorts workers by their names, if the name is equal - it is sorted by the department, if the department is equal - it is sorted by salary. here the comparator I wrote:

  class WorkerComparatorByName implements Comparator<Worker<?>> { @Override public int compare(Worker<?> w1, Worker<?> w2) { int compareValue = w1.getName().compareTo(w2.getName()); if (compareValue != 0) return compareValue; compareValue = w1.getDepartment().toString().compareTo(w2.getDepartment().toString()); if (compareValue != 0) return compareValue; return w1.getSalary() - w2.getSalary(); } } 

The problem is this:

 Bamba Industrial Engineering 3000 Bisli Medical Engineering 4000 Elvis Software Engineering 1000 Samba Mechanical Engineering 2000 Kinder Electrical Engineering 1000 Elvis Software Engineering 9999 

all workers are sorted, but Elvis (which is duplicated) is NOT sorted, he remains at the end of the queue. I tried replacing Elvis with another duplicate name and the same result. What am I missing? how can i sort the duplicate value so that they are one by one? Here is the code:

  public <T extends Worker<?>> Map<?, ?> createMap(ArrayList<T> list) { int i = 1; // creating a PriorityQueue sorted by names Queue<T> pq = new PriorityQueue<>(new WorkerComparatorByName()); // filling the PriorityQueue with the workers pq.addAll(list); Map<Integer, T> treeMap = new TreeMap<Integer, T>(); // iterating over the PriorityQueue and puting the workers in the map for (T element : pq) treeMap.put(i++, element); return treeMap; } 
+7
java sorting treemap queue comparator
source share
3 answers

PriorityQueue API:

The iterator provided in the iterator method () does not guarantee that the elements of the priority queue intersect in any particular order. If you need an ordered workaround, consider using the Arrays.sort array (pq.toArray ()).

+2
source share

Instead of using the foreach use the regular for and poll() loop elements from the queue.

 // creating a PriorityQueue sorted by names Queue<T> pq = new PriorityQueue<>(new WorkerComparatorByName()); // filling the PriorityQueue with the workers pq.addAll(list); Map<Integer, T> treeMap = new TreeMap<Integer, T>(); int size = pq.size(); for (int j = 0; j < size; j++) { treeMap.put(j + 1, pq.poll()); } 
+1
source share

Used this question as an exercise for streaming / lambda, also used some Java 8 comparing goodies. I saw that you have finished using TreeSet , which is a good solution, but I will add this anyway if anyone is interested.

 PriorityQueue<Worker> queue = new PriorityQueue<>(Comparator.comparing(Worker::getName) .thenComparing(Worker::getDepartment) .thenComparing(Worker::getSalary)); queue.addAll(list); TreeMap<Integer, Worker> treeMap = IntStream.range(1, queue.size() + 1) .boxed() .collect(Collectors.toMap(Function.identity(), o -> queue.poll(), (u, v) -> { throw new Error("Will never happen"); }, TreeMap::new)); 
0
source share

All Articles