¿Cómo puedo mejorar el comparador de objetos por varios campos? El comparador debe ordenar usuario por el apellido o el nombre si el apellido no existe. Y si no hay apellido y el nombre de ordenar por nombre de usuario. Sin embargo, estos usuarios deben estar al final de la lista.
public static Comparator<UserConfigurationDto> BY_LASTNAME = (u1, u2) -> {
// if users have only username compare them
if((u1.getLastName().isEmpty() && u1.getFirstName().isEmpty())
&& (u2.getLastName().isEmpty() && u2.getFirstName().isEmpty())){
return u1.getUsername().compareToIgnoreCase(u2.getUsername());
}
//if user doesnt have firstName and LastName drop them at the end
if(u1.getLastName().isEmpty() && u1.getFirstName().isEmpty()){
return 1000000 + getWeight(u1.getUsername());
}
if(u2.getLastName().isEmpty() && u2.getFirstName().isEmpty()){
return -1000000 + getWeight(u2.getUsername());
}
String s1 = u1.getLastName().isEmpty() ? u1.getFirstName() : u1.getLastName();
String s2 = u2.getLastName().isEmpty() ? u2.getFirstName() : u2.getLastName();
return s1.compareToIgnoreCase(s2);
};
}
private static int getWeight(String s){
return s.codePoints().sum();
}
¿Alguien tiene una idea de cómo mejorar esto? Trato de usar Comparator.comparing y Comparator.thenComparing sino que producen un resultado incorrecto
1) return 1000000 + getWeight(u1.getUsername());
y return -1000000 + getWeight(u2.getUsername());
no son necesarios. return 1
y return -1
es más clara y produce el mismo resultado si se hace referencia a la CompareTo()
javadoc:
Compara este objeto con el objeto especificado por el orden. Devuelve un negativo del número entero, cero , o un positivo entero como este objeto es menor que, igual a, o mayor que el objeto especificado
2) No encadenar las comparaciones de campo, pero hay 3 formas de clasificación de acuerdo con el estado de los objetos comparados. Por lo que el hecho de que el código sea un poco más detallado para definir cada caso es finalmente normal.
Se podría reducir todo lo mismo que con un método de extracto como duplicar una gran cantidad de user.getLastName().isEmpty()
invocaciones.
Por ejemplo :
public static Comparator<UserConfigurationDto> BY_LASTNAME = (u1, u2) -> {
// first case
if( u1.isLastAndFirstNameEmpty() && u2.isLastAndFirstNameEmpty()){
return u1.getUsername().compareToIgnoreCase(u2.getUsername());
}
// second case
if(u1.isLastAndFirstNameEmpty()){
return 1;
}
else if(u2.isLastAndFirstNameEmpty()){
return -1;
}
// third case
String s1 = u1.getLastName().isEmpty() ? u1.getFirstName() : u1.getLastName();
String s2 = u2.getLastName().isEmpty() ? u2.getFirstName() : u2.getLastName();
return s1.compareToIgnoreCase(s2);
};