como - treeset java 8
¿Por qué mi TreeSet no agrega nada más allá del primer elemento? (1)
Si coloca sus objetos en un TreeSet
, debe proporcionar una implementación de la interfaz Comparator
en el constructor o necesita que sus objetos TreeSet
a una clase que implemente Comparable
.
Dijiste que implementa compareTo
desde la interfaz Comparable
, pero en tu comentario dices que no, así que estoy en lo cierto al asumir que simplemente return 0;
en el método compareTo
? Eso explicaría su problema, porque TreeSet pensaría que todos sus objetos son "iguales" en función del resultado del método compareTo
.
Básicamente, en un TreeSet
, sus objetos se mantienen en un orden ordenado, y la clasificación se determina por el resultado del método Comparable / Comparador. Esto se usa para buscar rápidamente duplicados en un TreeSet y tiene el beneficio adicional de que cuando itera sobre TreeSet, obtiene los resultados en orden ordenado.
El Javadoc de TreeSet
dice:
Tenga en cuenta que la ordenación mantenida por un conjunto (independientemente de si se proporciona un comparador explícito o no) debe ser coherente con igual si se trata de implementar correctamente la interfaz
Set
.
La forma más fácil de lograr eso es dejar que su método compareTo
llame al método compareTo
y verifique si el resultado es 0
.
Dada tu clase PatientImpl
, supongo que te gustaría clasificar a los pacientes primero por su apellido, luego por su primer nombre y luego por el resto de los campos de la clase.
Puede implementar un método compareTo
como este:
@Override
public int compareTo(Object o) {
if (!(o instanceof Patient))
return -1;
Patient temp = (Patient) o;
int r = this.lastName.compareToIgnoreCase(temp.getLastName());
if (r == 0)
r = this.firstName.compareToIgnoreCase(temp.getFirstName());
if (r == 0)
r = this.SSN.compareToIgnoreCase(temp.getSSN());
if (r == 0)
r = this.dob.toString().compareToIgnoreCase(temp.getDOB().toString());
if (r == 0)
r = Integer.compare(this.getID(), temp.getID());
return r;
}
Creo que eso resolvería el problema que describes. Te aconsejaría que leas (Javadoc o libros) en TreeSet
y HashSet
y la importancia de los métodos equals
, compareTo
y hashCode
. Si desea colocar sus objetos en un Conjunto o un Mapa, debe conocerlos para implementarlos correctamente.
Tenga en cuenta que compareTo
este método compareTo
en su método equals
. Estabas comparando la fecha de nacimiento llamando primero a String. Esa no es una buena manera de hacerlo: puedes usar el método equals
en java.util.Date directamente. En un método compareTo, el problema empeora porque las fechas no se ordenan correctamente cuando las ordena alfabéticamente. java.util.Date
también implementa Comparable
para que pueda reemplazar esa comparación en el método con:
if (r == 0)
r = this.dob.compareTo(temp.getDOB());
Además, si alguno de los campos puede ser null
, debe verificarlo también.
Tengo varias matrices en el formulario:
private static String[] patientNames = { "John Lennon", "Paul McCartney", "George Harrison", "Ringo Starr" };
Luego hago un TreeSet como este:
TreeSet<Patient> patTreeSet = new TreeSet<Patient>();
Donde el paciente es una clase diferente que crea objetos "pacientes". Luego patTreeSet
cada elemento en mis matrices para crear varios pacientes y agregarlos a mi patTreeSet
esta manera:
for(int i = 0; i< patientNames.length; i++){
Date dob = date.getDate("MM/dd/yyyy", patientBirthDates[i]);
Patient p = new PatientImpl(patientNames[i], patientSSN[i], dob);
patTreeSet.add(p);
}
Pero cuando voy a comprobar mi patTreeSet.size()
solo devuelve "1", ¿por qué es esto?
Sé que mis objetos funcionan bien porque cuando trato de hacer lo mismo pero con ArrayList
lugar, todo funciona bien. Así que supongo que estoy usando el TreeSet mal.
Si ayuda, el paciente tiene un método llamado getFirstName (), y cuando intento hacer lo siguiente:
Iterator<Patient> patItr = patTreeSet.iterator();
while(patItr.hasNext()){
System.out.println(patItr.next().getFirstName());
}
Entonces solo se imprime "John", lo que obviamente no debería ser el caso ... Entonces, ¿estoy haciendo un uso incorrecto del TreeSet?
¡Gracias de antemano por cualquier ayuda!
EDITAR debajo
================ PatientImpl Class ====================
public class PatientImpl implements Patient, Comparable{
Calendar cal = new GregorianCalendar();
private String firstName;
private String lastName;
private String SSN;
private Date dob;
private int age;
private int thisID;
public static int ID = 0;
public PatientImpl(String fullName, String SSN, Date dob){
String[] name = fullName.split(" ");
firstName = name[0];
lastName = name[1];
this.SSN = SSN;
this.dob = dob;
thisID = ID += 1;
}
@Override
public boolean equals(Object p) {
//for some reason casting here and reassigning the value of p doesn''t take care of the need to cast in the if statement...
p = (PatientImpl) p;
Boolean equal = false;
//make sure p is a patient before we even compare anything
if (p instanceof Patient) {
Patient temp = (Patient) p;
if (this.firstName.equalsIgnoreCase(temp.getFirstName())) {
if (this.lastName.equalsIgnoreCase(temp.getLastName())) {
if (this.SSN.equalsIgnoreCase(temp.getSSN())) {
if(this.dob.toString().equalsIgnoreCase(((PatientImpl) p).getDOB().toString())){
if(this.getID() == temp.getID()){
equal = true;
}
}
}
}
}
}
return equal;
}
y luego todos los getters están debajo, al igual que el método compareTo () de la interfaz Comparable