Map集合

151 阅读4分钟

Map集合是什么

集合是java中用于存储数据的一种容器,Map集合以键值对的方式存储元素

  1. 特点:每一个节点对象中都包含一个键对象和一个值对象,储存顺序是无序的,键不能重复,值可以重复
  2. 结构:Map接口及其实现类 集合名称 = new Map的实现类<key值类型,value值类型>();
1,Map中的常用方法

1,添加方法

Map map = new HashMap<Integer,String>();
//添加元素
map.put(1,"第一个");//方法的返回值为null map修改为 {1=第一个}
//当你添加的键已经存在,将根据键修改原有的值
map.put(1,"第一个修改");//方法的返回值为"第一个" {1=第一个修改}
//修改时返回被修改的值,添加时返回null

2,删除方法

Map map = new HashMap<Integer,String>();
map.put(1,"第一个");//{1=第一个}
map.put(2,"第二个");//{1=第一个, 2=第二个}
//remove删除集合中键值相同的对象或者删除与给定键值对相同的对象 remove返回值为被删除的值
map.remove(1);//{2=第二个}
map.remove(2,"第二个");//{2=第二个}
map.remove(2,"第二个");//{}
Map map = new HashMap<Integer,String>();
map.put(1,"第一个");//{1=第一个}
map.put(2,"第二个");//{1=第一个, 2=第二个}
//clear删除集合中所有对象
map.clear();//{}

3,判断方法

Map map = new HashMap<Integer,String>();
map.put(1,"第一个");//{1=第一个}
map.put(2,"第二个");//{1=第一个, 2=第二个}
System.out.println(map.containsKey(1));//判断集合是否包含指定的键 true
System.out.println(map.containsValue("第二个"));//判断集合是否包含指定的值 true
System.out.println(map.isEmpty());//判断集合是否为空 false

4,获取方法

Map map = new HashMap<Integer,String>();
map.put(1,"第一个");//{1=第一个}
map.put(2,"第二个");//{1=第一个, 2=第二个}
map.entrySet();//获取entrySet集合 [1=第一个, 2=第二个]
map.get(1);//根据键获取值 "第一个"
map.keySet();//获取集合中所有键的集合 [1, 2]
map.values();//获取集合中所有值的集合 [第一个, 第二个]

//根据获取方法,可以使用增强for循环堆集合进行遍历
如:
for (Map.Entry entry:map.entrySet()) {
    System.out.println(entry.getKey()+"---"+entry.getValue());
}

5,获取长度

Map map = new HashMap<Integer,String>();
map.put(1,"第一个");//{1=第一个}
map.put(2,"第二个");//{1=第一个, 2=第二个}
//返回集合长度
map.size();//2
2,Map集合的实现类
一,TreeMap
  1. 底层结构:红黑树
  2. 特点:去重,无序,自动排序
  3. 排序根据key值,当key为自定义类时,需要实现Comparable接口,并重写compareTo方法,或者在创建TreeMap实例时传入一个Comparator接口实现匿名对象
  4. 增加一些针对于key值大小的方法:如
TreeMap map = new TreeMap<Integer,String>();
Integer i = 1;
map.put(1,"第一个");//{1=第一个}
map.put(2,"第二个");//{1=第一个, 2=第二个}
map.put(3,"第三个");//{1=第一个, 2=第二个, 3=第三个}
map.ceilingEntry(2);//2=第二个 返回键值大于或等于给定键值的键值对,没有返回null
map.ceilingKey(2);//2 返回键值大于或等于给定键值的键,没有返回null
//floorEntry()和floorKey()方法返回小于等于给定键的关联的键值对
map.firstEntry();//1=第一个 返回最小键相关联的键值对
map.firstKey();//1  返回最小键相关联的键
//lastEntry()和lastKey()返回最大键相关联的键值对或键

等...

二,HashMap
  1. 底层结构:哈希表(java1.7及以前为数组加链表,java1.8及以后为数组加链表加红黑树)
  2. 特点:去重,无序,查找快,修改也快
  3. 扩容:初始容量为16,负载因子是0.75,扩容增量1倍,当已用容量大于等于容量*负载因子后,Map集合就会开始扩容
  4. 注意:当数组扩容长度到64前,会尝试扩容数组长度,数组长度到达64后,链表的长度大于等于8后,会将链表转为红黑树结构,但是当元素小于等于6后,红黑树会变回链表结构
  5. 没有新添加方法

与HashTable的对比 相同点

  1. 底层结构都为哈希表
  2. 都实现了Cloneable(克隆),Serializable(可序列化),map(集合)接口 不相同点
  3. Hashtable 是不允许键或值为 null 的,HashMap 的键值则都可以为 null
  4. 实现方式不同:Hashtable 继承的是 Dictionary类,而 HashMap 继承的是 AbstractMap 类
  5. 初始化容量不同:HashMap 的初始容量为:16,Hashtable 初始容量为:11,两者的负载因子默认都是:0.75
  6. 扩容机制不同:当已用容量>总容量 * 负载因子时,HashMap 扩容规则为当前容量翻倍,Hashtable 扩容规则为当前容量翻倍 +1
  7. HashMap只支持Iterator遍历,而HashTable支持Iterator和Enumeration两种方式遍历
  8. Hashtable是同步(synchronized)的,适用于多线程环境,而hashmap不是同步的,适用于单线程环境。多个线程可以共享一个Hashtable;而如果没有正确的同步的话,多个线程是不能共享HashMap的

注意点

  1. 由于Hashtable是线程安全的也是synchronized,所以在单线程环境下它比HashMap要慢。如果你不需要同步,只需要单一线程,那么使用HashMap性能要好过Hashtable
  2. 但是在需要线程安全的情况下使用哈希表结构容器也不推荐使用Hashtable,可以使用ConcurrentHashMap以及Collections.synchronizedMap()来代替