第十四章 (Set)

news2024/11/26 20:33:35

一、Set 接口(P518)

1. Set 接口基本介绍

(1)无序(添加和取出的顺序不一致),没有索引。
(2)不允许重复元素,所以最多包含一个 null。

2. Set 接口的常用方法

和 List 接口一样,Set 接口也是 Collection 的子接口,因此,常用方法和 Collection 接口一样。

3. Set 接口的遍历方式

同 Collection 的遍历方式一样,因为 Set 接口是 Collection 接口的子接口。
(1)可以使用选代器
(2)增强for
(3)不能使用索引的方式来获取

二、HashSet(P519)

1. Hashset 的说明

(1)HashSet 实现了 Set 接口。
(2)HashSet 实际上是 HashMap。

(3)可以存放 null 值,但是只能有一个 null。
(4)HashSet 不保证元素是有序的,取决于 hash 后,再确定索引的结果。
(5)不能有重复元素/对象。

2. Hashset底层机制源码说明(P522)

分析 Hashset 底层是 HashMap,HashMap 底层是(数组+链表+红黑树

public class HashMap_<K, V> {

    transient Node<K, V>[] table;

    transient int modCount;

    transient int size;

    public V put(K key, V value) {
        return putVal(hash(key), key, value, false, true);
    }

    static final int hash(Object key) {
        int h;
        return (key == null) ? 0 : (h = key.hashCode()) ^ (h >>> 16);
    }

    final V putVal(int hash, K key, V value, boolean onlyIfAbsent,
                   boolean evict) {
        Node<K, V>[] tab;
        Node<K, V> p;
        int n, i;

        // 属性table为null或table的长度为0,就扩容
        if ((tab = table) == null || (n = tab.length) == 0) {
            n = (tab = resize()).length;
        }
        // 如果tab[i]为null,表示没有存放元素,就创建节点并赋值给tab[i]
        if ((p = tab[i = (n - 1) & hash]) == null) {
            tab[i] = newNode(hash, key, value, null);
        } else {
            Node<K, V> e;
            K k;

            // p 和添加元素的hash值相同 并且 (key相同或equals相同),p赋值给e
            if (p.hash == hash &&
                    ((k = p.key) == key || (key != null && key.equals(k)))) {
                e = p;

            }
            // 链表循环比较
            else {
                for (int binCount = 0; ; ++binCount) {
                    if ((e = p.next) == null) {
                        p.next = newNode(hash, key, value, null);
                        break;
                    }
                    if (e.hash == hash &&
                            ((k = e.key) == key || (key != null && key.equals(k)))) {
                        break;
                    }
                    p = e;
                }
            }
            if (e != null) { // existing mapping for key
                V oldValue = e.value;
                if (!onlyIfAbsent || oldValue == null) {
                    e.value = value;
                }
                return oldValue;
            }
        }
        ++modCount;
        if (++size > threshold) {
            resize();
        }
        return null;
    }

    int threshold;

    final float loadFactor = DEFAULT_LOAD_FACTOR;

    static final int MAXIMUM_CAPACITY = 1 << 30;

    static final int DEFAULT_INITIAL_CAPACITY = 1 << 4; // 16
    // 加载因子
    static final float DEFAULT_LOAD_FACTOR = 0.75f;

    final Node<K, V>[] resize() {
        Node<K, V>[] oldTab = table;
        int oldCap = (oldTab == null) ? 0 : oldTab.length;
        int oldThr = threshold;
        int newCap, newThr = 0;
        if (oldCap > 0) {
            if (oldCap >= MAXIMUM_CAPACITY) {
                threshold = Integer.MAX_VALUE;
                return oldTab;
            } else if ((newCap = oldCap << 1) < MAXIMUM_CAPACITY &&
                    oldCap >= DEFAULT_INITIAL_CAPACITY) {
                newThr = oldThr << 1; // double threshold
            }
        } else if (oldThr > 0) {
            newCap = oldThr;
        } else {
            // 扩容
            newCap = DEFAULT_INITIAL_CAPACITY;
            newThr = (int) (DEFAULT_LOAD_FACTOR * DEFAULT_INITIAL_CAPACITY);
        }
        if (newThr == 0) {
            float ft = (float) newCap * loadFactor;
            newThr = (newCap < MAXIMUM_CAPACITY && ft < (float) MAXIMUM_CAPACITY ?
                    (int) ft : Integer.MAX_VALUE);
        }
        threshold = newThr;

        // 初始化数组,并赋值给属性table
        Node<K, V>[] newTab = (Node<K, V>[]) new Node[newCap];
        table = newTab;

        return newTab;
    }

    Node<K, V> newNode(int hash, K key, V value, Node<K, V> next) {
        return new Node<>(hash, key, value, next);
    }

    static class Node<K, V> {
        final int hash;
        final K key;
        V value;
        Node<K, V> next;

        Node(int hash, K key, V value, Node<K, V> next) {
            this.hash = hash;
            this.key = key;
            this.value = value;
            this.next = next;
        }
    }
}

(1)HashSet 底层是 HashMap

(2)添加一个元素时,先得到hash值-会转成->索引值

(3)找到存储数据表 table,看这个索引位置是否已经存放的有元素

(4)如果没有,直接加入

(5)如果有,调用 equals 比较,如果相同,就放弃添加,如果不相同,则添加到最后

(6)在 Java8 中,如果一条链表的元素个数达到 TREEIFY_THRESHOLD(默认是8),并且 table 的大小 >= MIN_TREEIFY_CAPACITY(默认64),就会进行树化(红黑树)

红黑树机制

(1)HashSet 底层是 HashMap,第一次添加时,table 数组扩容到16,临界值(threshold)是16,加载因子(loadFactor)是0.75=12
(2)如果table数组使用到了临界值12,就会扩容到16*2=32,新的临界值就是32*0.75=24,依次类推
(3)在Java8中,如果一条链表的元素个数到达TREEIFY_THRESHOLD(默认是8),并且table的大小>=MIN_TREEIFY_CAPACITY(默认64)就会进行树化(红黑树),否则仍然采用数组扩容机制

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/578014.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

阿里云服务器ECS云盘扩容

前言 对于云服务器&#xff0c;相信大多数开发的铁子们都玩过&#xff0c;但是云盘爆满的情况&#xff0c;对于新手或者没有自己运营业务的铁子们&#xff0c;平台给的初始容量也不算小&#xff0c;所以这种情况碰到的概率还是比较小。由于我的服务器应用的复杂度随着业务的发…

ubuntu安装搜狗输入法,图文详解+踩坑解决

搜狗输入法已支持Ubuntu16.04、18.04、19.10、20.04、20.10&#xff0c;本教程系统是基于ubuntu18.04 一、添加中文语言支持 系统设置—>区域和语言—>管理已安装的语言—>在“语言”tab下—>点击“添加或删除语言”。 弹出“已安装语言”窗口&#xff0c;勾选中文…

chatgpt赋能python:Python在SEO领域的优势

Python在SEO领域的优势 Python作为一种高效、灵活的编程语言&#xff0c;已经被广泛应用于多个领域&#xff0c;包括Web应用、数据科学、自然语言处理等。在SEO领域&#xff0c;Python也有其独特的优势。 爬虫 Python强大的爬虫库和框架&#xff0c;如BeautifulSoup、Scrapy…

chatgpt赋能python:Python行列转换教程:如何轻松实现行列转换

Python行列转换教程&#xff1a;如何轻松实现行列转换 在数据处理和分析中&#xff0c;经常需要将行和列进行转换。Python是一种优秀的编程语言&#xff0c;提供了多种方法来实现行列转换。在本教程中&#xff0c;我们将介绍如何使用Python实现行列转换&#xff0c;并提供简单…

《Spring Guides系列学习》guide66 - guide68及小结

要想全面快速学习Spring的内容&#xff0c;最好的方法肯定是先去Spring官网去查阅文档&#xff0c;在Spring官网中找到了适合新手了解的官网Guides&#xff0c;一共68篇&#xff0c;打算全部过一遍&#xff0c;能尽量全面的了解Spring框架的每个特性和功能。 接着上篇看过的gui…

深入了解Golang中的反射机制

目录 反射 反射的分类 值反射 类型反射 运行时反射 编译时反射 接口反射 结构体反射 常用函数 值反射 类型反射 值反射和类型反射的区别 结构体反射 示例代码 反射 反射是指在程序运行时动态地检查和修改对象的能力。在Go语言中&#xff0c;通过反射可以在运行时…

chatgpt赋能python:Python逆序对:什么是逆序对,如何使用Python进行逆序对计算?

Python逆序对&#xff1a;什么是逆序对&#xff0c;如何使用Python进行逆序对计算&#xff1f; 在计算机科学中&#xff0c;逆序对是指在一个数组中&#xff0c;如果存在下标i < j&#xff0c;但是a[i] > a[j]&#xff0c;则a[i]和a[j]构成一个逆序对。逆序对对于理解和…

pthread多线程:传入参数并检查 data race

文章目录 1. 目的2. 给子线程传入参数&#xff1a;万能类型 void*3. data race3.1 什么是 data race3.2 怎样检测 data race 4. data race 的例子4.1 子线程传入同一个 data4.2 使用栈内存 5. 解决 data race 问题5.1 忽视问题&#xff1f;5.2 避开同一个变量的使用5.3 使用互斥…

Office project 2010安装教程

哈喽&#xff0c;大家好。今天一起学习的是project 2010的安装&#xff0c;Microsoft Office project项目管理工具软件&#xff0c;凝集了许多成熟的项目管理现代理论和方法&#xff0c;可以帮助项目管理者实现时间、资源、成本计划、控制。有兴趣的小伙伴也可以来一起试试手。…

每天一道面试题之String str=“i“与 String str=new String(“i”)一样吗?

String str"i"与 String strnew String(“i”)一样吗&#xff1f; 要想知道二者是否一样&#xff0c;我们只需要通过进行比较&#xff0c;为什么不用equals的原因&#xff0c;大家可以认真阅读这篇文章 测试代码如下&#xff1a; public class Test1 {public stati…

chatgpt赋能python:Python选择器:优化你的SEO

Python 选择器&#xff1a;优化你的SEO 介绍 随着搜索引擎优化(SEO)变得越来越重要&#xff0c;Web 开发人员需要采取各种措施来提高网站的搜索排名。其中之一就是通过使用正确的 HTML 标签和优秀的内容来提高搜索引擎爬虫对网站的理解。这时候 Python 选择器就变得尤为重要。…

chatgpt赋能python:Python选择函数

Python 选择函数 Python是一种流行的编程语言&#xff0c;是许多开发人员的首选。在Python中&#xff0c;有许多函数可供开发人员使用。这些函数不仅提高了开发的速度&#xff0c;而且还可以帮助我们更快地解决许多问题。在本文中&#xff0c;我们将重点介绍Python选择函数。 …

iostat详解

iostat在centOS中默认没有 安装 yum install sysstat 使用 iostat -dxk 5 rrqm/s 每秒进入队列的合并读写请求数 wrqm/sr/s每秒发送到设备的读写请求数w/srKB/s每秒读写的吞吐量&#xff0c;单位KBwKB/savgrq-sz 以扇区为大小的请求大小 avgqu-sz设备队列中等待的请求数await在…

HNU-电路与电子学-综合设计-模型机

写在前面&#xff1a; 每一年的综合设计肯定都有改动&#xff0c;故肯定不能照搬照抄&#xff0c;大家可以借鉴思路&#xff0c;复现成果&#xff0c;但要注意不同之处&#xff0c;以免被0分处理。 模型设计的指导书我不放在这里了&#xff0c;因为那是课程组老师们的成果。 …

HNU-电路与电子学-学习建议

电路与电子学我考的并不好&#xff0c;最后总评只有85分。 &#xff08;主要是期末考太差了&#xff0c;只有70分&#xff0c;前面基本全拿满了&#xff0c;也无济于事&#xff09; 但我自认为学的还可以&#xff0c;于是写下一些感想。 我姑妄言之&#xff0c;诸位姑妄信之…

【华为OD机试】投骰子【2023 B卷|200分】

【华为OD机试】-真题 !!点这里!! 【华为OD机试】真题考点分类 !!点这里 !! 题目描述 骰子是一个立方体,每个面一个数字,初始为左1,右2,前3(观察者方向),后4,上5,下6, 用123456表示这个状态,放置在平面上, 可以向左翻转(用L表示向左翻转1次), 可以向右翻转(用…

C Primer Plus第九章编程练习答案

学完C语言之后&#xff0c;我就去阅读《C Primer Plus》这本经典的C语言书籍&#xff0c;对每一章的编程练习题都做了相关的解答&#xff0c;仅仅代表着我个人的解答思路&#xff0c;如有错误&#xff0c;请各位大佬帮忙点出&#xff01; 1.设计一个函数min(x, y)&#xff0c;…

【利用AI让知识体系化】5种创建型模式

文章目录 创建型模式简介工厂模式抽象工厂模式单例模式建造者模式原型模式 创建型模式 简介 创建型模式&#xff0c;顾名思义&#xff0c;是用来创建对象的模式。在软件开发中&#xff0c;对象的创建往往比一般的编程任务更为复杂&#xff0c;可能涉及到一些琐碎、复杂的过程…

Boosting以及代表算法(Adaboost、GBDT)介绍

一、Boosting介绍 1.什么是Boosting Boosting&#xff08;提升&#xff09;是一种集成学习方法&#xff0c;通过组合多个弱学习器来构建一个强学习器。与Bagging不同&#xff0c;Boosting采用了序列化的方式构建模型&#xff0c;每个弱学习器都是在前一个弱学习器的基础上进行…

Linux-0.11 文件系统exec.c详解

Linux-0.11 文件系统exec.c详解 模块简介 该模块实现了二进制可执行文件和shell脚本文件的加载和执行。 函数详解 create_tables static unsigned long * create_tables(char * p,int argc,int envc)该函数的作用是建立参数和环境变量指针表。 create_table的作用就是建立…