【JAVA数据结构】哈希表-HashSet and HashMap(二)

简介: JAVA数据结构 & 哈希表 -HashSet and HashMap

5. 集合类的基本用途与使用

5.1 实例化Map

一般用普通类实例化接口的形式,这样这个引用的功能更加具有针对性。


接下来来看看Map的一些基本功能(高亮即重点)


方法 解释

V get(Object key) 返回key对应的value值

V getOrDefault(Object key, V defaultValue) 返回对应value,不存在则返回defaultValue

V put(K key, V value) 放置键值对(key重复则覆盖)

V remove(Object key) 根据唯一的key删除键值对

Set keySet() key不重复,将所有key值放在Set里并返回

Collection values() 将所有values放在集合中并返回

Set<Map.Entry<K, V>> entrySet() 返回所有键值对集(entry即条目)

boolean containsKey(Object key) 是否存在key值

boolean containsValue(Object value) 是否存在value值

其中还有一个特别重要的静态内部接口,Entry


这里我们可以理解为,将key和value打包起来了,成为一个独立的引用,其实里面


方法 解释

K getKey()  获取键值对的key值
V getValue()  获取键值对的value值
V setValue(V value) 设置键值对的value值
Set<Map.Entry<Integer, Integer>> set = hashMap.entrySet();
Map.Entry<Integer, Integer>[] entry = (Map.Entry<Integer, Integer>[]) set.toArray();//把map的 key 和 value 组装成一个整体
entry[0].getKey();
entry[0].getValue();
entry[0].setValue();


无法设置key,转化为Set有什么用,等一下将Set的时候细说!


接下来解答一些疑惑,就是为什么返回类型是接口/抽象类型,但是仍然可以正常使用?


原因就是,重写方法的规矩除了完全相等以外,还有一个例外

就是,返回类型呈现继承/实现关系,【父亲方法的返回类型】被【子类方法的返回类型】继承或者实现,也是重写!

这样,返回类型就可以是普通类啦,并且哈希实现就是哈希,树实现就是树。

至于Entry的本质



这是源码,Entry被Node实现后,


只要被Node实例化,【对应的引用就有了对应的Node】,也就有了对应的【key,value】

这是因为,方法被重写后,访问key和value并非private

这样就能够在父类访问子类成员了!

这样,使用Entry的get…方法,就相当于有对应的Node引用使用了get…方法,就获取到了对应的key,value值

对于entrySet()方法



看不懂不重要,重要的是解决了我们的疑问


就是,Entry被一个特定的Node实例化后,Node被删除,还访问得到吗?

明确的告诉你,还可以,因为这里的节点被(深)拷贝了一份,Entry是被这份拷贝实例化的!

注意

key唯一,value不唯一,key不可被设置,只能删掉重新放置

哈希里是可以存放null的,而树不可以(因为null不能比较,会抛异常的)

Map并不是”Collection家族“的

5.2 实例化Set

下面是Set的基本功能(高亮即重点)


方法 解释

boolean add(E e) 增加元素,重复则会失败,返回false

void clear() 清空集合

boolean contains(Object o) 查看元素是否存在

Iterator iterator() 返回迭代器

boolean remove(Object o) 删除对应元素

int size() 返回集合大小

boolean isEmpty() 集合是否为空

Object[] toArray() 转化为数组(非基本数据类型数组!)

boolean containsAll(Collection<?> c) 查询c集合的所有元素是否个个都存在

boolean addAll(Collection<? extends E> c) 添加一整个集合的所有元素,去重作用(完全不重复则返回true)(有现成的集合类的时候适用)

5.2.1 迭代器

这个“工具”的作用就是遍历集合


用法如下:

hasNext() 与 next() 这两个方法打配合
public static void main(String[] args) {
    Map<String, Integer> hashMap = new HashMap<>();
    hashMap.put("小卡拉", 3);
    hashMap.put("马拉圈", 4);
    hashMap.put("芜湖", 5);
    System.out.println(hashMap.get("小"));
    Set<Map.Entry<String, Integer>> set = hashMap.entrySet();
    //for-each 语法遍历
    for(Map.Entry<String, Integer> s : set) {
        System.out.print(s.getKey() + " " + s.getValue() + " ");
    }
    //迭代器遍历法
    Iterator<Map.Entry<String, Integer>> iter =  set.iterator();
    //Iterator<?> 用通配符也可以
    while(iter.hasNext()) {
        System.out.print(iter.next() +  " ");
    }
}


