java基础---集合(2)
一、 Set 集合
- java.util.Set集合是Collection集合的子集合,与List集合平级。该集合中元素没有先后放入次序,且不允许重复。
- 存储的数据在底层数组中并非按照数组索引的顺序添加,而是根据数据的哈希值决定的
- 保证添加的元素按照equals()判断时,不能返回true.即:相同的元素只能添加一个
- 该集合的主要实现类是:HashSet类 和 TreeSet类以及LinkedHashSet类。
- HashSet类的底层是采用哈希表进行数据管理的,数组+链表
- TreeSet类的底层是采用红黑树进行数据管理的
- LinkedHashSet类与HashSet类的不同之处在于内部维护了一个双向链表,链表中记录了元素的迭代顺序,也就是元素插入集合中的先后顺序,因此便于迭代。
- Set接口中没有额外定义新的方法,使用的都是Collection中声明过的方法
1. HashSet
- 底层是采用哈希表进行数据管理的,数组+链表,数组初始容量为16, 当如果使用率超过0.75,就会扩大容量为原来的2倍;不能保证元素的排列顺序,非线程安全,集合元素可以为null
- 为什么用Eclipse/IDEA复写hashCode方法,有31这个数字?
- 选择系数的时候要选择尽量大的系数。因为如果计算出来的hash地址越大,所谓的“冲突”就越少,查找起来效率也会提高。(减少冲突)
- 31只占用5bits,相乘造成数据溢出的概率较小。
- 31可以 由i*31== (i<<5)-1来表示,现在很多虚拟机里面都有做相关优化。 (提高算法效率)
- 31是一个素数,素数作用就是如果我用一个数字来乘以这个素数,那么最终出来的结果只能被素数本身和被乘数还有1来整除! (减少冲突)
- 添加元素的过程
- 我们向HashSet中添加元素a,首先调用元素a所在类的hashCode()方法,计算元素a的哈希值,此哈希值接着通过某种算法计算出在HashSet底层数组中的存放位置(即为:索引位置),判断数组此位置上是否已经有元素
如果此位置上没有其他元素,则元素a添加成功。 --->情况1
如果此位置上有其他元素b(或以链表形式存在的多个元素),则比较元素a与元素b的hash值:
如果hash值不相同,则元素a添加成功。--->情况2
如果hash值相同,进而需要调用元素a所在类的equals()方法:equals()返回true,元素a添加失败;equals()返回false,则元素a添加成功。--->情况2
对于添加成功的情况2和情况3而言:元素a 与已经存在指定索引位置上数据以链表的方式存储。
jdk 7 :元素a放到数组中,指向原来的元素。
jdk 8 :原来的元素在数组中,指向元素a
2. LinkedHashSet
- 根据元素的 hashCode 值来决定元素的存储位置,但它同时使用双向链表维护元素的次序,这使得元素看起来是以插入顺序保存的
- LinkedHashSet 不允许集合元素重复
- 向Set添加的数据,其所在的类一定要重写hashCode()和equals(),相等的对象必须具有相等的散列码;对象中用作 equals() 方法比较的 Field,都应该用来计算 hashCode 值。
3. TreeSet
- 底层采用红黑树进行数据的管理,当有新元素插入到TreeSet集合时,需要使用新元素与集合中已有的元素依次比较来确定新元素的合理位置
- 比较元素大小的规则有两种方式:
- 使用元素的自然排序规则进行比较并排序,让元素类型实现java.lang.Comparable接口;
- BigDecimal、 BigInteger 以及所有的数值型对应的包装类:按它们对应的数值大小进行比较
- Character:按字符的 unicode值来进行比较
- Boolean: true 对应的包装类实例大于 false 对应的包装类实例
- String:按字符串中字符的 unicode 值进行比较
- Date、 Time:后边的时间、日期比前面的时间、日期大
- 使用比较器规则进行比较并排序,构造TreeSet集合时传入java.util.Comparator接口;
- 自然排序的规则比较单一,而比较器的规则比较多元化,而且比较器优先于自然排序;
- 使用元素的自然排序规则进行比较并排序,让元素类型实现java.lang.Comparable接口;
@Test
public void tes1(){
HashSet set = new HashSet();
Person p1 = new Person(1001,"AA");
Person p2 = new Person(1002,"BB");
set.add(p1);
set.add(p2);
p1.name = "CC";
set.remove(p1); //找不到new Person(1001,"AA");
System.out.println(set);//[Person{name='CC', id=1001}, Person{name='BB', id=1002}]
set.add(new Person(1001,"CC"));
System.out.println(set);//[Person{name='CC', id=1001}, Person{name='CC', id=1001}, Person{name='BB', id=1002}]
set.add(new Person(1001,"AA"));
System.out.println(set);//[Person{name='CC', id=1001}, Person{name='CC', id=1001}, Person{name='AA', id=1001}, Person{name='BB', id=1002}]
}
class Person{
public String name;
public int id; public Person(int id,String name) {
this.name = name;
this.id = id;
} @Override
public String toString() {
return "Person{" +
"name='" + name + '\'' +
", id=" + id +
'}';
} @Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false; Person person = (Person) o; if (id != person.id) return false;
return name != null ? name.equals(person.name) : person.name == null;
} @Override
public int hashCode() {
int result = name != null ? name.hashCode() : 0;
result = 31 * result + id;
return result;
}
}
二、Map集合
- java.util.Map<K,V>集合中存取元素的基本单位是:单对元素,其中类型参数如下:
- K - 此映射所维护的键(Key)的类型,相当于目录。
- V - 映射值(Value)的类型,相当于内容。该集合中key是不允许重复的,而且一个key只能对应一个value。
- 该集合的主要实现类有:HashMap类、TreeMap类、LinkedHashMap类、Hashtable类、Properties类。
- HashMap类的底层是采用哈希表进行数据管理的。
- TreeMap类的底层是采用红黑树进行数据管理的。
- LinkedHashMap类与HashMap类的不同之处在于内部维护了一个双向链表,链表中记录了元素的迭代顺序,也就是元素插入集合中的先后顺序,因此便于迭代。
- Hashtable类是古老的Map实现类,与HashMap类相比属于线程安全的类,且不允许null作为key或者value的数值。
- Properties类是Hashtable类的子类,该对象用于处理属性文件,key和value都是String类型的。
- Map集合是面向查询优化的数据结构, 在大数据量情况下有着优良的查询性能。经常用于根据key检索value的业务场景。
| 方法声明 | 功能介绍 |
| V put(K key, V value) | 将Key-Value对存入Map,若集合中已经包含该Key,则替换该Key所对应的Value,返回值为该Key原来所对应的Value,若没有则返回null |
| V get(Object key) | 返回与参数Key所对应的Value对象,如果不存在则返回null |
| boolean containsKey(Object key); | 判断集合中是否包含指定的Key |
| boolean containsValue (Object value); | 判断集合中是否包含指定的Value |
| V remove(Object key) | 根据参数指定的key进行删除 |
| Set keySet() | 返回此映射中包含的键的Set视图 |
| Collection values() | 返回此映射中包含的值的Set视图 |
| Set<Map.Entry<K,V>> entrySet() | 返回此映射中包含的映射的Set视图 |
- 使用元素的key调用hashCode方法获取对应的哈希码值,再由某种哈希算法计算在数组中的索引位置。若该位置没有元素,则将该键值对直接放入即可。
- 若该位置有元素,则使用key与已有元素依次比较哈希值,若哈希值不相同,则将该元素直接放入。
- 若key与已有元素的哈希值相同,则使用key调用equals方法与已有元素依次比较。
- 若相等则将对应的value修改,否则将键值对直接放入即可
- DEFAULT_INITIAL_CAPACITY : HashMap的默认容量是16。
- DEFAULT_LOAD_FACTOR:HashMap的默认加载因子是0.75。
- threshold:扩容的临界值,该数值为:容量*填充因子,也就是12。
- TREEIFY_THRESHOLD:若Bucket中链表长度大于该默认值则转化为红黑树存储,该数值是8。
- MIN_TREEIFY_CAPACITY:桶中的Node被树化时最小的hash表容量,该数值是64
java.util.Collections类主要提供了对集合操作或者返回集合的静态方法。
| 方法声明 | 功能介绍 |
| static <T extends Object & Comparable<? super T>> T max(Collection<? extends T> coll) |
根据元素的自然顺序返回给定集 合的最大元素 |
| static T max(Collection<? extends T> coll, Comparator<? super T> comp) |
根据指定比较器引发的顺序返回 给定集合的最大元素 |
| static <T extends Object & Comparable<?super T>> T min(Collection<? extends T> coll) |
根据元素的自然顺序返回给定集 合的最小元素 |
| static T min(Collection<? extends T> coll, Comparator<? super T> comp) |
根据指定比较器引发的顺序返回 给定集合的最小元素 |
| static void copy(List<? super T> dest, List<? extends T> src) |
将一个列表中的所有元素复制到 另一个列表中 |
| 方法声明 | 功能介绍 |
| static void reverse(List<?> list) | 反转指定列表中元素的顺序 |
| static void shuffle(List<?> list) | 使用默认的随机源随机置换指定的列表 |
| static <T extends Comparable<? super T>> void sort(List list) |
根据其元素的自然顺序将指定列表按升 序排序 |
| static void sort(List list, Comparator<? super T> c) | 根据指定比较器指定的顺序对指定列表 进行排序 |
| static void swap(List<?> list, int i, int j) | 交换指定列表中指定位置的元素 |
java基础---集合(2)的更多相关文章
- JAVA基础-集合(二)
一.Map整体结构体系 Map是集合的另一大派系,与Collection派系不同的是Map集合是以键值对儿的形式存储在集合的.两个键为映射关系,其中第一个键为主键(主键是唯一的不可重复),第二个键为v ...
- Java基础-集合的嵌套
Java基础-集合的嵌套 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.静态导入 静态导入是在JDK1.5后的新特性,可以减少开发的代码量,但是实际用处是很一般,静态导入的标准 ...
- Java基础——集合框架
Java的集合框架是Java中很重要的一环,Java平台提供了一个全新的集合框架.“集合框架”主要由一组用来操作对象的接口组成.不同接口描述一组不同数据类型.Java平台的完整集合框架如下图所示: 上 ...
- java基础---集合(1)
一. 基本概念 集合.数组都是对多个数据进行存储操作的结构,简称Java容器 数组:长度确定,类型确定,对于添加.删除.插入等操作效率不高,元素有序可重复 Java中集合框架顶层框架是:java.ut ...
- Java基础——集合源码解析 List List 接口
今天我们来学习集合的第一大体系 List. List 是一个接口,定义了一组元素是有序的.可重复的集合. List 继承自 Collection,较之 Collection,List 还添加了以下操作 ...
- Java基础—集合
一.概述 Java中的集合框架主要分为两大派别:Collection 和 Map —— 位于util包下 类的基础关系图如下(图片来自百度) 常用: List——有序可重复 Set——无序不可重复 M ...
- java基础集合简介Set(三)中
今天主要说夏set集合,每天抽出一个小时总结下,生活会更加美好! --< java.util >-- Set接口: 数据结构:数据的存储方式: Set接口中的方法和Collection中方 ...
- java基础集合经典训练题
第一题:要求产生10个随机的字符串,每一个字符串互相不重复,每一个字符串中组成的字符(a-zA-Z0-9)也不相同,每个字符串长度为10; 分析:*1.看到这个题目,或许你脑海中会想到很多方法,比如判 ...
- 十七、Java基础---------集合框架之Map
前两篇文章中介绍了Collection框架,今天来介绍一下Map集合,并用综合事例来演示. Map<K,V> Map<K,V>:Map存储的是键值对形式的元素,它的每一个元素, ...
- 十六、Java基础---------集合框架之Set
写在前面的话,这篇文章在昨天就写好了,今天打开的时候一不小心将第二天的文章粘贴到了这篇文章,很不幸的是除了标题之外依然面目全非,今天带着沉痛的心情再来写这篇文章! 上篇文章介绍了Collection体 ...
随机推荐
- idea配置javaweb项目(最新版)
idea(最新版)配置javaweb项目 本篇文章使用Maven构建javaweb环境 最新版maven压缩包 链接:https://pan.baidu.com/s/1El7b3YzPTZX-7QRE ...
- 基于雪花算法生成分布式ID(Java版)
SnowFlake算法原理介绍 在分布式系统中会将一个业务的系统部署到多台服务器上,用户随机访问其中一台,而之所以引入分布式系统就是为了让整个系统能够承载更大的访问量.诸如订单号这些我们需要它是全局唯 ...
- OpenResty搭建高性能服务端
OpenResty搭建高性能服务端 Socket编程 Linux Socket编程领域为了处理大量连接请求场景,需要使用非阻塞I/O和复用,select.poll.epoll是Linux API提 ...
- Go语言的函数07---闭包练习(ATM存取款)
package main import "fmt" /* @ATM(闭包练习) ·写一个Atm(函数),返回存款,取款两个内层函数 ·存款,取款两个函数,都以一个金额为参数,返回存 ...
- C# MVC(File)控件多张图片上传加预览
刚来公司实习,老板叫我写一个积分商城网站.用的是公司的框架结构搭建的后台,所以后台的图片上传不需要自己写.但是前台的评价图片就需要自己手写了,在网上找了很多代码发现都用不了.问了很多人也都没有实现! ...
- 2.5D Visual Sound:CVPR2019论文解析
2.5D Visual Sound:CVPR2019论文解析 论文链接: http://openaccess.thecvf.com/content_CVPR_2019/papers/Gao_2.5D_ ...
- ITS智能交通监控系统技术解析
ITS智能交通监控系统技术解析 红灯,逆行,变 车辆抓拍和车速检测 非法停车和交通流量检测 交叉路口违法检测 发生碰撞的交叉口是智能交通管理. 机动执法 当你需要一个可以移动的系统时,会跟着你移动.移 ...
- MySQL笔记01(黑马)
一.数据库基本介绍 目标:了解数据库的功能和常见数据库分类.数据库产品 数据库基本知识 数据库分类 SQL简介 MySQL访问 1.数据库基本知识 目标:了解数据库的概念和数据库的作用 概念 数据库: ...
- 1738. 找出第 K 大的异或坐标值
2021-05-19 LeetCode每日一题 链接:https://leetcode-cn.com/problems/find-kth-largest-xor-coordinate-value/ 标 ...
- 「模拟8.29」chinese(性质)·physics·chemistry(概率期望)
T1 chinese 根据他的问题i*f[i]我们容易联想到,答案其实是每种方案中每个点的贡献为1的加和 我们可以转变问题,每个点在所有方案的贡献 进而其实询问就是1-k的取值,有多少中方案再取个和 ...