韩顺平0基础学java——第25天

news2024/11/24 19:04:53

p509-522


List接口

ArrayList


1.Arraylist 可以加入null,并且多个定什么都能放
2.ArrayRist 和yector其生一致,但A)是成程不安全的源码没有synchronized.优总是效率高
王.Amayeit底层由数数组实现.
阶以变线程的情况下不建议用Arroyst
源码分析
)Aranglast中主d户了-个obje化类的数组
element Date:
2.创建AL时,老用的无参构造器,则初始
elementPnte容量为0第次添加扩容为10.
当需要再次添加时,到1.5倍
0—→10→5→22
3. 老使用将定大小的构造器,要需要广容时就直接扩到1.5倍
如:ArrayList list=new Anaylist(8);后8→12→18→27
transi'ent Obiect[] element Data;
表示该属性不会被序列化。
P51) 讲了Araylist底层的扩容机制
P512 首有将定大小的构造器的Arraytist
有参:CJ第一次扩容就按照1.5倍扩容
(2)整个执行流程和前面一样
建议:自己去debng.一把扩容体程.


Vector


<E>是什么?
1.Vector底层也是一个对象类文组.protected Object[ ]  element Data;
2.Vector是线程同步的.即线程安全:有synchronized
3.开发时,需要线称同步安全时,用Vector.
(不需要时,用Arraylist.因为效率高)

LinkedList

package com.day25;

import java.util.LinkedList;
import java.util.Vector;

public class Day25 {
    public static void main(String[] args) {

        Node jack = new Node("jack");
        Node mdk = new Node("mdk");
        Node lan = new Node("lan");
        //形成链表,连接三个节点!
        jack.next=mdk;
        mdk.next=lan;

        lan.pre=mdk;
        mdk.pre=jack;

        Node first = jack;//让first引用指向jack,也就是头结点
        Node last = lan;//尾节点

        //遍历:
        while (true){
            if(first == null){
                break;
            }
            System.out.println(first);
            first=first.next;
        }

        //添加节点到mdk和lan之间
        Node simis = new Node("simis");
        mdk.next = simis;
        simis.next=lan;
        lan.pre = simis;
        simis.pre = mdk;

        System.out.println("=======添加后======");
        first=jack;
        while (true){
            if(first == null){
                break;
            }
            System.out.println(first);
            first=first.next;
        }
    }
}
class Node{
    //表示双向链表的一个节点(对象
    public Object item;//真正存放数据的地方
    public Node next;
    public Node pre;
    public Node(Object name){
        this.item = name;
    }
    public String toString(){
        return "Node name:"+item;
    }
}

删除节点源码:

remove-removefirst-unlinkFirst

private E unlinkFirst(Node<E> f) {
    // assert f == first && f != null;
    final E element = f.item;
    final Node<E> next = f.next;
    f.item = null;
    f.next = null; // help GC
    first = next;
    if (next == null)
        last = null;
    else
        next.prev = null;
    size--;
    modCount++;
    return element;
}

遍历:

由于LinckedList实现了List接口,所以遍历方式也是一样的:迭代器、增强for、普通for

ArrayList和LinckedList对比

Set接口

Set接口和常用方法

1.无序

2.不允许重复元素,所以最多包含一个null

常用方法:

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

Set接口的遍历方式

1.可以使用迭代器

2.增强for

3.不能使用索引的方式来获取

发现它存放的数据是无序的!(即添加的顺序和取出的顺序不一致)但是它这次这样取了,下次还是这样取的,取出的顺序是固定的。底层是数组+链表的形式!

public static void main(String[] args) {
    Set set = new HashSet();
    set.add("14");
    set.add("12");
    set.add("53");
    set.add("24");
    set.add("56");
    set.add("68");
    set.add(null);
    System.out.println(set);

}

1.HashSet

1.HashSet的底层其实是HashMap

        HashMap的底层是数组+链表+红黑树

