2011-12-31 24 views
33

Estoy trabajando en la creación de una calculadora .. Pongo mis botones en una Colección HashMap y cuando quiero agregarlos a mi Clase que extiende Jpanel, no sé cómo puedo obtener los botones de mi colección. Encontré en la red las 2 últimas líneas de mi código, pero no sé su significado.Map.Entry: cómo usarlo?

Aquí está mi código:

import java.awt.Component; 
import java.util.HashMap; 
import java.util.Iterator; 
import java.util.Map; 
import java.util.Set; 

import javax.swing.JButton; 
import javax.swing.JPanel; 


public class PanneauCalcul extends JPanel { 

    private HashMap<String, JButton> listbouton = new HashMap<String, JButton>() ; 

    public PanneauCalcul() { 
     for(int i = 0; i < 10; i ++) { 
      listbouton.put("num" + i, new JButton("" + i)) ; 
     } 

     listbouton.put("add", new JButton("+")) ; 
     listbouton.put("soustract", new JButton("-")) ; 
     listbouton.put("multiply", new JButton("x")) ; 
     listbouton.put("divise", new JButton("/")) ; 
     listbouton.put("equal", new JButton("=")) ; 

     Set entrys = listbouton.entrySet() ; 

     Iterator iter = entrys.iterator() ; 

     while(iter.hasNext()) { 
      Map.Entry me = (Map.Entry)iter.next(); //don't understand 
      this.add((Component) me.getValue()) ; //don't understand 
     } 

     EcouteCalcul ecout = new EcouteCalcul(this) ; 
    } 
} 

No entiendo cómo podemos utilizar Map.Entry -que es un interface- sin redefinir Map.Entry 's funciones.

+0

Cuál es el 'añadir)' método (? – fge

+1

http://stackoverflow.com/questions/1066589/java-iterate-through-hashmap –

Respuesta

69

Map.Entry es una clave y su valor combinados en una sola clase. Esto le permite iterar sobre Map.entrySet() en lugar de tener que iterar sobre Map.keySet(), y luego obtener el valor para cada tecla. Una mejor manera de escribir lo que tiene es:

for (Map.Entry<String, JButton> entry : listbouton.entrySet()) 
{ 
    String key = entry.getKey(); 
    JButton value = entry.getValue(); 

    this.add(value); 
} 

Si no está claro, hágamelo saber y corregiré mi respuesta.

+0

Gracias :) Pero lo que no entiendo es ¿cómo podemos tener una variable cuyo tipo es el de The Interface? Normalmente implementamos la interfaz y redefinimos todas sus funciones y no podemos crear un objeto con el tipo de interfaz. ¿Verdad? – Copernic

+4

Si un método devuelve una colección de objetos que implementan una 'interfaz', no necesita preocuparse por cuál es el objeto subyacente. En este caso particular, el objeto que implementa la interfaz 'Map.Entry' es una clase interna en cualquier implementación' Map' que esté utilizando (en este caso está integrada en 'HashMap'). Todo lo que necesita saber es que el objeto cumple con el contrato especificado por la interfaz y, por lo tanto, puede llamar a los métodos especificados por la interfaz. – Paul

+0

Lo que quiero saber es: ¿cómo usaría Map.Entry aquí sin tener que volver a escribir 'String, JButton' una y otra vez? Dejar los parámetros genera advertencias frenéticas de todos los compiladores que he intentado, aunque deberían poder deducir el tipo de retorno de 'entrySet()' al examinar el tipo de 'listbouton'. –

3

Este código es mejor volver a escribir como:

for(Map.Entry me : entrys.entrySet()) 
{ 
    this.add((Component) me.getValue()); 
} 

y es equivalente a:

for(Component comp : entrys.getValues()) 
{ 
    this.add(comp); 
} 

Al enumerar las entradas de un mapa, la iteración produce una serie de objetos que implementan la Map.Entry interfaz. Cada uno de estos objetos contiene una clave y un valor.

