Map.Entry: как его использовать?
Я работаю над созданием калькулятора. Я помещаю свои кнопки в коллекцию HashMap
и когда я хочу добавить их в свой класс, который расширяет JPanel
, я не знаю, как мне получить кнопки из моей коллекции. Итак, я нашел в интернете 2 последние строки моего кода, но я не знаю их значения.
Вот мой код:
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) ;
}
}
Я не понимаю, как мы можем использовать Map.Entry
--which - интерфейс - без переопределения функций Map.Entry
.
Ответы
Ответ 1
Map.Entry
- это ключ и его значение, объединенное в один класс. Это позволяет вам перебирать Map.entrySet()
вместо того, чтобы перебирать значение Map.keySet()
, а затем получать значение для каждой клавиши. Лучший способ написать то, что у вас есть:
for (Map.Entry<String, JButton> entry : listbouton.entrySet())
{
String key = entry.getKey();
JButton value = entry.getValue();
this.add(value);
}
Если бы это было неясно, дайте мне знать, и я поправлю свой ответ.
Ответ 2
Этот код лучше переписать как:
for( Map.Entry me : entrys.entrySet() )
{
this.add( (Component) me.getValue() );
}
и это эквивалентно:
for( Component comp : entrys.getValues() )
{
this.add( comp );
}
Когда вы перечисляете записи карты, итерация дает серию объектов, реализующих интерфейс Map.Entry
. Каждый из этих объектов содержит ключ и значение.
Предполагается, что будет немного более эффективно перечислять записи карты, чем перечислять ее значения, но этот фактоид предполагает, что ваш Map
является HashMap
, а также предполагает знание внутренней работы (подробности реализации ) класса HashMap
. То, что можно сказать с большей определенностью, заключается в том, что независимо от того, как ваша карта реализована (будь то HashMap
или что-то еще), если вам нужен как ключ, так и значение карты, то перечисление записей будет более эффективным, чем перечисление ключей, а затем для каждого ключа, снова вызывающего карту, чтобы найти соответствующее значение.
Ответ 3
Карта представляет собой набор пар "ключ + значение", который визуализируется следующим образом:
{[fooKey=fooValue],barKey=barValue],[quxKey=quxValue]}
Интерфейс карты позволяет несколько вариантов доступа к этой коллекции: Набор клавиш [fooKey, barKey,quxKey]
, значение [fooValue, barValue, quxValue]
и окончательный ввод Set [fooKey=fooValue],barKey=barValue],[quxKey=quxValue]
.
Набор записей - просто удобство для итерации по парам значений ключей на карте, Map.Entry - это представление каждой пары значений ключа. Аналогичный способ сделать ваш последний цикл:
for (String buttonKey: listbouton.keySet()) {
this.add(listbouton.get(buttonKey)) ;
}
или
for (JButton button: listbouton.values()) {
this.add(button) ;
}
Ответ 4
Карта состоит из пар ключ/значение. Например, в вашем коде один ключ - "Добавить", а связанное значение - JButton ( "+" ). Map.Entry - это одна пара ключей/значений, содержащаяся в Map. Это два наиболее используемых метода: getKey() and getValue()
. Ваш код получает все пары в Set:
Set entrys = listbouton.entrySet() ;
и итерации по ним. Теперь он смотрит только на часть значения с помощью me.getValue()
и добавляет их в ваш PanneauCalcul
this.add((Component) me.getValue()) ; //don't understand
Часто этот тип цикла (над Map.Entry) имеет смысл, если вам нужно посмотреть как на ключ, так и на значение. Однако в вашем случае вы не используете ключи, поэтому гораздо более простая версия - просто получить все значения на вашей карте и добавить их. например.
for (JButton jb:listbouton.values()) {
this.add(jb);
}
Последний комментарий. Порядок итераций в HashMap довольно случайный. Таким образом, кнопки будут добавлены в ваш PanneauCalcul в полуслучайном порядке. Если вы хотите сохранить порядок кнопок, вы должны использовать LinkedHashMap.
Ответ 5
Hash-Map хранит пару (ключ, значение) в качестве типа Map.Entry. Как вы знаете, Hash-Map использует Linked Hash-Map (в случае возникновения столкновений). Поэтому каждый Node в Bucket of Hash-Map имеет тип Map.Entry. Поэтому всякий раз, когда вы перебираете Hash-Map, вы получаете узлы типа Map.Entry.
Теперь в вашем примере, когда вы выполняете итерацию через Hash-Map, вы получите Map.Entry Type (который является интерфейсом), чтобы получить ключ и значение из этого Map.Entry Node Объект, интерфейс предоставил методы, такие как getValue(), getKey() и т.д. Так как в коде, в вашем объекте вы добавляете все операторы JButtons viz (+, -,/, *, =).
Ответ 6
Интерфейс Map.Entry помогает нам повторять класс карты
Проверьте этот простой пример:
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());
}
}
}
Ответ 7
Обратите внимание, что вы также можете создавать свои собственные структуры, используя Map.Entry в качестве основного типа, используя его базовую реализацию AbstractMap.SimpleEntry. Например, если вы хотите иметь упорядоченный список записей, вы можете написать:
List<Map.Entry<String, Integer>> entries = new ArrayList<>();
entries.add(new AbstractMap.SimpleEntry<String, Integer>(myStringValue, myIntValue));
И так далее. Оттуда у вас есть список кортежей. Очень полезно, когда вам нужны упорядоченные кортежи, а базовая карта не нужна.