结构:

把每个链表的头结点存在table数组里面,效率非常高。

2.HashSet是可以放null的,但是只能放一个,数据是不能重复的!

3.HashSet不保真元素是有序的,取决于hash后,再确定索引的结果。

经典面试题

1.HashSet底层是HashMap
2添加一个元素时,先得到hash值-会转成->索引值
3.找到存储数据表table,看这个索引位者是否已经存放的有元素
4如果没有。直接加入table里
5.如果有,调用equals比较,如果相同,就放弃添加,如果不相同,则添加到最后
6.在Java8中,如果一条链表的元素个数超过TREEIFY_THRESHOLD(默认是8)。并且table的大小>=MIN TREEIFY CAPACITY(默认64).就会进行树化(红黑树)
源码来咯

HashSet的add底层干了什么-1

首先new一个HashSet的时候:

public HashSet() {
    map = new HashMap<>();
}

接下来打开add:这里的map是HashSet里的一个字段,是HashMap

put是map 的一个方法,参数e是泛型,这里姑且当它是我hashset.add(“小小肥橘”)的这个小小肥橘。PRESENT是HashSet类里的占位符,

public boolean add(E e) {
    return map.put(e, PRESENT)==null;
}

接下来我们进入put,这是HashMap 的方法(毕竟是map.put)

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

那么,实际上前文的e就是这里的key,key是“小小肥橘”,value是PRESENT占位符,不管它。

不管以后这个key变化了多少次,value都是不变的。

接下来,分析这个put方法,它返回了putVal,参数有hash(key),我们进入hash这个方法:

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

这也就解释了null为什么总是在HashSet里排在0号位。往右位移16位是为了避免碰撞哈希值。注意这个hash方法返回的不是hashCode!!

回来接着看putVal方法:

