当前位置: 首页 > news >正文

【Java】Map和Set

文章目录

  • 一.Map
    • 1.Map的说明
    • 2.Map.Entry<K,V>
    • 3.Map的常用接口
    • 4.HsahMap和TreeMap的对比
  • 二.Set
    • 1.Set的接口
    • 2.TreeSet和HashSet的对比
  • 三.Java中的哈希表
    • 1.HashMap的结构
    • 2.负载因子
    • 3.HashMap的put过程


image.png

一.Map

1.Map的说明

由图中可知,Map是一个接口类,且该类未继承自Collection,其存储的是键值对<k,v>结构。其中,k是唯一的,无法重复;

2.Map.Entry<K,V>

Map.Entry<K,V>是Map中的一个内部类,其主要用来存放<K,V>键值对并提供相应的访问方法

方法说明
K getKey()返回Entry中的key
V getValue()返回Entry中的value
V setValue(V value)将Entry中的value改为指定的value

注: Map.Entry<K,V>中并未提供能修改key的方法

3.Map的常用接口

Map虽然有两种实现类,但其接口是基本相同的;

方法说明
V put(K key,V value)将键值对<k,v>放入Map中,如果key已经存在,将原value替换为新的value;
V get(Object key)返回key对应的value
V remove(Object key)删除<key,value>键值对
boolean containsKey(Object key)判断key是否存在Map中
boolean containsValue(Object value)判断value是否在Map中
Set keySet()返回所有的key集合,作为Set返回
Set<Map.Entry<K,V>> entrySet()返回所有的<K,V>键值对,每个元素是Map.Entry<K,V>类型
Collection values()返回所有的可重复的values集合
V getOrDefault(Object k,V defaultV)返回key对应的value,如果key不存在,则返回默认值
// 1.创建空的Map
Map<String,Integer> e1=new TreeMap<>();   //使用TreeMap作为实现类
Map<String,Integer> e2=new HashMap<>();   //使用HashMap作为实现类// 2.插入键值对
e.put(key,value)// 3.移除键值对
e.remove(key);// 4.获取key对应的value
e.get(key);// 5.获取所有key的集合
Set<K> t=e.keySet();// 6.遍历Map
Set<Map.Entry<K,V>> s=e.entrySet();
for(Map.Entry<K,V>  tmp: s){K key=tmp.getKey();V value=tmp.getValue();//7.修改valuetmp.setValue(val);
}

注意点:

  • Map是一个接口,无法实例化对象,只能通过实例化实现类来进行实例化;
  • Map中的key和value全部可以分离出来单独访问,key是Set,value是Collection;
  • Map中的key是唯一的,value不唯一;

4.HsahMap和TreeMap的对比

TreeMapHashMap
底层结构红黑树哈希桶
增/删/查的时间复杂度O(logn)O(1)
是否线程安全线程不安全线程不安全
元素是否有序有序不有序
补充:

TreeMap的底层是红黑树,是搜索树,因此相关操作会涉及key的比较,因此TreeMap 的key不允许为null;
HashMap的底层是哈希桶,对于自定义类型,必须重写equals或者hashCode方法,其允许key的值为null;

二.Set

set继承自Collection接口类,其只存储了key;

1.Set的接口

方法说明
boolean add(E e)插入元素e,如果已经存在,则无法插入,返回false
boolean contains(Object o)判断元素o是否在Set中
boolean remove(Object o)删除Set中的元素o
int size()返回Set的元素个数
boolean isEmpty()判断Set是否为空
Object[] toArray()将Set的元素转为数组并返回
Iterator<E> iterator()返回迭代器
boolean addAll(Collection< ? extends E> c)将集合c添加到Set中,可以达到去重的效果
public static void main(String[] args) {Set<Integer> set=new TreeSet();//1.插入-addfor(int i=10;i>=0;i--){set.add(i);}//2.判断元素是否存在-containsSystem.out.println(set.contains(5));//3.移除元素-removeSystem.out.println(set.remove(10));//4.获取迭代器-iteratorIterator<Integer> it=set.iterator();while(it.hasNext()) {System.out.print(it.next() + " ");}//5.去重-addAllSet<String> s=new TreeSet();s.addAll(new ArrayList<>(Arrays.asList("a","d","c","a")));System.out.println(s);
}

