es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

El TreeMap de Java no se ordena según el comparador proporcionado.

He implementado un TreeMap que contiene planos (para simplificarlo).

private TreeMap<buildingfloorkey, blueprint=""> blueprints = new TreeMap<>((o1, o2) -> {
        int value = o1.compareTo(o2);
        return value;
});

Para utilizar el edificio (en mi caso llamado complejo) y el piso como una clave de tupla, escribí la siguiente clase:

public static class BuildingFloorKey {
    private Complex mComplex;
    private int mFloor;

    public BuildingFloorKey(Complex complex, int floor){
        mComplex = complex;
        mFloor = floor;
    }

    @Override
    public boolean equals(Object other) {
        if (!(other instanceof BuildingFloorKey)) return false;
        BuildingFloorKey that = (BuildingFloorKey) other;
        return mFloor == that.mFloor && mComplex.equals(that.mComplex);
    }

    @Override
    public int hashCode() {
        return Arrays.hashCode(new Object[]{mComplex, mFloor});
    }

    public int compareTo(BuildingFloorKey otherKey){
        if(this.equals(otherKey)) return 0;

        //mismo complejo -> comparar pisos
        else if (this.getComplex().equals(otherKey.getComplex())){
            return otherKey.getFloorInt() - this.getFloorInt();
        }
        //complejos diferentes (incl. alguna modificación para casos especiales)
        else return -(Math.abs(otherKey.mFloor + 2) + 100);
    }
}

Estoy trabajando en una aplicación de Android y quiero navegar por los planos mediante botones. Para ello, utilizo los métodos TreeMap.lowerKey(otherKey) y TreeMap.higherKey(otherKey). De esta manera:

@Override
    public void onNextPlanClicked() {
           nextFloorPlan = blueprints.higherKey(currentlyDisplayedPlan);
           drawFloorPlan(nextFloorPlan);
        }

Como ejemplo, tengo un caso de uso donde el conjunto de planos es:

  • 04|02
  • 03|03
  • 04|-1
  • 03|00

(formato: complejo|piso). Desafortunadamente, no está ordenado correctamente en el TreeMap (como se puede ver, la lista anterior está ordenada como las entradas del TreeMap en el depurador).

Leí algo sobre la ordenación de TreeMap usando cadenas distinguiendo entre mayúsculas y minúsculas. Pero en realidad estoy usando enteros. Entonces no entiendo por qué la ordenación y el uso de lowerKey() y higherKey() no funcionan correctamente. ¿Me equivoqué con el comparador? ¿Alguien puede ayudar, por favor?</buildingfloorkey,>

Tags:  , , ,

Answer

  1. Avatar for davy.ai

    Problema con la clasificación y uso de lowerKey() y higherKey() en TreeMap

    El problema en este caso es la implementación del método compareTo() en la clase BuildingFloorKey. Según el código, si los complejos son diferentes, el resultado siempre es un valor negativo, lo que provoca que TreeMap clasifique los elementos de una manera extraña, mostrando resultados que no se esperan.

    Para solucionar esto, necesitamos modificar el método compareTo() para que compare correctamente los dos objetos BuildingFloorKey. Aquí hay una posible solución:

    public int compareTo(BuildingFloorKey otherKey) {
        if (this.equals(otherKey)) return 0;
    
        int complexCompare = this.mComplex.compareTo(otherKey.mComplex);
        if (complexCompare != 0) {
            return complexCompare;
        }
    
        return Integer.compare(this.mFloor, otherKey.mFloor);
    }
    

    Este método compareTo() modificado compara los complejos primero y, si son diferentes, devuelve el resultado de la comparación. Si son iguales, compara los pisos y devuelve el resultado de la comparación.

    Con esta modificación, TreeMap clasificará los planos como se espera y los métodos lowerKey() y higherKey() funcionarán correctamente.

    ¡Espero que esto ayude!

Comments are closed.