que se supone que ser un poco más eficiente para enumerar las entradas de un mapa de enumerar sus valores, pero esto factoide presume que su Map es una HashMap, y supone, además, el conocimiento de los mecanismos internos (los detalles de implementación) de la HashMap clase. Lo que se puede decir con un poco más de certeza es que no importa cómo se implemente su mapa (si es HashMap u otra cosa) si necesita tanto la clave como el valor del mapa, entonces enumerar las entradas va a ser más eficiente que enumerar las claves y luego para cada tecla invocar el mapa nuevamente para buscar el valor correspondiente.

2

Un mapa es un conjunto de pares clave + Valor, que se visualiza así:

{[fooKey=fooValue],barKey=barValue],[quxKey=quxValue]} 

la interfaz del mapa permite algunas opciones para acceder a esta colección: la tecla SET [fooKey, barKey,quxKey], el valor establecido [fooValue, barValue, quxValue] y finalmente la entrada Set [fooKey=fooValue],barKey=barValue],[quxKey=quxValue].

El conjunto de entrada es simplemente una conveniencia para iterar sobre los pares de valores clave en el mapa, Map.Entry es la representación de cada par de valores clave. Una forma equivalente a hacer su último bucle sería:

for (String buttonKey: listbouton.keySet()) { 
    this.add(listbouton.get(buttonKey)) ; 
} 

o

for (JButton button: listbouton.values()) { 
    this.add(button) ; 
} 
+0

'listbouton' es un' Mapa' - no puede iterar directamente sobre las claves, debe iterar sobre 'listbouton.keySet'. – Paul

2

Un mapa consta de pares clave/valor. Por ejemplo, en su código, una tecla es "Agregar" y el valor asociado es JButton ("+"). Un Map.Entry es un par clave/valor único contenido en el Mapa. Sus dos métodos más usados ​​son getKey() and getValue().Su código obtiene todos los pares en un conjunto:

Set entrys = listbouton.entrySet() ; 

e itera sobre ellos. Ahora bien, sólo se ve en la partevalor utilizando me.getValue() y los añade a su PanneauCalcul

this.add((Component) me.getValue()) ; //don't understand 

A menudo, este tipo de bucle (el Map.Entry) tiene sentido si se necesita mirar tanto la clave y el valor Sin embargo, en su caso, no está utilizando las claves, por lo que una versión mucho más simple sería obtener todos los valores en su mapa y agregarlos. p.ej.

for (JButton jb:listbouton.values()) { 
    this.add(jb); 
} 

Un último comentario. El orden de iteración en un HashMap es bastante aleatorio. Entonces los botones se agregarán a su PanneauCalcul en un orden semialeatorio. Si desea conservar el orden de los botones, debe usar un LinkedHashMap.

1

Hash-Map almacena el par (clave, valor) como el Tipo Map.Entry. Como usted sabe, Hash-Map usa Linked Hash-Map (En caso de que se produzca una colisión). Por lo tanto, cada Nodo en el Cubo de Hash-Map es de Tipo Map.Entry. Por lo tanto, cada vez que itere a través del Hash-Map obtendrá Nodos de Tipo Map.Entry.

Ahora en su ejemplo cuando está iterando a través del Hash-Map, obtendrá Map.Entry Type (Which is Interface), Para obtener la clave y el valor de este Map.Entry Node Object, la interfaz proporcionó métodos como getValue(), getKey() etc. Así que según el código, en su Objeto está agregando todos los operadores JButtons viz (+, -, /, *, =).

0

interfaz Map.Entry nos ayuda a la iteración de una clase Mapa

Comprobar este sencillo ejemplo:

public class MapDemo { 
    public static void main(String[] args) { 
    Map<Integer,String> map=new HashMap(); 
    map.put(1, "Kamran"); 
     map.put(2, "Ali"); 
     map.put(3, "From"); 
     map.put(4, "Dir"); 
     map.put(5, "Lower"); 
     for(Map.Entry m:map.entrySet()){ 
     System.out.println(m.getKey()+" "+m.getValue()); 
     } 
    } 
} 
Cuestiones relacionadas