2009-08-28 11 views
55

así que tengo dos preguntas sobre HashMap s en Java:¿Forma correcta de inicializar HashMap y puede HashMap contener diferentes tipos de valores?

  1. Cuál es la forma correcta para inicializar un HashMap? Creo que podría ser mejor en mi situación de usar:

    HashMap x = new HashMap(); 
    

    Pero Eclipse se mantenga lo que sugiere que utilizo:

    HashMap<something, something> map = new HashMap(); 
    

    ¿Qué es mejor?

  2. ¿Puede a HashMap mantener diferentes tipos de objetos/tipos de datos como valores? Por ejemplo, sería este trabajo y estar bien:

    map.put("one", 1); 
    map.put("two", {1, 2}); 
    map.put("three", "hello"); 
    

    En la primera put(), quiero una int como un valor, en el segundo una int[], y la tercera una cadena. ¿Esto está bien que hacer en Java con HashMap s? Además, ¿está bien almacenar un HashMap como un valor dentro de un HashMap?

Respuesta

91

Realmente depende del tipo de seguridad que necesita.La forma no genérica de hacerlo es mejor hacerlo como:

Map x = new HashMap(); 

Tenga en cuenta que x se escribe como una Map. esto hace que sea mucho más fácil cambiar las implementaciones (a TreeMap o LinkedHashMap) en el futuro.

Puede utilizar genéricos para garantizar un cierto nivel de seguridad de tipos:

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

En Java 7 y más tarde se puede hacer

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

Lo anterior, mientras que más detallado, evita las advertencias del compilador. En este caso, el contenido de HashMap puede ser cualquier Object, de modo que puede ser Integer, int[], etc., que es lo que está haciendo.

Si usted todavía está utilizando Java 6, Guava Libraries (aunque es bastante fácil de hacer usted mismo) tiene un método llamado newHashMap() que evita la necesidad de duplicar la información de tipificación genérica cuando se hace una new. Se deduce el tipo de la declaración de variable (esta es una característica de Java no disponible en los constructores antes de Java 7).

Por cierto, cuando agrega una primitiva u otra primitiva, Java la está autocaptulando. Eso significa que el código es equivalente a:

x.put("one", Integer.valueOf(1)); 

Por supuesto que puede poner un HashMap como un valor en otro HashMap, pero creo que hay problemas si lo hace de forma recursiva (que es poner el HashMap como un valor en sí mismo).

+0

¿cuál es la diferencia entre hacer un HashMap map = new ... y Map map = new ...? ¿O hacen lo mismo? – sepiroth

+3

Hacen lo mismo, es solo que su referencia se escribe como un Mapa (la interfaz) en lugar de HashMap (la implementación) para que la implementación se pueda cambiar fácilmente sin afectar a más de una línea de código. – Yishai

4

Eclipse recomienda que declare el tipo de HashMap porque eso impone cierto tipo de seguridad. Por supuesto, parece que estás tratando de evitar la seguridad de tipo de tu segunda parte.

Si desea hacer esto último, intente declarar el mapa como HashMap<String,Object>.

+0

es un int considera una objeto..? – sepiroth

+0

"int" s no son objetos, es un tipo primitivo. Todas las primitivas (int, double, long, short ...) tienen una versión de objeto que puede usar (Integer, Double, Long, Short). Java 1.5+ incluso hará la conversión entre int e Integer por usted para que no tenga que preocuparse por ello (la mayoría de las veces, busque "autoboxing"). – MBCook

+0

autoboxing convertirá int [] en un objeto. –

1

Un HashMap puede contener cualquier objeto como un valor, incluso si se trata de otro HashMap. Eclipse sugiere que declare los tipos porque esa es la práctica recomendada para las Colecciones. en Java 5. Puede ignorar las sugerencias de Eclipse.

En Java 5, un int (o cualquier tipo primitivo) será autoboxed en un Entero (u otro tipo correspondiente) cuando lo agregue a una colección. Tenga cuidado con esto, sin embargo, ya que hay algunas capturas de usar el autoboxing.

