Java中Map,List与Set的区别

首先,数组和集合的区别:

  • 数组是大小固定的
  • 集合可以存储和操作数目不固定的一组数据,集合只能存放引用类型的的数据,不能存放基本数据类型

特性

List

  • 允许重复
  • 有序
  • 继承自Connection

Set

  • 不允许重复
  • 无序
  • 继承自Connection

Map

  • 键值对
  • 区别与ListSet,既没有继承也没有实现Connection

场景

三者各自适用什么样的场景?

List

  • 使用索引对元素进行访问
    ArrayList适合快速查找,LinkedList适合增删元素
  • 对有序有需求

Set

  • 确保元素的唯一性
    常用的Set有:HashSetLinkedHashSetTreeSet。其中,TreeSet中的元素可以使用Comparator 或者 Comparable 进行排序;LinkedHashSet也按照元素的插入顺序对它们进行存储

Map

  • 希望以键值对的形式存在
    常用的Map有:HashMapLinkedHashSetTreeMap。其中HashMap是无序的,LinkedHashSet有序,TreeMap可通过Comparator 或者 Comparable 进行排序
    另外HashTable也可以实现键值对,并且相对于HashMap是线程安全的,但是由于JAVA5以上 ConcurrentHashMap是线程安全的,但现在已经基本被HashMap取代

怎么让HashMap同步?

  • synchronizeMap

    Map m = Collections.synchronizeMap(hashMap);

  • JAVA5以上 ConcurrentHashMapHashTable的替代 (即线程安全的)

关于List<Map<String, Object>>理解

首先map<String,Object>是定义了一个Map集合变量,然后list<map<String,Object>>是定义了一个List的集合变量,是map的一个集合;map是那个list的其中一个值。
List<Map<String,Object> list=new ArrayList<Map<String,Object>>;
Map<String,Object> map=new HashMap<String,Object>;
  
list.add(map);//map是list中的其中一个值。

List集合中的对象是一个Map对象,而这个Map对象的键是String类型,值是Object类型

1package com.test; 2 3import java.util.*; 4 5public class MyTest01 { 6public static void main(String[] args) { 7 8List<Map<String, Object>> listMaps = new ArrayList<Map<String, Object>>(); 9 10Map<String, Object> map1 = new HashMap<String, Object>(); 11map1.put("1", "a"); 12map1.put("2", "b"); 13map1.put("3", "c"); 14listMaps.add(map1); 15 16Map<String, Object> map2 = new HashMap<String, Object>(); 17map2.put("11", "aa"); 18map2.put("22", "bb"); 19map2.put("33", "cc"); 20listMaps.add(map2); 21 22for (Map<String, Object> map : listMaps) { 23for (String s : map.keySet()) { 24System.out.print(map.get(s) + " "); 25} 26} 27System.out.println(); 28System.out.println("========================"); 29for (int i = 0; i < listMaps.size(); i++) { 30Map<String, Object> map = listMaps.get(i); 31Iterator iterator = map.keySet().iterator(); 32while (iterator.hasNext()) { 33String string = (String) iterator.next(); 34System.out.println(map.get(string)); 35} 36} 37System.out.println("++++++++++++++++++++++++++++"); 38for (Map<String, Object> map : listMaps) { 39for (Map.Entry<String, Object> m : map.entrySet()) { 40System.out.print(m.getKey() + " "); 41System.out.println(m.getValue()); 42} 43} 44System.out.println("-----------------------------"); 45} 46}

List<Map<String, Object>>存放的对象问题

一、提出问题
代码一:

1import java.util.ArrayList; 2import java.util.HashMap; 3import java.util.List; 4import java.util.Map; 5 6public class Test { 7public static void main(String args[]) { 8List<Map<String, Object>> list = new ArrayList<Map<String,Object>>(); 9Map<String, Object> map = new HashMap<String, Object>(); 10for(int i=0;i<5;i++) { 11// Map<String, Object> map = new HashMap<String, Object>(); 12map.put("a", i); 13map.put("b", i); 14list.add(map); 15} 16System.out.println(list); 17} 18}

代码二:

1import java.util.ArrayList; 2import java.util.HashMap; 3import java.util.List; 4import java.util.Map; 5 6public class Test { 7public static void main(String args[]) { 8List<Map<String, Object>> list = new ArrayList<Map<String,Object>>(); 9// Map<String, Object> map = new HashMap<String, Object>(); 10for(int i=0;i<5;i++) { 11Map<String, Object> map = new HashMap<String, Object>(); 12map.put("a", i); 13map.put("b", i); 14list.add(map); 15} 16System.out.println(list); 17} 18} 19

二、给出答案
猜猜看代码一二运行的结果分别是啥?

没错,就是:

代码一:

[{a=4,b=4},{a=4,b=4},{a=4,b=4},{a=4,b=4},{a=4,b=4}]
代码二:

[{a=0,b=0},{a=1,b=1},{a=2,b=2},{a=3,b=3},{a=4,b=4}]
 

三、问题分析
代码一中,List<Map<String, Object>>里面存放的是map对象的地址,尽管循环了五次,但是每次的map对象对应的都是同一个地址,即listMap里面存放的是五个同样的map对象。 
代码二中,每次循环的时候都实例化一个新的map对象,这样list在执行add方法的时候,每次都是存的不一样的map对象。
 可以通过debug来观察list存放的map对象对应的id。如图:

代码一:

 

代码二:

 

四、总结
通过上面的分析,我们可以知道,以后需要创建不同的map对象的时候,需要在循环里面进行map的创建。

而不是在循环体外面,因为List<Map<String, Object>>指向的是map对象的地址。

本文同步分享在 博客"Amber-"(CNBlog)。
如有侵权,请联系 support@oschina.cn 删除。
本文参与“OSC源创计划”,欢迎正在阅读的你也加入,一起分享。

点赞
收藏

评论区

加载中...

相关推荐

MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1

文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s

Oracle 分组与拼接字符串同时使用

SELECTT.,ROWNUMIDFROM(SELECTT.EMPLID,T.NAME,T.BU,T.REALDEPART,T.FORMATDATE,SUM(T.S0)S0,MAX(UPDATETIME)CREATETIME,LISTAGG(TOCHAR(

MySQL部分从库上面因为大量的临时表tmp_table造成慢查询

背景描述Time:20190124T00:08:14.70572408:00User@Host:@Id:Schema:sentrymetaLast_errno:0Killed:0Query_time:0.315758Lock_

皕杰报表之UUID

​在我们用皕杰报表工具设计填报报表时,如何在新增行里自动增加id呢?能新增整数排序id吗?目前可以在新增行里自动增加id,但只能用uuid函数增加UUID编码,不能新增整数排序id。uuid函数说明:获取一个UUID,可以在填报表中用来创建数据ID语法:uuid()或uuid(sep)参数说明:sep布尔值,生成的uuid中是否包含分隔符'',缺省为

手写Java HashMap源码

HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程22

2020年前端实用代码段,为你的工作保驾护航

有空的时候,自己总结了几个代码段,在开发中也经常使用,谢谢。1、使用解构获取json数据let jsonData  id: 1,status: "OK",data: 'a', 'b';let  id, status, data: number   jsonData;console.log(id, status, number )