Set的注意事项:

  1. Set是一个接口,其无法实例化出对象,必须使用HashSet或者TreeSet或者LinkedHashSet来进实现该接口
  2. Set的最大功能是对集合中的元素进行去重
  3. Set的底层是Map实现的
  4. TreeSet中不能插入null作为key,但HashSet可以,这与底层实现有关;
  5. TreeSet和HashSet的对比与前文Map的基本一致;

2.TreeSet和HashSet的对比

TreeSetHashSet
底层结构红黑树哈希桶
是否有序有序不一定
是否线程安全不安全不安全

三.Java中的哈希表

1.HashMap的结构

Java中解决哈希冲突的方法是开散列法(链地址法)/哈希桶;故HashMap的数据结构由数组和链表组成,数组中存放的是一个个链表(哈希桶),当发生冲突时,将元素尾插到对应桶中;
image.png

2.负载因子

负载因子= 表中元素个数/表的长度;HashMap的默认负载因子为0.75;当表中元素个数超过容量的75%时,就需要进行扩容
负载因子太低会造成空间浪费,负载因子太高会造成频繁冲突,因此默认值0.75很好的维持了这个平衡;

3.HashMap的put过程

前面说过,HashMap的无参构造并未对容量进行设置,因此可以猜到put极有可能对容量进行了设置;

部分成员:
6044a33b4bc1d846ad79e58d0a0aa708.png

put过程源码:
9f476e148bcb6adfa4587b06509f6ddf.png

put的过程:

  1. 首先,put方法会调用putVal方法
  2. 如果是第一次put,会调用reSize方法,将数组的大小改为默认值16
  3. 通过(n-1)&hash拿到key需要被映射的位置
  4. 如果该位置为null,则直接进行覆盖,如果非null,则进行尾插法;
  5. 尾插过程中,记录元素个数,如果元素个数>=8,则会调用treeify方法
  6. 如果8<=binCount<64,则直接进行扩容,如果binCount>=64,则将链表构造成红黑树,并插入键值对
  7. 插入完,判断是否需要reSize,如不需要,结束;

注意点:
1.扩容时需要注意什么?

将原哈希表中的每个元素均进行重新映射(重新哈希); 因为键值对的index是基于oldLength的,而扩容后,length变了,因此键值对的index理应按照新的length来映射;

2.构造的时候如果给了容量,且容量非二次幂数,怎么办?

如果构造时,给定的容量不等于二次幂,则Java会在构造方法中通过tableSizeFor返回一个接近输入的二次幂数作为initcapacity;

3.equals和hashCode的区别?

Java中,计算哈希值实际是通过hashCode方法,进行key比较时是通过equals方法;
在比较元素时,时间先比较hashCode值是否相等,如果相等,则再用equals进行比较;
因此,equals相等的对象,hashCode也一致,hashCode相等的对象,equals不一定一致

4.HashSet的底层是HashMap;

http://www.dtcms.com/a/400906.html

相关文章:

  • 中国建设银行绑定网站网络改造实施方案
  • 做网站要钱吗搭建平台舞台
  • 海东地网站建设wordpress免费相册插件
  • 搭建公司网站教程南京制作网页培训班
  • 北京赛车网站开发网站建设柚子网络科技官网
  • 做的网站图片模糊帮忙推广的平台
  • 做网站交互demo工具濮阳房产网官网
  • 做淘宝货源网站没有网站可以做seo
  • 用服务器做网站空间再高权重网站加自己的链接会容易被收录吗
  • 网站推广平台有哪些wordpress 获取page
  • 网站开发工程师岗位描述老专家个人网站
  • 微信网站开发登录兰州网络推广技术
  • 源代码代做网站wordpress不同分类不同模板 插件
  • 上海做电缆桥架的公司网站joomla 做的网站
  • 东营网站建设推广足彩网站建设
  • 网站建设价值188旅游网站管理系统6.0模板
  • 从城内快递到国际物流:深入浅出BGP协议基本原理
  • 乌镇网站开发文档建设工程职称 在哪个网站
  • 榆林网站建设网站开发的对联
  • wordpress全站注明wordpress 主题添加小工具
  • 做网站做国外广告网站维护 一年
  • 06627网页制作与网站建设北京十大装饰装修公司
  • 企业网站建设一般包含哪些内容app怎么制作视频
  • 做歌厅广告在哪个网站做好门户网站采用较多的模式是
  • 怎么开通网站广西桂林特产
  • 企业手机网站制作新民网站建设价格咨询
  • 南京电商网站建设商业计划书模板范文
  • 太原网站设计公司沈阳自助模板建站
  • 网站运营周期我要自学网官网
  • 小程序代码做网站经营网站 备案查询