Map.Entry:如何使用?
Posted
技术标签:
【中文标题】Map.Entry:如何使用?【英文标题】:Map.Entry: How to use it? 【发布时间】:2012-01-31 03:53:25 【问题描述】:我正在开发一个计算器。
我将按钮放在HashMap
集合中,当我想将它们添加到扩展JPanel
的类中时,我不知道如何从我的集合中获取按钮。
所以我在网上找到了我代码的最后两行,但我不知道它们的含义。
这是我的代码:
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
——这是一个接口——而不重新定义Map.Entry
的功能。
【问题讨论】:
***.com/questions/1066589/… 【参考方案1】:public HashMap<Integer,Obj> ListeObj= new HashMap<>();
public void addObj(String param1, String param2, String param3)
Obj newObj = new Obj(param1, param2, param3);
this.ListObj.put(newObj.getId(), newObj);
public ArrayList<Integer> searchdObj (int idObj)
ArrayList<Integer> returnList = new ArrayList<>();
for (java.util.Map.Entry<Integer, Obj> e : this.ListObj.entrySet())
if(e.getValue().getName().equals(idObj))
returnList.add(e.getKey());
return returnList;
【讨论】:
【参考方案2】:请注意,您还可以使用 Map.Entry 作为主要类型,使用其基本实现 AbstractMap.SimpleEntry 创建自己的结构。例如,如果你想要一个有序的条目列表,你可以这样写:
List<Map.Entry<String, Integer>> entries = new ArrayList<>();
entries.add(new AbstractMap.SimpleEntry<String, Integer>(myStringValue, myIntValue));
等等。从那里,你有一个元组列表。当您需要有序元组并且基本 Map 不可行时非常有用。
【讨论】:
【参考方案3】: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);
如果不清楚,请告诉我,我会修改答案。
【讨论】:
谢谢 :) 但我不明白的是,我们如何才能拥有一个类型为接口类型的变量?通常我们实现接口并重新定义其所有功能,我们无法创建具有接口类型的对象..对吗? 如果方法返回实现interface
的对象集合,则无需担心底层对象是什么。在这种特殊情况下,实现接口Map.Entry
的对象是您正在使用的任何Map
实现中的内部类(在这种情况下,它内置在HashMap
中)。你只需要知道对象满足接口指定的契约,你就可以调用接口指定的方法。
我想知道的是:您将如何在这里使用 Map.Entry 而不必一遍又一遍地重新输入String, JButton
?省略参数会从我尝试过的所有编译器中生成疯狂的警告,即使它们应该能够通过检查 listbouton
的类型推断出 entrySet()
的返回类型。
@LearNer,你是对的。每个条目都是对listbouton
持有的条目的引用,因此对条目的更改将反映在映射中。但是,不应在此循环中从地图中删除项目。在迭代集合时从集合中删除对象的正确方法是使用Iterator
并调用remove
方法。
@LearNer,如果您想在遍历条目集时删除Entry
,您需要使用Iterator
:Iterator<Map.Entry<String, Object>> myIter = myMap.entrySet().iterator(); while (myIter.hasNext()) Map.Entry<String, Object> myEntry = iter.next(); if (delete condition is true) iter.remove();
【参考方案4】:
Map.Entry 接口帮助我们迭代 Map 类
检查这个简单的例子:
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());
【讨论】:
【参考方案5】:这段代码最好改写为:
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
还是其他东西),如果您同时需要地图的键和值,那么枚举条目就是这将比枚举键更有效,然后为每个键再次调用映射以查找相应的值。
【讨论】:
【参考方案6】:Hash-Map 将(键,值)对存储为 Map.Entry 类型。如您所知,Hash-Map 使用 Linked Hash-Map(以防发生冲突)。因此 Hash-Map Bucket 中的每个 Node 都是 Map.Entry 类型。因此,每当您遍历 Hash-Map 时,您都会得到 Map.Entry 类型的节点。
现在在您的示例中,当您遍历 Hash-Map 时,您将获得 Map.Entry 类型(即接口),要从此 Map.Entry 节点对象获取键和值,接口提供了 getValue( )、getKey() 等。因此,根据代码,在您的对象中添加所有运算符 JButton,即(+、-、/、*、=)。
【讨论】:
【参考方案7】:Map 是 Key + Value 对的集合,可视化如下:
[fooKey=fooValue],barKey=barValue],[quxKey=quxValue]
Map 接口允许访问此集合的几个选项:Key 集 [fooKey, barKey,quxKey]
、Value 集 [fooValue, barValue, quxValue]
,最后是条目集 [fooKey=fooValue],barKey=barValue],[quxKey=quxValue]
。
Entry set 只是为了方便遍历 map 中的键值对,Map.Entry 是每个键值对的表示。执行最后一个循环的等效方法是:
for (String buttonKey: listbouton.keySet())
this.add(listbouton.get(buttonKey)) ;
或
for (JButton button: listbouton.values())
this.add(button) ;
【讨论】:
listbouton
是 Map
- 您不能直接遍历键,您必须遍历 listbouton.keySet
。【参考方案8】:
Map 由键/值对组成。例如,在您的代码中,一个键是“Add”,关联的值是 JButton("+")。 Map.Entry 是 Map 中包含的单个键/值对。最常用的两种方法是getKey() and getValue()
。您的代码将 所有 对放入一个 Set:
Set entrys = listbouton.entrySet() ;
并遍历它们。现在,它只使用 me.getValue()
查看 value 部分并将它们添加到您的 PanneauCalcul
this.add((Component) me.getValue()) ; //don't understand
如果您需要同时查看 键和值,这种类型的循环(通过 Map.Entry)通常是有意义的。但是,在您的情况下,您没有使用键,因此更简单的版本是获取地图中的所有 值 并添加它们。例如
for (JButton jb:listbouton.values())
this.add(jb);
最后的评论。 HashMap 中的迭代顺序是非常随机的。因此,这些按钮将以半随机顺序添加到您的 PanneauCalcul 中。如果你想保留按钮的顺序,你应该使用 LinkedHashMap。
【讨论】:
以上是关于Map.Entry:如何使用?的主要内容,如果未能解决你的问题,请参考以下文章