首页 > 编程知识 正文

集合概念和普遍概念的区别,java中的map集合详解

时间:2023-05-05 09:23:33 阅读:32659 作者:1086

Java的Map收藏1. Map集合的特点

映射是无序的键-值对集合,键不能重复。 值可以重复。 当键重复时,后者涵盖前者。 Map集合没有继承Collection接口

无序:无序是指插入的数据,读取时不按顺序输出

2. Map集合的扩容方式

初始容量16、负载因子0.75、容量增加量1倍

Map集合的最底层是数组

数组的初始容量为16

长度达到排列负荷因子0.75的长度时(16*0.75=12即12的长度时) ) ) ) ) ) ) ) ) )。

在一次容量扩展中,容量是原始容量的两倍

当知道所需容量的大小时

可以指定初始容量和负载率的大小

//例MapInteger,string map=new hashmap (16,0.75 f );4. Map的几种遍历方式

通过JDK1.8新特性//方法1示例map.foreach((k,v )-system.out.println ) key='k'value='v );通过KeySet方法拿到所有键,再遍历用所有键拿到对应的所有值//方法2示例SetInteger keySet=map.keySet (; for(integerinteger:keyset ) system.out.println ) ' value:'map.get ) integer ); } 通过迭代器//方法3示例iteratorintegeriterator=map.keyset (.iterator ); while(iterator.hasnext () ) {int inext=iterator.next; system.out.println (' key : ' inext ' value : ' map.get ) inext ); } 通过entrySet取出保存所有Entry的Set,再遍历此Set即可//方法4示例SetEntryInteger,String entrySet=map.entrySet (; for (输入整数,字符串输入: entryset ) system.out.println(key: )输入.获取) value: )输入打印

5. Map集合的实现

1、线程安全是指多个线程在执行同一du代码时采用锁定机制,确保每次zhi行的执行结果和单线程的执行结果与dao相同,程序运行时不会发生意外结果。

2、线程安全性低意味着未提供锁定机制保护,多个线程前后更改数据的结果是所得数据可能是脏数据。 在内部使用数组存储数据

线程不安全,最常用,速度快

hashMap的基础是由数组和链表组合构成的数据结构

数组中的任何位置都包含Key-Value的实例(节点),在java7中称为Entry,在java8中称为Node

数组中的所有位置最初都是空的,为空。 为什么长度也是空的,是因为HashMap有初始容量。 (在put中插入数据时,根据key的散列计算索引值。 也就是说,它被放置在指定的数组位置

例如,假设在HashMap中插入了一个名为put (“斯科农”,在1024中插入了斯科农的元素)。 此时,计算用散列函数插入的位置。 如果索引为2,则为:

链表在HashMap中起着什么作用呢?

我们在计算散列值时有一定的概念会得到相同的索引值。 此时,会生成链表。 例如,我们用put和put农码得到的结果都是2

HashMap Node插入链表1.8之前和1.8之后的不同java8之前用“头插法”从上到下

简单来说,新值将被当前值替换,原始值将被推入链表中。 如果用于多线程,则链表将是死循环

java8之后用“尾插法”从下往上走

避免了环链表的产生

这是网上大人物整理的put资料

HashMap put方法执行过程的基本原理1. HashMap

线程安全,很少使用,并行性能慢

HashTable很少使用的原因是基本代码部分函数使用了相同的对象锁

由于某些函数使用同一对象锁,因此在使用某个函数时,被该对象锁锁定的其他函数在该人停止使用之前不可用

3. HashTable

线程安全,写入时

复制的方式

在写入数据的时候写把原集合复制一份在复制的集合上进行操作,然后再赋值给原集合,这样假如在写入数据的时候正好有用户在进行读取数据用户就是读取的原集合,当新集合写入好了再给用户读取

ConcurrentHashMapJDK1.7跟JDK1.8的区别
1.7采取的方式是分段锁

HashTable采取的是synchronized
在有一个人使用同一个synchronized加锁的方法时,会把这个方法独占起来,其他人都不能使用
好比一个仓库,这个人进去就直接把大门锁了起来
如果其他人想要进入房间的话,就必须等已经进去的那个人出来,这样就会导致大门口外面等了很多人,性能就会很慢

而ConcurrentHashMap1.7采取的是分段锁
把一个大仓库分成很多个小房间每个房间都有一把锁,用户a进去a房间,就把a房间锁起来,其他房间别人一样能进去
大大的提高运行效率

1.8采取的是CAS+synchronized实现

CAS:Compare and Swap,先比较再交换。
CAS是一种无锁算法,CAS有3个操作数,内存值V,旧的预期值A,要修改的新值B。并且仅当预期值A和内存值V相同时,将内存值V修改为B,否则什么都不做。

1.7中发生hash碰撞采用链表存储
1.8中先使用链表存储,后面满足条件后(链表长度超过8的时候)会转换为红黑树来优化查询;

适合于读多,写少的场景

写时复制出一个新的数组,完成插入,修改,或者移除操作后将新数组赋值给array

比HashTable性能高

因为保证安全的方式是写时复制,而不是用对象锁加锁函数

达成最终一致性

使用方式与HashMap类似

5. TreeMap
Key值可以通过Comparator指定按一定的顺序排序,在没有指定排序方式时按自然排序排序,如果key的类型是String则按照ASCII码从小到大排序

//Comparator示例Map<Integer, String> treemap = new TreeMap<>(new Comparator<Integer>() {@Overridepublic int compare(Integer o1, Integer o2) {// TODO Auto-generated method stubreturn -(o1-o2);}});

使用Lambda表达式跟Comparator进行排序

//使用Lambda表达式跟Comparator进行排序Map<Integer, String> treemap = new TreeMap<>((Integer o1, Integer o2) -> -(o1-o2));

int compare(Object o1, Object o2) 返回一个基本类型的整型
如果要按照升序排序,
则o1 小于o2,返回-1(负数),相等返回0,01大于02返回1(正数)
如果要按照降序排序
则o1 小于o2,返回1(正数),相等返回0,01大于02返回-1(负数)

因为需要维护内部的红黑树,用于保证key值的顺序,所以添加或获取元素时性能较HashMap慢
6. LinkedHashMap
继承于HashMap
LinkedHashMap是有序的,且默认为插入顺序,当我们希望有顺序地去存储key-value时,就需要使用LinkedHashMap了

//代码示例 Map<String, String> linkedHashMap = new LinkedHashMap<>(); linkedHashMap.put("name1", "josan1"); linkedHashMap.put("name2", "josan2"); linkedHashMap.put("name3", "josan3"); Set<Entry<String, String>> set = linkedHashMap.entrySet(); Iterator<Entry<String, String>> iterator = set.iterator(); while(iterator.hasNext()) { Entry entry = iterator.next(); String key = (String) entry.getKey(); String value = (String) entry.getValue(); System.out.println("key:" + key + ",value:" + value); }

版权声明:该文观点仅代表作者本人。处理文章:请发送邮件至 三1五14八八95#扣扣.com 举报,一经查实,本站将立刻删除。