final V putVal(int hash, K key, V value, boolean onlyIfAbsent,
               boolean evict) {
    Node<K,V>[] tab; Node<K,V> p; int n, i;//定义了辅助变量
    if ((tab = table) == null || (n = tab.length) == 0)//这个table是HashMap的一个字段,用来存放Node节点的数组
        n = (tab = resize()).length;//给tab进行resize,这个方法进入后发现是在对table进行计算扩容的值,默认是16,并且按照0.75来进行提前扩容,比如存放到12的时候就继续扩容它。执行了resize()后,table的大小就变成了16
    if ((p = tab[i = (n - 1) & hash]) == null)//根据key得到hash,去计算key应该放在哪个位置,并把这个位置的对象赋给p,如果p是否为空,就创建一个节点,并存到这个tab【i】的位置。
        tab[i] = newNode(hash, key, value, null);
    else {
        Node<K,V> e; K k;
        if (p.hash == hash &&
            ((k = p.key) == key || (key != null && key.equals(k))))
            e = p;
        else if (p instanceof TreeNode)
            e = ((TreeNode<K,V>)p).putTreeVal(this, tab, hash, key, value);
        else {
            for (int binCount = 0; ; ++binCount) {
                if ((e = p.next) == null) {
                    p.next = newNode(hash, key, value, null);
                    if (binCount >= TREEIFY_THRESHOLD - 1) // -1 for 1st
                        treeifyBin(tab, hash);
                    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;
            afterNodeAccess(e);
            return oldValue;
        }
    }
    ++modCount;//表示我们修改的次数
    if (++size > threshold)//如果放入的数据超过了缓冲线12,就扩容
        resize();
    afterNodeInsertion(evict);//其实它什么都没干,给HashMap子类实现用的
    return null;//返回空的意思就是,我刚刚添加的这个对象,里面是没有的,也就是添加成功了。否则,见前文还会return别的
}

HashSet的add底层干了什么-2

脑壳痛,先睡了...

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

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

相关文章

MyBatisPlus基础学习

一、简介 二、集成MP 三、入门HelloWorld 四、条件构造器EntityWrapper 五、ActiveRecord(活动记录 ) 六、代码生成器 七、插件扩展 八、自定义全局操作 九、公共字段自动填充 十、Oracle主键Sequence 十一、Idea快速开发插件 十二、mybatis-plus实践及架构原理

SSRF学习,刷题

[HNCTF 2022 WEEK2]ez_ssrf 给了一个Apache2的界面&#xff0c;翻译一下 就是一个默认的界面,目录扫描 可以看到flag.php,肯定是不能直接访问得到的&#xff0c;还有index.php&#xff0c;访问这个 可以看到三个参数data,host,port 还有fsockopen() 函数是 PHP 中用于打开一个…

【网络编程】套接字的多种可选项

可以看出&#xff0c;套接字可选项是分层的。IPPROTOIP层可选项是IP协议相关事项IPPROTO TCP层可选项是TCP协议相关的事项&#xff0c;SOLSOCKET层是套接字相关的通用可选项 getsockopt&&setsockopt #include <sys/socket.h> int getsockopt(int sock, int lev…

第2讲:pixi.js 绘制HelloWorld

基于第0讲和第1讲&#xff0c;我们增添了vite.config.ts文件。并配置了其他的http端口。 此时&#xff0c;我们删除掉没用的东西。 删除 conter.ts、typescript.svg 在main.ts中改成如下内容&#xff1a; import {Application, Text} from pixi.js import ./style.css// 指明…

Aeron:Aeron Agent

Aeron Agent 是一个 Java 代理&#xff0c;用于提供 Aeron、Aeron Archive 和 Aeron Cluster 中发生的运行时低级日志信息。这些日志语句包括从高级管理员事件到大容量数据帧事件。 在调试 Archive 和 Cluster 问题时&#xff0c;Aeron Agent 的日志数据尤其有用。 一、Availab…

github国内加速访问有效方法

这里只介绍实测最有效的一种方法&#xff0c;修改主机的Hosts文件&#xff0c;如果访问github网站慢或者根本无法访问的时候可以采用下面方法进行解决。 1、搜索一个IP查询网站 首先百度搜索选择一个IP查询的网站&#xff0c;这里我用下面这个网站&#xff08;如果该网站失效…

shop APP UI

APP和微信小程序不一样&#xff0c; APP的客户端需要两个(一个安卓&#xff0c;一个苹果IOS); APP的服务端需要&#xff08;管理端后台&#xff0c;接口&#xff09;&#xff1b;

分布式理论与设计 三、分布式一致性协议

1.两阶段提交协议&#xff08;2PC&#xff09; 1&#xff09;两阶段提交协议 两阶段提交协议&#xff0c;简称2PC(2 Prepare Commit)&#xff0c;是比较常用的解决分布式事务问题的方式&#xff0c;要么所有参与进程都提交事务&#xff0c;要么都取消事务&#xff0c;即实现A…

Xlua三方库Android编译出错解决办法

Xlua三方库Android编译出错解决办法 最近听老师的热更教程&#xff0c;讲到xlua编译android平台会报错&#xff0c;也是看了老师的博客&#xff0c;按照方法去解决&#xff0c;然而问题并没有解决。应该是因为代码更新或者版本不一样&#xff0c;在此简单记录一下解决过程。 参…

SpringBoot三层架构

目录 一、传统方式 二、三层架构 三、代码拆分 1、dao层 2、service层 3、control层 四、运行结果 一、传统方式 上述代码存在一定的弊端&#xff0c;在进行软件设计和软件开发中提倡单一责任原则&#xff0c;使代码的可读性更强&#xff0c;复杂性更低&#xff0c;可扩展性…

【Linux硬盘数据读取】WIN10访问linux分区解决方案:ext2fsd

<div id"content_views" class"htmledit_views" style"user-select: auto;"><p>尝试ext2explore、Paragon ExtFS都不好用&#xff0c;强烈安利ext2fsd&#xff0c;可读写&#xff0c;很强大</p> 转自&#xff1a;https://blog…

超高清图像生成新SOTA!清华唐杰教授团队提出Inf-DiT:生成4096图像比UNet节省5倍内存。

清华大学唐杰教授团队最近在生成超高清图像方面的新工作&#xff1a;Inf-DiT&#xff0c;通过提出一种单向块注意力机制&#xff0c;能够在推理过程中自适应调整内存开销并处理全局依赖关系。基于此模块&#xff0c;该模型采用了 DiT 结构进行上采样&#xff0c;并开发了一种能…

JMU 数科 数据库与数据仓库期末总结(4)实验设计题

E-R图 实体-关系图 E-R图的组成要素主要包括&#xff1a; 实体&#xff08;Entity&#xff09;&#xff1a;实体代表现实世界中可相互区别的对象或事物&#xff0c;如顾客、订单、产品等。在图中&#xff0c;实体通常用矩形表示&#xff0c;并在矩形内标注实体的名称。 属性…

Java项目:基于SSM框架实现的汽车养护保养管理系统【ssm+B/S架构+源码+数据库+开题+毕业论文+任务书】

一、项目简介 本项目是一套基于SSM框架实现的汽车养护保养管理系统 包含&#xff1a;项目源码、数据库脚本等&#xff0c;该项目附带全部源码可作为毕设使用。 项目都经过严格调试&#xff0c;eclipse或者idea 确保可以运行&#xff01; 该系统功能完善、界面美观、操作简单、…

VirtualBox 安装UOS统信服务器操作系统

1、准备 1.1安装VirtualBox 由于过程简单&#xff0c;不做赘述&#xff01; 1.2下载UOS服务器版本 下载免费版本即可 服务器与云计算操作系统-统信软件 (uniontech.com)https://uniontech.com/os-serverCloud.html 2、安装 2.1新建虚拟机 2.2选择虚拟机模式&#xff0c;这…

pandas 根据关键词从表格属性进行筛选企业

文章目录 背景实战情况一情况二 背景 最近一段时间在做企业分类的实验&#xff0c;给定一个企业信息表&#xff0c;利用关键词从企业名称和经营范围中筛选相关企业。 情况一&#xff1a;企业名称和经营范围任何一个包含关键词&#xff1b; 情况二&#xff1a;企业名称和经营范…

飞天茅台酒的惊魂五日

“电商百亿补贴修改发货规则”导致黄牛资金压力剧增&#xff0c;资金压力之下部分黄牛择低价甩卖&#xff0c;其他求货的酒行、大酒商则选择观望&#xff0c;价格下行压力最终扩散&#xff0c;造成整个回收市场踩踏&#xff0c;价格急速下跌。 不到半年时间&#xff0c;飞天茅台…

flink1.12.0学习笔记(七)-监控与优化

flink1.12.0学习笔记第 7 篇-监控与优化 7-1-Flink-Metrics 1.Metrics介绍 由于集群运行后很难发现内部的实际状况&#xff0c;跑得慢或快&#xff0c;是否异常等&#xff0c;开发人员无法实时查看所有的 Task 日志&#xff0c;比如作业很大或者有很多作业的情况下&#xff…

【C++进阶学习】第二弹——继承(下)——挖掘继承深处的奥秘

继承&#xff08;上&#xff09;&#xff1a;【C进阶学习】第一弹——继承&#xff08;上&#xff09;——探索代码复用的乐趣-CSDN博客 前言&#xff1a; 在前面我们已经讲了继承的基础知识&#xff0c;让大家了解了一下继承是什么&#xff0c;但那些都不是重点&#xff0c;今…

半监督学习

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 目录 介绍一、Self Training自训练1、介绍2、代码示例3、参数解释 二、Label Propagation&#xff08;标签传播&#xff09;1、介绍2、代码示例3、参数解释 三、Label Spread…