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,您需要使用IteratorIterator&lt;Map.Entry&lt;String, Object&gt;&gt; myIter = myMap.entrySet().iterator(); while (myIter.hasNext()) Map.Entry&lt;String, Object&gt; 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 接口的对象。这些对象中的每一个都包含一个键和一个值。

枚举映射的条目应该比枚举其值更有效,但是这个事实假定您的MapHashMap,并且还假定了解内部工作原理(实现细节) 的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) ;

【讨论】:

listboutonMap - 您不能直接遍历键,您必须遍历 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:如何使用?的主要内容,如果未能解决你的问题,请参考以下文章

Java中如何遍历Map对象的4种方法

Map.Entry使用详解

Thymeleaf遍历Map

Java - 如何创建新条目(键、值)

java中Map.Entry的使用方法

java怎么获取map的key