Saltar al contenido

¿Cuál es la diferencia entre los objetos HashMap y Map en Java?

Nuestro team de expertos pasados varios días de trabajo y recopilación de de información, dimos con los datos necesarios, esperamos que te resulte útil para tu trabajo.

Solución:

No hay diferencia entre los objetos; usted tiene un HashMap en ambos casos. Hay una diferencia en el interfaz tienes al objeto. En el primer caso, la interfaz es HashMap, mientras que en el segundo es Map. Pero el objeto subyacente es el mismo.

La ventaja de usar Map es que puede cambiar el objeto subyacente para que sea un tipo diferente de mapa sin romper su contrato con ningún código que lo esté usando. Si lo declaras como HashMap, debe cambiar su contrato si desea cambiar la implementación subyacente.


Ejemplo: digamos que escribo esta clase:

class Foo 
    private HashMap things;
    private HashMap moreThings;

    protected HashMap getThings() 
        return this.things;
    

    protected HashMap getMoreThings() 
        return this.moreThings;
    

    public Foo() 
        this.things = new HashMap();
        this.moreThings = new HashMap();
    

    // ...more...

La clase tiene un par de mapas internos de string-> objeto que comparte (a través de métodos de acceso) con subclases. Digamos que lo escribo con HashMaps para empezar porque creo que esa es la estructura apropiada para usar al escribir la clase.

Más tarde, Mary escribe código subclasificando. Ella tiene algo que necesita hacer con ambos things y moreThings, así que, naturalmente, lo pone en un método común, y usa el mismo tipo que usé en getThings/getMoreThings al definir su método:

class SpecialFoo extends Foo 
    private void doSomething(HashMap t) 
        // ...
    

    public void whatever() 
        this.doSomething(this.getThings());
        this.doSomething(this.getMoreThings());
    

    // ...more...

Más tarde, decido que en realidad es mejor si uso TreeMap en lugar de HashMap en Foo. Yo actualizo Foo, cambiando HashMap para TreeMap. Ahora, SpecialFoo ya no se compila porque rompí el contrato: Foo solía decir que siempre HashMaps, pero ahora proporciona TreeMaps en lugar de. Entonces tenemos que arreglar SpecialFoo ahora (y este tipo de cosas pueden propagarse a través de una base de código).

A menos que tuviera una muy buena razón para compartir que mi implementación estaba usando un HashMap (y eso sucede), lo que debí haber hecho fue declarar getThings y getMoreThings como solo regresando Map sin ser más específico que eso. De hecho, salvo una buena razón para hacer otra cosa, incluso dentro de Foo Probablemente debería declarar things y moreThings como Map, no HashMap/TreeMap:

class Foo 
    private Map things;             // <== Changed
    private Map moreThings;         // <== Changed

    protected Map getThings()      // <== Changed
        return this.things;
    

    protected Map getMoreThings()  // <== Changed
        return this.moreThings;
    

    public Foo() 
        this.things = new HashMap();
        this.moreThings = new HashMap();
    

    // ...more...

Note como estoy usando ahora Map en todas partes que puedo, solo siendo específico cuando creo los objetos reales.

Si hubiera hecho eso, Mary habría hecho esto:

class SpecialFoo extends Foo 
    private void doSomething(Map t)  // <== Changed
        // ...
    

    public void whatever() 
        this.doSomething(this.getThings());
        this.doSomething(this.getMoreThings());
    

... y cambiando Foo no hubiera hecho SpecialFoo dejar de compilar.

Las interfaces (y clases base) nos permiten revelar solo lo necesario, manteniendo nuestra flexibilidad bajo las sábanas para realizar cambios según corresponda. En general, queremos que nuestras referencias sean lo más básicas posible. Si no necesitamos saber que es un HashMap, solo llámalo un Map.

Esta no es una regla ciega, pero en general, codificación a la interfaz más general va a ser menos frágil que codificar algo más específico. Si hubiera recordado eso, no habría creado un Foo que preparó a Mary para el fracaso con SpecialFoo. Si María había recordado eso, entonces, a pesar de que lo arruiné Foo, ella habría declarado su método privado con Map en lugar de HashMap y mi cambio FooEl contrato no habría afectado su código.

A veces no puedes hacer eso, a veces tienes que ser específico. Pero a menos que tenga una razón para estarlo, diríjase hacia la interfaz menos específica.

Map es una interfaz que implementa HashMap. La diferencia es que en la segunda implementación su referencia al HashMap solo permitirá el uso de funciones definidas en la interfaz del Mapa, mientras que la primera permitirá el uso de cualquier función pública en HashMap (que incluye la interfaz del Mapa).

Probablemente tendrá más sentido si lee el tutorial de interfaz de Sun

ingrese la descripción de la imagen aquí

Map tiene las siguientes implementaciones:

  1. HashMap Map m = new HashMap();

  2. LinkedHashMap Map m = new LinkedHashMap();

  3. Mapa del árbol Map m = new TreeMap();

  4. WeakHashMap Map m = new WeakHashMap();

Suponga que ha creado un método (esto es solo un pseudocódigo).

public void HashMap getMap()
   return map;

Suponga que los requisitos de su proyecto cambian:

  1. El método debe devolver el contenido del mapa: es necesario volver HashMap.
  2. El método debería devolver el mapa keyestá en orden de inserción - Necesita cambiar el tipo de devolución HashMap para LinkedHashMap.
  3. El método debería devolver el mapa keyestá en orden: es necesario cambiar el tipo de devolución LinkedHashMap para TreeMap.

Si su método devuelve clases específicas en lugar de algo que implementa el Map interfaz, tienes que cambiar el tipo de retorno de getMap() método cada vez.

Pero si usa la función de polimorfismo de Java, y en lugar de devolver clases específicas, use la interfaz Map, mejora la reutilización del código y reduce el impacto de los cambios de requisitos.

Si te gustó nuestro trabajo, tienes la libertad de dejar una reseña acerca de qué le añadirías a este tutorial.

¡Haz clic para puntuar esta entrada!
(Votos: 0 Promedio: 0)



Utiliza Nuestro Buscador

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *