EDIT 1 - Com Priorityqueue
In case 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 the class Conta
:
private static int ultimo = 0;
Create an attribute ordem
which will be used internally:
private final int ordem;
In the constructor, type the order and update the variable ultimo
:
this.ordem = ultimo + 1;
ultimo = this.ordem;
Add the get
country ordem
:
public int getOrdem() {
return ordem;
}
To make the comparison, you don’t need a Comparator
, only that its class Conta
implement the interface
Comparable
as follows:
public class Conta implements Comparable<Conta> {
You will need to implement the method compareTo
which will look like the following, respecting the 3 rules imposed on 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 the items after the poll
.
This will result in:
- "A",2
- "A",1
- "B",3
- "A",5
- "B",6
Sem Priorityqueue
I believe that using the Collections.sort
and PriorityQueue
is not the best choice because there already exists a structure with the requirement 3
which is the insertion order. The LinkedHashSet
.
I will put here two implementations and the test of both is carried out 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 the method toString
next:
@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" have top 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 necessary to use PriorityQueue
you can do the conversion below:
PriorityQueue pq = new PriorityQueue();
pq.addAll(listaOrdenada);
Just something expensive. To access the attribute
numero
you use a same method?numero()
?– Sorack
by chance until it was get number, already changed
– rrr
In your example the final correct order would not be: "A",2 "B",3 "A",1 "A",5 "B",6?
– Sorack