集合

集合

Vector底层结构和ArrayList的比较

底层结构 版本 线程安全(同步)效率 扩容倍数 ArrayList 可变数组 jdk1.2 不安全,效率高 如果有参构造就是1.5倍扩容

如果是无参构造

1.第一次10

2.从第二次开始按1.5倍扩 Vector 可变数组Object[] jdk1.0 安全,效率不高 如果是无参,默认10,满后,就按2倍扩容

如果指定大小,则每次直接按2倍扩

底层结构 增删的效率 改查的效率 ArrayList 可变数组 较低

数组扩容 较高 LinkedList 双向链表 较高

通过链表追加 较低

如何选择:

  1. 如果我们改查的操作多,选择ArrayList
  2. 如果我们增删的操作多,选择LinkedList
  3. 一般来说,再程序中,80%-90%都是查询,因此大部分情况会选择ArrayList

Set集合概述和特点

Set集合特点:

  1. 不包含重复元素的集合
  2. 没有带索引的方法,所以不能使用普通for循环遍历

HashSET底层机制说明

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

集合

Map接口实现类的特点

注意:这里说的是jdk8

  1. Map用于保存具有映射关系的数据:Key-Value
  2. Map中的key和value可以是任何引用类型的数据,会封装到HashMap$Node对象中
  3. Map中的key不允许重复,原因和HashSet一样,如果有相同的key则新的value替换旧的value
  4. Map中的value可以重复
  5. Map的key可以为null,value也可以为null,注意key为null话只能有一个,value为null可以有多个;
  6. 常用String类作为Map的key
  7. key和value之间存在单向一对一关系,即通过指定的key总能找到对应的value

HashMap介绍

  1. Map接口的常用实现类:HashMap、Hashtable和Properties
  2. HashMap是Map接口使用频率最高的实现类
  3. HashMap是以key-val对应的方式来存储数据
  4. key值不能重复,但是value可以重复,允许使用null键和null值
  5. 如果添加相同的key,则会覆盖原来的key-val,等同于修改(key不会替换,val会替换)
  6. 与HashSet一样,不保证映射的顺序,因为磁层是以hash表的方式来存储的
  7. HashMap没有实现同步,因此是线程不安全的

HashTable介绍

  1. 存放的元素是键值对:k-v
  2. hashTable的键和值都不能为null,否则会抛出NullPointerException
  3. hashTable使用方法基本上和HashMap一样
  4. hashTable是线程安全的,hashMap是线程不安全的

Hashtable和HashMap对比

版本 线程安全(同步) 效率 允许null键null值 HashMap 1.2 不安全 高 可以 Hashtable 1.0 安全 较低 不可以

Properties基本介绍

  1. Properties类继承自Hashtable类并且实现了Map接口,也是使用一种键值对的形式来保存数据。
  2. 它的使用特点和Hashtable类似
  3. Properties还可以用于从xxx.properties文件中,加载数据到Properties类对象,并进行读取和修改
  4. key和value不能为null

开发中如何选择集合实现类

在开发中,选择上面集合实现类,主要取决于业务操作特点,然后根绝结合实现类特性进行选择,分析如下:

1.先判断存储的类型 (一组对象[单列]或是一组键值对[双列])

2.一组对象[单列]: Collection接口

​ 允许重复: List

​ 增删多: LinkedList[底层维护了一个双向链表]

​ 改查多: ArrayList[底层维护Object类型的可变数组]

​ 不允许重复:Set

​ 无序: HashSet [底层是HashMap,维护了一个哈希表,即(数组+链表+红黑树)]

​ 排序:TreeSet

​ 插入和取出顺序一致: LinkedHashSet,维护的是数组+双向链表

3.一组键值对[双列]: Map

​ 键无序: HashMap [底层是:哈希表 jdk7:数组+链表,jdk8:数组+链表+红黑树]

​ 键排序: TreeMap