5.2.2 toArray()

这个方法有两个用法

(T[])set.toArray();
//需要强制类型转化!由于擦除机制,数组的返回是Object[]
set.toArray(arr);
//这个arr必须是对应的非基本数据类型数组!或者父类数组
//set里面的元素被整合到arr里了
//返回值可以不接收,接收的话,方式跟上面一样


需要重点强调的一点是,基本数据类型的数组与其包装类的数组不能直接相互转化(自然也不存在自动拆箱装箱),必须遍历一遍!!!


其他方法相对简单,不细说


注意

Set是Collection家族的接口类

key值唯一,Set重点在于除重

key要修改,必须删除再添加

树的key不能是null,因为需要比较

TreeSet/HashSet底层由Map实现,value为Object类型的一个默认对象,key就是key

节省功夫嘛


Set和Map 还可用 LinkedHashSet和LinkedHashMap实例化

这维护了双向链表,可以记录元素的插入次序

6. 哈希部分源码

刚才已经接触了一些源码了,接下来只有一些补充了

6.1 HashMap

6.1.1 一些常量




这个是默认的表的默认容量


这个是表的最大容量


这个是负载因子默认最大值


这个哈希桶树化临界值

即桶内节点达到8,就会折叠成红黑树(原本只是链表)


这个是哈希桶退化为链表的临界值

即桶内节点被删除到6,就会退化成链表(原本是红黑树)


这个是哈希桶树化前提的前提

就是,表的容量很少时,可能会导致桶内的东西太多了【就是冲突次数多】

那么规定一个值,当表的已有元素总数(节点总个数)达到这个值的时候,才考虑折叠链表为红黑树,其他情况直接扩容即可【其他情况是指,桶内元素达到界值后不选择树化,而是扩容哈希表】

为了避免进行扩容、树形化选择的冲突,这个值不能小于 4 * TREEIFY_THRESHOLD

树化方法treeifyBin 就不带大家看了


6.1.2 哈希方法


此方法的作用是让值放的更分散

6.1.3 调整容量

这个操作是将容量调整为最接近的二进制数(较大)


即2, 4, 8, 16…

原理就是,让二进制序列最左边的1之后的位都变成1,

【10101】= =》【11111】= =》【100000】

右移按位与是让这个位【1】成倍数往后扩展

就是原本可能只有一个1扩展为两个1,扩展到四个1,这样最快

在一个构造方法中有用到


用途:搭配哈希方法降低冲突率

6.1.4 构造方法


提供容量和负载因子

提供容量

什么都不提供

提供一个Map,将整个Map的所有元素(拷贝成新的一个引用)

6.1.5 LinkedHashMap

在HashMap中并没有实例化对象LinkedHashMap的构造方法,但是有继承它的…

了解即可

6.2 HashSet

底层也是Map,key就是key,value是一个Object默认值

主要带大家看看构造方法

不带参数构造方法

提供一个集合引用,将所有元素导入Set里

提供容量和负载因子

提供容量

提供容量,负载因子以及布尔类型

这个类型并没有什么用,只是区分其他构造方法而已



就是构造LinkedHashMap( )


本质上LinkedHashSet就是用到的就是这个方法



文章到此结束!谢谢观看

可以叫我 小马,我可能写的不好或者有错误,但是一起加油鸭🦆!


这是我的代码仓库!(在马拉圈的23.2里)代码仓库


Map&Set · 代码位置


邮箱:2040484356@qq.com