12

Esto es un cambio realizado con Java 1.5. Lo que enumeras primero es el viejo, el segundo es el nuevo camino.

Mediante el uso de HashMap que puede hacer cosas como:

HashMap<String, Doohickey> ourMap = new HashMap<String, Doohickey>(); 

.... 

Doohickey result = ourMap.get("bob"); 

Si no tiene los tipos en el mapa, que tendría que hacer esto:

Doohickey result = (Doohickey) ourMap.get("bob"); 

es realmente muy útil. Te ayuda a detectar errores y evitar escribir todo tipo de lanzamientos extra. Fue una de mis características favoritas de 1.5 (y más reciente).

Todavía puede poner varias cosas en el mapa, simplemente especifíquelas como Mapa, luego puede poner cualquier objeto (una Cadena, otro Mapa e Integer, y tres MyObjects si así lo desea).

+2

Me has tenido hasta el último párrafo. "las listas con poco 'l'" se llaman matrices; y definitivamente son objetos en Java. – ChssPly76

+0

Usted menciona que para poner varias cosas en el mapa, solo debo especificarlo como un Mapa. ¿Por qué no podría usar HashMap? – sepiroth

+0

@ ChssPly76: "matrices". Ese es el término. No podía recordarlo e hice mi mejor intento por el momento. Gracias. – MBCook

0

En respuesta a su segunda pregunta: Sí, un HashMap puede contener diferentes tipos de objetos. Si esa es una buena idea o no, depende del problema que intentas resolver.

Dicho esto, su ejemplo no funcionará. El valor int no es un Objeto. Usted tiene que utilizar la clase Entero envoltura para almacenar un valor entero en un HashMap

+0

En Java 5+, el compilador hará eso por usted. – Yishai

+0

Funcionará en Java 5, que está utilizando ya que recibe advertencias sobre no haber parametrizado el mapa, con autoboxing. – ColinD

3

La forma en que está escrito es equivalente a

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

Lo que va dentro de los corchetes es que comunica al compilador lo que Colocaremos el HashMap para que pueda hacer una comprobación de errores por usted. Si Object, Object es lo que realmente quiere (probablemente no), debe declararlo explícitamente. En general, debe ser tan explícito como sea posible con la declaración para facilitar la comprobación de errores por parte del compilador. Lo que usted ha descrito, probablemente, debe ser declarada como esto:

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

De esa manera, al menos, declara que sus claves van a ser cadenas, pero sus valores pueden ser cualquier cosa. Solo recuerde usar un yeso cuando recupere un valor.

2

El segundo es el uso de genéricos que entró con Java 1.5. Reducirá la cantidad de conversiones en su código. & puede ayudarlo a detectar errores en tiempo de compilación en lugar de en tiempo de ejecución. Dicho eso, depende de lo que estás codificando. Un rápido & mapa sucio para contener algunos objetos de varios tipos no necesita genéricos. Pero si el mapa contiene objetos que descienden de un tipo distinto de Object, puede valer la pena.

El póster anterior es incorrecto sobre la matriz en un mapa. Una matriz es en realidad un objeto, por lo que es un valor válido.

Map<String,Object> map = new HashMap<String,Object>(); 
map.put("one",1); // autoboxed to an object 
map.put("two", new int[]{1,2}); // array of ints is an object 
map.put("three","hello"); // string is an object 

Además, como HashMap es un objeto, también puede ser un valor en un HashMap.

+0

, pero ¿cómo obtengo todos los valores que tengo en HashMap ????? – Ads

1

Eclipse sugiere que defina generic type para que pueda tener type safety. Puede escribir

Map m = new HashMap(); 

que no garantiza la seguridad de tipos, pero después va a garantizar la seguridad de tipos

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

El Object puede ser de cualquier tipo, tales como String, etc. Integer