​ 键插入和取出顺序一致: LinkedHashMap

​ 读取文件: Properties

HashSet和TreeSet是如何实现去重的

  • HashSet去重机制:hashCode() + equals(),底层先通过存入对象,进行运算得到hash值,通过hash值得到对应的索引,如果发现得到的索引对应table中相同索引的位置没有数据则直接存放,如果有数据,则会进行equals比较[遍历比较],如果比较后不相同则加入,否则不加入。
  • TreeSet去重机制:如果你传入了一个Comparator匿名对象,就是用实现的compare去重,如果方法返回0,就认为是相同的元素/数据,就不添加,如果你没有传入一个Comparator匿名对象,则以你添加的对象实现的Comparable接口的compareTo去重。

分析下面代码

package com.example.homework;

import java.util.HashSet;
import java.util.Objects;

/**
 * @Author 郜庆辉
 * @Time 2022/5/28 17:47
 * @Version 1.0
 */
public class Homework4 {
    public static void main(String[] args) {
        HashSet set = new HashSet();
        Person p1 = new Person(1001, "AA");
        Person p2 = new Person(1002, "BB");
        set.add(p1);  //第一次添加的1001, "AA",p1的hash值为10
        set.add(p2);
        System.out.println(set);

        p1.name = "CC"; //修改后的1001, "CC",p1的hash值还是10,只不过CC把AA占了
        System.out.println(set);
        set.remove(p1);//remove时也会计算hash值,但是计算的是1001, "CC"的hash值;hash值为11,删除的就hash值为11的索引位置;即p1没有删除成功,因为p1的hash为10;
        System.out.println(set);

        set.add(new Person(1001, "CC"));//这里添加的是按照1001, "CC"hash值进行添加的,同样会添加成功,hash值为12;
        System.out.println(set);
        set.add(new Person(1001,"AA")); //这里又添加的1001,"AA"hash值为10,跟p1的hash值一样,按理说不会添加成功,但是现在P1是1001,"CC",hash不一样时用equals比较,value不同,也可以添加成功。
        System.out.println(set);
    }
}

class Person {
    public int id;
    public String name;

    public Person(int id, String name) {
        this.id = id;
        this.name = name;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        Person person = (Person) o;
        return id == person.id && Objects.equals(name, person.name);
    }

    @Override
    public int hashCode() {
        return Objects.hash(id, name);
    }

    // @Override
    // public String toString() {
    //     return "Person{" +
    //             "id=" + id +
    //             ", name='" + name + '\'' +
    //             '}';
    // }
}

Vector和ArrayList比较

底层结构 版本 线程安全(同步)效率 扩容倍数 ArrayList 可变数组 jdk1.2 不安全,效率高 如果使用有参构造器按照1.5倍扩容,如果使用无参构造器:

1.第一次扩容10

2.从第二次开始按照1.5倍扩容 Vector 可变数组

Object[] jdk1.0 安全,效率不高 如果是无参,默认10,满后按照2倍扩容

如果是指定大小创建Vector,则每次按照2倍扩容。

Original: https://www.cnblogs.com/gaoqinghui/p/16344246.html
Author: 忧愁小松鼠
Title: 集合

