Comparación de objetos basado en los valores de varios campos utilizando Comparador

Vladimir Goncharov:

¿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

davidxxx:

1) return 1000000 + getWeight(u1.getUsername());y return -1000000 + getWeight(u2.getUsername());no son necesarios. return 1y return -1es 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);
    };

Supongo que te gusta

Origin http://43.154.161.224:23101/article/api/json?id=332676&siteId=1
Recomendado
Clasificación