ordenado - metodos de hashmap java




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

Agregando a la respuesta más votada y muchas de las anteriores, enfatizando "más genérico, mejor", me gustaría profundizar un poco más.

Map es la estructura del contrato, mientras que HashMap es una implementación que proporciona sus propios métodos para tratar diferentes problemas reales: cómo calcular el índice, cuál es la capacidad y cómo incrementarla, cómo insertar, cómo mantener el índice único, etc.

Veamos el código fuente:

En Map tenemos el método de containsKey(Object key) :

boolean containsKey(Object key);

JavaDoc:

booleano java.util.Map.containsValue (valor del objeto)

Devuelve verdadero si este mapa asigna una o más claves al valor especificado. Más formalmente, devuelve verdadero si y solo si este mapa contiene al menos una asignación a un valor v tal que (value==null ? v==null : value.equals(v)) . Es probable que esta operación requiera un tiempo lineal en el tamaño del mapa para la mayoría de las implementaciones de la interfaz del mapa.

Parámetros: valor

Valor cuya presencia en este mapa es para betested.

Devoluciones: verdad

si este mapa mapea una o más claves a la especificada

valueThrows:

ClassCastException - si el valor es de un tipo inapropiado para este mapa (opcional)

NullPointerException: si el valor especificado es nulo y este mapa no permite valores nulos (opcional)

Requiere sus implementaciones para implementarlo, pero el "cómo" está en su libertad, solo para garantizar que se devuelva correctamente.

En HashMap :

public boolean containsKey(Object key) {
    return getNode(hash(key), key) != null;
}

Resulta que HashMap utiliza el código hash para probar si este mapa contiene la clave. Así que tiene el beneficio del algoritmo hash.

¿Cuál es la diferencia entre los siguientes mapas que creo (en otra pregunta, las personas respondieron usándolos de forma indistinta y me pregunto si / cómo son diferentes):

HashMap<String, Object> map = new HashMap<String, Object>();
Map<String, Object> map = new HashMap<String, Object>();

Como lo señalaron TJ Crowder y Adamski, una referencia es a una interfaz, la otra a una implementación específica de la interfaz. De acuerdo con Joshua Block, siempre debe intentar codificar las interfaces, para permitirle manejar mejor los cambios en la implementación subyacente, es decir, si HashMap de repente no era lo ideal para su solución y necesitaba cambiar la implementación del mapa, aún podría usar el Mapa. Interfaz, y cambiar el tipo de instanciación.


HashMap es una implementación de Map, por lo que es bastante similar, pero tiene el método "clone ()" que veo en la guía de referencia))


Map is interface y Hashmap es una clase que implementa Map Interface.


Mapa es la interfaz y Hashmap es la clase que implementa eso.

Así que en esta implementación creas los mismos objetos.


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

La ventaja de usar Map<String, Object> es que puede cambiar el objeto subyacente para que sea un tipo diferente de mapa sin romper su contrato con cualquier código que lo esté utilizando. Si lo declara como HashMap<String, Object> , tiene que cambiar su contrato si desea cambiar la implementación subyacente.

Ejemplo: Digamos que escribo esta clase:

class Foo {
    private HashMap<String, Object> things;
    private HashMap<String, Object> moreThings;

    protected HashMap<String, Object> getThings() {
        return this.things;
    }

    protected HashMap<String, Object> getMoreThings() {
        return this.moreThings;
    }

    public Foo() {
        this.things = new HashMap<String, Object>();
        this.moreThings = new HashMap<String, Object>();
    }

    // ...more...
}

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

Más tarde, Mary escribe el código subclasificándolo. Ella tiene algo que necesita hacer con ambas things y más things , así que naturalmente pone eso en un método común, y usa el mismo tipo que usé en getThings / getMoreThings cuando define su método:

class SpecialFoo extends Foo {
    private void doSomething(HashMap<String, Object> t) {
        // ...
    }

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

    // ...more...
}

Más tarde, decido que, en realidad, es mejor si utilizo TreeMap lugar de HashMap en Foo . Actualizo Foo , cambiando HashMap a TreeMap . Ahora, SpecialFoo ya no compila, porque SpecialFoo el contrato: Foo solía decir que proporcionaba HashMap s, pero ahora está proporcionando TreeMaps . Así que tenemos que arreglar SpecialFoo ahora (y este tipo de cosas pueden pasar a través de un código base).

A menos que tuviera una buena razón para compartir que mi implementación estaba usando un HashMap (y eso sí ocurre), lo que debería haber hecho fue declarar getThings y getMoreThings como simplemente devolver Map<String, Object> 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 más things como Map , no HashMap / TreeMap :

class Foo {
    private Map<String, Object> things;             // <== Changed
    private Map<String, Object> moreThings;         // <== Changed

    protected Map<String, Object> getThings() {     // <== Changed
        return this.things;
    }

    protected Map<String, Object> getMoreThings() { // <== Changed
        return this.moreThings;
    }

    public Foo() {
        this.things = new HashMap<String, Object>();
        this.moreThings = new HashMap<String, Object>();
    }

    // ...more...
}

Tenga en cuenta que ahora estoy usando Map<String, Object> todos los lugares que puedo, solo siendo específico cuando creo los objetos reales.

Si hubiera hecho eso, entonces María habría hecho esto:

class SpecialFoo extends Foo {
    private void doSomething(Map<String, Object> t) { // <== Changed
        // ...
    }

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

... y el cambio de Foo no hubiera hecho que SpecialFoo dejara de compilar.

Las interfaces (y las clases básicas) nos permiten revelar solo lo necesario , manteniendo nuestra flexibilidad bajo las coberturas para hacer los cambios que sean apropiados. En general, queremos que nuestras referencias sean lo más básicas posible. Si no necesitamos saber que es un HashMap , solo HashMap Map .

Esta no es una regla ciega, pero en general, la codificación a la interfaz más general será menos frágil que la codificación a algo más específico. Si lo hubiera recordado, no habría creado un Foo que configurara a Mary para el fracaso con SpecialFoo . Si Mary hubiera recordado eso, entonces, a pesar de que arruiné a Foo , habría declarado su método privado con Map lugar de HashMap y el cambio de contrato de Foo 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 estar, errar hacia la interfaz menos específica.


Tú creas los mismos mapas.

Pero puedes llenar la diferencia cuando la uses. Con el primer caso podrás usar métodos especiales de HashMap (pero no recuerdo a nadie realmente útil), y podrás pasarlo como un parámetro de HashMap:

public void foo (HashMap<String, Object) { ... }

...

HashMap<String, Object> m1 = ...;
Map<String, Object> m2 = ...;

foo (m1);
foo ((HashMap<String, Object>)m2); 

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 las funciones definidas en la interfaz del Mapa, mientras que la primera permitirá el uso de cualquier función pública en el HashMap (que incluye la interfaz del Mapa).

Probablemente tenga más sentido si lees el tutorial de la interfaz de Sun.


HashMap<String, Object> map1 = new HashMap<String, Object>();
Map<String, Object> map2 = new HashMap<String, Object>();  

En primer lugar, Map es una interfaz que tiene diferentes implementaciones como: HashMap , TreeHashMap , LinkedHashMap , etc. La interfaz funciona como una súper clase para la clase implementadora. Entonces, de acuerdo con la regla de OOP, cualquier clase concreta que implemente Map es también Map . Eso significa que podemos asignar / poner cualquier variable de tipo HashMap a una variable de tipo Map sin ningún tipo de conversión.

En este caso, podemos asignar map1 a map2 sin ningún lanzamiento o pérdida de datos.

map2 = map1




hashmap