原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/569639/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

  • Spring动态代理的生成-如何判断是使用JDK动态代理还是CGlib代理

    前言 在上一篇文章中讲到了Spring是如何获取对应的Bean的增强,然后本次主要讲解一下Spring如何在获取到增强后创建Spring代理的。 在步入正题之前先给大家看一下Spr…

    Java 2023年6月7日
    098
  • Mybatis多数据源(一) 不同的mapper文件对应不同的数据源

    如果一个系统存在多个业务数据库,那么就意味着在该系统中存在多个数据源,此时针对数据库的操作如何让其具体的落地到某个库中呢? 一个解决办法就是mybatis不同的mapper文件对应…

    Java 2023年5月30日
    087
  • idea 安装Jenkins插件,管理自动任务

    下载插件 安装完成后出现在侧边栏 点击设置 配置界面 账号密码(Token) 给Jenkins配置Token 复制保存token 点击测试按钮 Successful,关闭配置就会同…

    Java 2023年6月6日
    098
  • 通俗易懂讲反射

    可进入本人语雀文档看,格式更清晰明了哦 https://www.yuque.com/docs/share/3c013ec6-6c35-4854-aaf6-ff9a6e8a6af2?…

    Java 2023年6月8日
    0100
  • Java: Image Viewer Frame

    java;gutter:true; /<em><em> * 版权所有 2022 涂聚文有限公司 * 许可信息查看: * 描述: * Core Java, V…

    Java 2023年6月16日
    060
  • springcloud整合nacos配置中心

    最近实物资产管理运维产品pams系统架构搭建中,涉及到配置中心的问题,在这里做个记录,作为第一手经验分享,也是自我备忘吧。 整个体系,目前一共有10+个中等粒度的微服务,每个服务都…

    Java 2023年5月30日
    0103
  • Java开发笔记(一百四十八)通过JDBC查询数据记录

    前面介绍了通过JDBC如何管理数据库,当时提到Statement专门提供了executeQuery方法用于查询操作,为什么查询操作这么特殊呢?这是因为其它语句跑完一次就了事了,顶多…

    Java 2023年6月6日
    059
  • The One

    博客园 :当前访问的博文已被密码保护 请输入阅读密码: Original: https://www.cnblogs.com/stupidxixi/p/9444380.htmlAut…

    Java 2023年6月5日
    086
  • effective java

    注:本文转载于http://www.cnblogs.com/xing901022/p/5854506.html,感谢xingoo! 通过函数作为策略有两个要注意的地方: 使用接口作…

    Java 2023年5月29日
    068
  • 1.欧拉算法求100以内素数个数

    class test { private static boolean[] check = new boolean[101];//这里定100会有越界错误 private stat…

    Java 2023年6月9日
    0185
  • 搭建简单JavaWeb项目

    参考:(17条消息) 手把手搭建一个完整的javaweb项目(适合新手)_心歌技术的博客-CSDN博客_javaweb项目完整案例 补充项目结构的细节,进行了一点修改,修改为学生信…

    Java 2023年6月9日
    098
  • 基于hashset对中文词快速查询

    下载附件”百度分词词库”, 里面大约有10w个词, 使用C语言或者Java实现单词快速查找功能(不借助第三方类库工具或者数据库), 将单词载入内存中, 建立…

    Java 2023年6月13日
    098
  • 踩坑了!0作为除数,不一定会抛出异常!

    你好呀,我是歪歪。 踩坑了啊,又踩坑了啊! 这次踩到一个特别无语的常识坑。知道真相的那一刻,人就是整个麻掉。 先上个代码: private&#xA0;static&…

    Java 2023年6月5日
    096
  • java 集合学习资料收集

    ArrayDeque , LinkedList , Stack的关系差不多就是下图那样 Stack实现了Vector接口,LinkKist实现了Deque,List接口,Array…

    Java 2023年5月29日
    085
  • DirectX11–深入理解Effects11、使用着色器反射机制(Shader Reflection)实现一个复杂Effects框架

    如果之前你是跟随本教程系列学习的话,应该能够初步了解Effects11(现FX11)的实现机制,并且可以编写一个简易的特效管理框架,但是随着特效种类的增多,要管理的着色器、资源等也…

    Java 2023年5月30日
    098
  • 2.Mybatis-常用sql

    1.Mybatis常用select语句 SELECT sr.ROLE_ID AS roleId, sr.ROLE_NAME AS roleName, sr.IS_ACTIVE AS…

    Java 2023年6月13日
    079
亲爱的 Coder【最近整理,可免费获取】👉 最新必读书单  | 👏 面试题下载  | 🌎 免费的AI知识星球