EDIT 1 - With PriorityQueue
If you really need to use PriorityQueue
to sort, I suggest creating a control variable to know the insertion order.
Create a class variable to control the last inserted within class Conta
:
private static int ultimo = 0;
Create a ordem
attribute that will be used internally:
private final int ordem;
In the constructor, instantiate the order and update the variable ultimo
:
this.ordem = ultimo + 1;
ultimo = this.ordem;
Add get
of field ordem
:
public int getOrdem() {
return ordem;
}
To make the comparison, you do not need a Comparator
, just that your Conta
class implements interface
Comparable
as follows:
public class Conta implements Comparable<Conta> {
You will need to implement the compareTo
method that will look like the following, respecting the 3 rules imposed in the topic:
@Override
public int compareTo(Conta conta) {
// 1. Tem de vir os que tem um numero inferior a 4
if (this.numero < 4 && conta.getNumero() >= 4) {
return -1;
} else if (this.numero >= 4 && conta.getNumero() < 4) {
return 1;
}
// 2. Tem de vir os que começam com a letra A
if (this.designacao.toUpperCase().startsWith("A") && !conta.getDesignacao().toUpperCase().startsWith("A")) {
return -1;
} else if (!this.designacao.toUpperCase().startsWith("A") && conta.getDesignacao().toUpperCase().startsWith("A")) {
return 1;
}
// 3. Ordem de inserção
return Integer.valueOf(this.ordem).compareTo(conta.getOrdem());
}
To test use:
public static void main(String[] args) {
PriorityQueue<Conta> listaOrdenada = new PriorityQueue<>();
listaOrdenada.add(new Conta("A", 2));
listaOrdenada.add(new Conta("B", 3));
listaOrdenada.add(new Conta("B", 6));
listaOrdenada.add(new Conta("A", 1));
listaOrdenada.add(new Conta("A", 5));
while(!listaOrdenada.isEmpty()) {
System.out.println(listaOrdenada.poll());
}
}
Remembering that the structure you are using ( PriorityQueue
) rearranges items after poll
.
This will result in:
- "A", 2
- "A", 1
- "B", 3
- "A", 5
- "B", 6
No PriorityQueue
I believe using Collections.sort
and PriorityQueue
is not the best choice because there is already a structure with the 3
requirement that is the insertion order. The LinkedHashSet
.
I will put here two implementations and the test of the two is accomplished with the following code:
LinkedHashSet<Conta> lista = new LinkedHashSet<>();
LinkedHashSet<Conta> listaOrdenada;
lista.add(new Conta("A", 2));
lista.add(new Conta("B", 3));
lista.add(new Conta("B", 6));
lista.add(new Conta("A", 1));
lista.add(new Conta("A", 5));
listaOrdenada = this.ordenar(lista);
for (Conta conta : listaOrdenada) {
System.out.println(conta);
}
Where the account class has method toString
following:
@Override
public String toString() {
return "\"" + this.designacao + "\"," + String.valueOf(this.numero);
}
The first considers only the 3 isolated rules:
public LinkedHashSet<Conta> ordenar(LinkedHashSet<Conta> lista) {
LinkedHashSet<Conta> prioridade1 = new LinkedHashSet<>(); // Números menores que 4
LinkedHashSet<Conta> prioridade2 = new LinkedHashSet<>(); // Letra "A"
LinkedHashSet<Conta> restante = new LinkedHashSet<>();
LinkedHashSet<Conta> listaOrdenada = new LinkedHashSet<>();
for (Conta conta : lista) {
if (conta.getNumero() < 4) {
prioridade1.add(conta);
} else if (conta.getDesignacao().toUpperCase().startsWith("A")) {
prioridade2.add(conta);
} else {
restante.add(conta);
}
}
listaOrdenada.addAll(prioridade1);
listaOrdenada.addAll(prioridade2);
listaOrdenada.addAll(restante);
return listaOrdenada;
}
Resulting in:
- "A", 2
- "B", 3
- "A", 1
- "A", 5
- "B", 6
The second considers that numbers smaller than 4 and with letter "A" has the highest priority:
public LinkedHashSet<Conta> ordenar(LinkedHashSet<Conta> lista) {
LinkedHashSet<Conta> prioridade1 = new LinkedHashSet<>(); // Números menores que 4 com letra "A"
LinkedHashSet<Conta> prioridade2 = new LinkedHashSet<>(); // Números menores que 4
LinkedHashSet<Conta> prioridade3 = new LinkedHashSet<>(); // Letra "A"
LinkedHashSet<Conta> restante = new LinkedHashSet<>();
LinkedHashSet<Conta> listaOrdenada = new LinkedHashSet<>();
for (Conta conta : lista) {
if (conta.getNumero() < 4
&& conta.getDesignacao().toUpperCase().startsWith("A")) {
prioridade1.add(conta);
} else if (conta.getNumero() < 4) {
prioridade2.add(conta);
} else if (conta.getDesignacao().toUpperCase().startsWith("A")) {
prioridade3.add(conta);
} else {
restante.add(conta);
}
}
listaOrdenada.addAll(prioridade1);
listaOrdenada.addAll(prioridade2);
listaOrdenada.addAll(prioridade3);
listaOrdenada.addAll(restante);
return listaOrdenada;
}
Resulting in:
- "A", 2
- "A", 1
- "B", 3
- "A", 5
- "B", 6
If you need to use PriorityQueue
you can do the following conversion:
PriorityQueue pq = new PriorityQueue();
pq.addAll(listaOrdenada);