Java中Map的使用

Java中Map的使用

大家好,又见面了,我是全栈君,祝每个程序员都可以多学几门语言。

Map以按键/数值对的形式存储数据,和数组很类似,在数组中存在的索引,它们本身也是对象。   

    Map的接口   

    Map---实现Map   

    Map.Entry--Map的内部类,描写叙述Map中的按键/数值对。   

    SortedMap—扩展Map,使按键保持升序排列   

    

    关于怎么使用,通常是选择Map的子类,而不直接用Map类。   

    以下以HashMap为例。   

    public     static     void     main(String     args[])   

    {   

        HashMap     hashmap     =     new     HashMap();   

        hashmap.put(“Item0”,     “Value0”);   

        hashmap.put(“Item1”,     “Value1”);   

        hashmap.put(“Item2”,     “Value2”);   

        hashmap.put(“Item3”,     “Value3”);   

        Set     set     =     hashmap.entrySet();   

        Iterator     iterator     =     set.iterator();   

        while     (iterator.hasNext()   

      {   

          Map.Entry     mapentry     =     (Map.Entry)     iterator.next();   

          System.out.println(mapentry.getkey()     +     “/”     +     mapentry.getValue());   

      }   

    }   

    注意,这里Map的按键必须是唯一的,比方说不能有两个按键都为null。   

    假设用过它,就会知道它的用处了。

又比方:

Map<String, Order> map = new HashMap<String, Order>();

            map.put(“Order”, (Order) obj);

资料:

Collection容器中包括Set和List接口,Set中又包括HashSet,List中包括LinkedList和ArrayList;单独的Map接口中仅仅有HashMap。

java.util 中的集合类包括 Java 中某些最经常使用的类。 最经常使用的集合类是 List 和 Map。 List 的详细实现包括 ArrayList 和 Vector,它们是可变大小的列表,比較适合构建、存储和操作不论什么类型对象的元素列表。 List 适用于按数值索引訪问元素的情形,当中的数据有顺序且能够反复。而Set中数据无顺序且不能够反复。

Map 提供了一个更通用的元素存储方法。 Map 集合类用于存储元素对(称作“键”和“值”),当中每一个键映射到一个值。 从概念上而言,您能够将 List 看作是具有数值键的 Map。 而实际上,除了 List 和 Map 都在定义 java.util 中外,两者并没有直接的联系。本文将着重介绍核心 Java 发行套件中附带的 Map,同一时候还将介绍怎样採用或实现更适用于您应用程序特定数据的专用 Map。

了解 Map 接口和方法

Java 核心类中有非常多提前定义的 Map 类。 在介绍详细实现之前,我们先介绍一下 Map 接口本身,以便了解全部实现的共同点。 Map 接口定义了四种类型的方法,每一个 Map 都包括这些方法。 以下,我们从两个普通的方法(表 1)開始对这些方法加以介绍。

表 1: 覆盖的方法。 我们将这 Object 的这两个方法覆盖,以正确比較 Map 对象的等价性。

equals(Object o) 比較指定对象与此 Map 的等价性
hashCode() 返回此 Map 的哈希码

 

Map 构建

Map 定义了几个用于插入和删除元素的变换方法(表 2)。

表 2: Map 更新方法: 能够更改 Map 内容。

clear() 从 Map 中删除全部映射
remove(Object key) 从 Map 中删除键和关联的值
put(Object key, Object value) 将指定值与指定键相关联
clear() 从 Map 中删除全部映射
putAll(Map t) 将指定 Map 中的全部映射拷贝到此 map

 

虽然您可能注意到,纵然如果忽略构建一个须要传递给 putAll() 的 Map 的开销,使用 putAll() 通常也并不比使用大量的 put() 调用更有效率,但 putAll() 的存在一点也不稀奇。 这是由于,putAll() 除了迭代 put() 所运行的将每一个键值对加入�到 Map 的算法以外,还须要迭代所传递的 Map 的元素。 但应注意,putAll() 在加入�全部元素之前能够正确调整 Map 的大小,因此如果您未亲自调整 Map 的大小(我们将对此进行简介),则 putAll() 可能比预期的更有效。

查看 Map

迭代 Map 中的元素不存在直接了当的方法。 假设要查询某个 Map 以了解其哪些元素满足特定查询,或假设要迭代其全部元素(不管原因怎样),则您首先须要获取该 Map 的“视图”。 有三种可能的视图(參见表 3

  • 全部键值对 — 參见 entrySet()
  • 全部键 — 參见 keySet()
  • 全部值 — 參见 values()

 

前两个视图均返回 Set 对象,第三个视图返回 Collection 对象。 就这两种情况而言,问题到这里并没有结束,这是由于您无法直接迭代 Collection 对象或 Set 对象。要进行迭代,您必须获得一个 Iterator 对象。 因此,要迭代 Map 的元素,必须进行比較烦琐的编码

 

Iterator keyValuePairs = aMap.entrySet().iterator();Iterator keys = aMap.keySet().iterator();Iterator values = aMap.values().iterator();

 

值 得注意的是,这些对象(Set、Collection 和 Iterator)实际上是基础 Map 的视图,而不是包括全部元素的副本。 这使它们的使用效率非常高。 还有一方面,Collection 或 Set 对象的 toArray() 方法却创建包括 Map 全部元素的数组对象,因此除了确实须要使用数组中元素的情形外,其效率并不高。

我执行了一个小測试(随附文件里的 Test1),该測试使用了 HashMap,并使用下面两种方法对迭代 Map 元素的开销进行了比較:

 

int mapsize = aMap.size();Iterator keyValuePairs1 = aMap.entrySet().iterator();for (int i = 0; i < mapsize; i++){    Map.Entry entry = (Map.Entry) keyValuePairs1.next();    Object key = entry.getKey();    Object value = entry.getValue();    ...}Object[] keyValuePairs2 = aMap.entrySet().toArray();for (int i = 0; i < rem; i++) {{    Map.Entry entry = (Map.Entry) keyValuePairs2[i];    Object key = entry.getKey();
  
  
Profilers in Oracle JDeveloper

 

Oracle JDeveloper 包括一个嵌入的监測器,它測量内存和运行时间,使您可以高速识别代码中的瓶颈。 我曾使用 Jdeveloper 的运行监測器监測 HashMap 的 containsKey() 和 containsValue() 方法,并不是常快发现 containsKey() 方法的速度比 containsValue() 方法慢非常多(实际上要慢几个数量级!)。 (參见图 1图 2,以及随附文件里的 Test2 类)。

   Object value = entry.getValue();   ...}

此 測试使用了两种測量方法: 一种是測量迭代元素的时间,还有一种測量使用 toArray 调用创建数组的其它开销。 第一种方法(忽略创建数组所需的时间)表明,使用已从 toArray 调用中创建的数组迭代元素的速度要比使用 Iterator 的速度大约快 30%-60%。 但假设将使用 toArray 方法创建数组的开销包括在内,则使用 Iterator 实际上要快 10%-20%。 因此,假设因为某种原因要创建一个集合元素的数组而非迭代这些元素,则应使用该数组迭代元素。 但假设您不须要此中间数组,则不要创建它,而是使用 Iterator 迭代元素。

 

表 3: 返回视图的 Map 方法: 使用这些方法返回的对象,您能够遍历 Map 的元素,还能够删除 Map 中的元素。

entrySet() 返回 Map 中所包括映射的 Set 视图。 Set 中的每一个元素都是一个 Map.Entry 对象,能够使用 getKey() 和 getValue() 方法(另一个 setValue() 方法)訪问后者的键元素和值元素
keySet() 返回 Map 中所包括键的 Set 视图。 删除 Set 中的元素还将删除 Map 中对应的映射(键和值)
values() 返回 map 中所包括值的 Collection 视图。 删除 Collection 中的元素还将删除 Map 中对应的映射(键和值)

 

訪问元素

表 4 中列出了 Map 訪问方法。Map 通常适合按键(而非按值)进行訪问。 Map 定义中没有规定这肯定是真的,但通常您能够期望这是真的。 比如,您能够期望 containsKey() 方法与 get() 方法一样快。 还有一方面,containsValue() 方法非常可能须要扫描 Map 中的值,因此它的速度可能比較慢。

表 4: Map 訪问和測试方法: 这些方法检索有关 Map 内容的信息但不更改 Map 内容。

get(Object key) 返回与指定键关联的值
containsKey(Object key) 假设 Map 包括指定键的映射,则返回 true
containsValue(Object value) 假设此 Map 将一个或多个键映射到指定值,则返回 true
isEmpty() 假设 Map 不包括键-值映射,则返回 true
size() 返回 Map 中的键-值映射的数目

 

对使用 containsKey() 和 containsValue() 遍历 HashMap 中全部元素所需时间的測试表明,containsValue() 所需的时间要长非常多。 实际上要长几个数量级! (參见图 1图 2,以及随附文件里的 Test2)。 因此,假设 containsValue() 是应用程序中的性能问题,它将非常快显现出来,并可以通过监測您的应用程序轻松地将其识别。 这样的情况下,我相信您可以想出一个有效的替换方法来实现 containsValue() 提供的等效功能。 但假设想不出办法,则一个可行的解决方式是再创建一个 Map,并将第一个 Map 的全部值作为键。 这样,第一个 Map 上的 containsValue() 将成为第二个 Map 上更有效的 containsKey()。

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/118588.html原文链接:https://javaforall.cn

【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛

【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...

(0)


相关推荐

  • OCX控件数字签名图文教程[通俗易懂]

    OCX控件数字签名图文教程[通俗易懂]这段时间做了一个B/S下套打的控件(过几天整理一下放到博客上来),控件测试完成,但是因为没有数字证书,IE如果不设置信任区域和等级的话,会直接被阻止下载安装(我不期望客户能熟练地改IE设置),但是数字证书价格昂贵,暂不考虑,看到cnblogs上一篇文章后深受启发,照着搞了一个测试用的数字签名,但是这篇文章上的OS貌似是win2000,IE5,我有必要在win7下给大家做个演示:首先,下载

  • qmake自定义函数「建议收藏」

    qmake自定义函数「建议收藏」使用qmake编写构建步骤时,如果较为复杂或重复的行为可以使用函数来实现。

  • WEBAPP开发技巧总结

    WEBAPP开发技巧总结自Iphone和Android这两个牛逼的手机操作系统发布以来,在互联网界从此就多了一个新的名词-WebApp(意为基于WEB形式的应用程序,运行在高端的移动终端设备)。开发者们都知道在高端智能手机系统中有两种应用程序:一种是基于本地(操作系统)运行的APP;一种是基于高端机的浏览器运行的WebApp,本文将主要讲解后者。WebApp与Native App有何区别呢?Nat

  • 复位信号 rst

    复位信号 rstaltera的触发器是低电平触发,所以建议使用rst_n,xilinx的触发器是高电平触发,所以建议使用rst,如果是rst_n,则会增加额外的非逻辑xilinx推荐:由于rst是一个高扇出网络,所以要尽量减少rst的使用,扇出太大会导致时序收敛困难。参考:https://blog.csdn.net/maowang1234588/article/details/103510605根据ff初始值和敏感信号列表中是否有rst(异步触…

  • JAVA的除法计算

    JAVA的除法计算我们都知道在JAVA中”/“是取整,”%”是取余,那么我们要是想算类似1÷10=0.1怎么算?方法一DecimalFormat //定义方法 publicstaticStringChufa(inta,intb){ //“0.00000000”确定精度 DecimalFormatdF=newDecimalFormat(“0.00000000”); …

发表回复

您的电子邮箱地址不会被公开。

关注全栈程序员社区公众号