目录
相关文章
|
2天前
|
Java
Java之HashMap详解
本文介绍了Java中HashMap的源码实现(基于JDK 1.8)。HashMap是基于哈希表的Map接口实现,允许空值和空键,不同步且线程不安全。文章详细解析了HashMap的数据结构、主要方法(如初始化、put、get、resize等)的实现,以及树化和反树化的机制。此外,还对比了JDK 7和JDK 8中HashMap的主要差异,并提供了使用HashMap时的一些注意事项。
Java之HashMap详解
|
17天前
|
存储 Java
Java中的HashMap和TreeMap,通过具体示例展示了它们在处理复杂数据结构问题时的应用。
【10月更文挑战第19天】本文详细介绍了Java中的HashMap和TreeMap,通过具体示例展示了它们在处理复杂数据结构问题时的应用。HashMap以其高效的插入、查找和删除操作著称,而TreeMap则擅长于保持元素的自然排序或自定义排序,两者各具优势,适用于不同的开发场景。
32 1
|
19天前
|
存储 安全 Java
Java Map新玩法:探索HashMap和TreeMap的高级特性,让你的代码更强大!
【10月更文挑战第17天】Java Map新玩法:探索HashMap和TreeMap的高级特性,让你的代码更强大!
47 2
|
19天前
|
存储 Java 开发者
Java Map实战:用HashMap和TreeMap轻松解决复杂数据结构问题!
【10月更文挑战第17天】本文深入探讨了Java中HashMap和TreeMap两种Map类型的特性和应用场景。HashMap基于哈希表实现,支持高效的数据操作且允许键值为null;TreeMap基于红黑树实现,支持自然排序或自定义排序,确保元素有序。文章通过具体示例展示了两者的实战应用,帮助开发者根据实际需求选择合适的数据结构,提高开发效率。
50 2
|
19天前
|
存储 缓存 安全
HashMap VS TreeMap:谁才是Java Map界的王者?
HashMap VS TreeMap:谁才是Java Map界的王者?
60 2
|
17天前
|
存储 Java 程序员
Java面试加分点!一文读懂HashMap底层实现与扩容机制
本文详细解析了Java中经典的HashMap数据结构,包括其底层实现、扩容机制、put和查找过程、哈希函数以及JDK 1.7与1.8的差异。通过数组、链表和红黑树的组合,HashMap实现了高效的键值对存储与检索。文章还介绍了HashMap在不同版本中的优化,帮助读者更好地理解和应用这一重要工具。
40 5
|
17天前
|
存储 Java API
详细解析HashMap、TreeMap、LinkedHashMap等实现类,帮助您更好地理解和应用Java Map。
【10月更文挑战第19天】深入剖析Java Map:不仅是高效存储键值对的数据结构,更是展现设计艺术的典范。本文从基本概念、设计艺术和使用技巧三个方面,详细解析HashMap、TreeMap、LinkedHashMap等实现类,帮助您更好地理解和应用Java Map。
37 3
|
17天前
|
存储 缓存 安全
在Java的Map家族中,HashMap和TreeMap各具特色
【10月更文挑战第19天】在Java的Map家族中,HashMap和TreeMap各具特色。HashMap基于哈希表实现,提供O(1)时间复杂度的高效操作,适合性能要求高的场景;TreeMap基于红黑树,提供O(log n)时间复杂度的有序操作,适合需要排序和范围查询的场景。两者在不同需求下各有优势,选择时需根据具体应用场景权衡。
22 2
|
17天前
|
存储 安全 Java
Java Map新玩法:深入探讨HashMap和TreeMap的高级特性
【10月更文挑战第19天】Java Map新玩法:深入探讨HashMap和TreeMap的高级特性,包括初始容量与加载因子的优化、高效的遍历方法、线程安全性处理以及TreeMap的自然排序、自定义排序、范围查询等功能,助你提升代码性能与灵活性。
23 2
|
8天前
|
C语言
【数据结构】栈和队列(c语言实现)(附源码)
本文介绍了栈和队列两种数据结构。栈是一种只能在一端进行插入和删除操作的线性表,遵循“先进后出”原则;队列则在一端插入、另一端删除,遵循“先进先出”原则。文章详细讲解了栈和队列的结构定义、方法声明及实现,并提供了完整的代码示例。栈和队列在实际应用中非常广泛,如二叉树的层序遍历和快速排序的非递归实现等。
75 9
下一篇
无影云桌面