[Java核心技术]第九章-集合(Java集合框架、具体的集合、映射)
9.1Java集合框架
一些有的没的
- 可以使用接口类型存放集合的引用。一旦改变了想法,只需要在调用构造函数的地方做一处修改。
- add方法用于向集合添加元素,如果添加元素确实改变了集合就返回true。
- tostring()方法用来调试。
迭代器
- 不同于C++,查找操作与迭代器的位置变更是紧密相连的,在执行查找操作的同时,迭代器的位置随之向前移动。
- Iterator接口的remove方法:删除上次访问的对象(即调用next方法时返回的元素)。
Queue、Deque extends Queue接口。(队列)
队列实现的两种方式的选择:
- 循环数组 ArrayDeque。优先选择,更高效。
- 链表 LinkedList。程序中要收集的对象数量没有上限时选择。
List接口
- List是一个有序集合
- 两种实现方式:数组、链表
- 测试一个集合是否支持高效的随机访问
if(c instanceof RandomAccess)
Set、SortedSet extends Set、NavigableSet extends SortedSet接口
- 基本等同于Collection接口,区别在于不允许重复。
- Set中的元素必须实现了equals和hashCode方法。
- SortedSet接口,提供用于排序的比较器对象,可以得到集合子集视图?
- NavigableSet接口,包含一些搜索和遍历有序集的方法。
9.2具体的集合
Part1 链表
LinkedList类(链表)
- 从数组中间删除元素代价很大
- Java中,所有的链表底层都是双向链表
ListIterator接口
- 链表和泛型集合重要区别,链表是一个有序集合。区别Collection.add和ListIterator.add。后者不返回boolean类型值,假定操作总会改变链表。后者在迭代器位置前插入listiter.next();listiter.add("hello");,前者在链表尾部插入。
- ListIteraror接口有两个方法,previous和hasPrevious(),用来反向遍历链表。
- 可以给容器附加很多个迭代器,但只能有一个可写可读的迭代器。如果一个迭代器发现它的集合被另一个迭代器/集合自身方法 修改了,就会抛异常。
- 检测并法修改问题的方法:每个迭代器维护一个独立的计数值,若发现与集合改写操作计数值不一致,则抛异常。
- 程序需要随机访问时,通常不选择链表。同时,尽量避免引用索引访问链表。
ArrayList类(数组列表)
ArrayList封装了一个动态再分配的数组对象。
需要动态数组时的选择
- Vector类的所有方法都是同步的,可以由两个线程安全的访问一个Vector对象。
- 不需要同步时使用ArrayList。
ArrayList的扩容机制
https://github.com/Snailclimb/JavaGuide/blob/master/docs/java/collection/ArrayList-Grow.md
默认构造函数,则初始为0,然后扩容为10,以后扩容为1.5+1倍。
Part2 集合
HashSet类(散列集)
- 放入其中的元素必须实现hashCode方法和equals方法。且两者兼容,即a.equals(b)==true则a与b必须具有相同的散列码。
- Java中,散列表用链表数组实现。每个列表称为桶。查找表中对象:计算它的散列码,然后与桶的总数取余,所得到的结果就是保存这个元素的桶的索引。散列表只在某个桶中查找元素,而不必查看集合中的所有元素。
- ASL,指查找算法的查找成功时的平均查找长度,是为确定记录在查找表中的位置,需和给定值进行比较的关键字个数的期望值。
- 散列冲突:指不同对象散列到相同的hashcode。解决方法如下,
- 开发定址法:例如线性探测再散列,即产生冲突后 原查找对象+1 再做hash ,若产生冲突,原查找对象+2 再做hash,直到找到空的地方。
- 再哈希法:即产生冲突后用第二种hash函数。
- 链地址法:Java中HashSet采用这种方法。
- 建立一个公共溢出区:冲突的都放在公共溢出区。
- 桶满时,会发生散列冲突。Java 中,桶满时会从链表变为平衡二叉树。
- 设置桶数:如果大致知道要有多少个元素插入散列表,就可以设置桶数。通常设置为预计元素的75%-150%。标准类库使用的桶数是2的幂,默认值16。
- 装填因子决定何时对散列表进行再散列(创建一个桶数更多的表,将所有元素插入新表,丢弃原来的表):默认值0.75,超过75%的位置已经填入元素后,会用双倍的桶数进行再散列。
- JDK1.8 以后的 HashMap 在解决哈希冲突时有了较大的变化,当链表长度大于阈值(默认为8)时,将链表转化为红黑树,以减少搜索时间。
- HashSet如何检查重复:当你把对象加入HashSet时,HashSet会先计算对象的hashcode值来判断对象加入的位置,同时也会与其他加入的对象的hashcode值作比较,如果没有相符的hashcode,HashSet会假设对象没有重复出现。但是如果发现有相同hashcode值的对象,这时会调用equals()方法来检查hashcode相等的对象是否真的相同。如果两者相同,HashSet就不会让加入操作成功。
- ==与equals的区别
==是判断两个变量或实例是不是指向同一个内存空间 equals是判断两个变量或实例所指向的内存空间的值是不是相同
==是指对内存地址进行比较 equals()是对字符串的内容进行比较
==指引用是否相同 equals()指的是值是否相同 - HashMap的数组长度为什么是必须是2的幂次
散列值用之前还要先做对数组的长度取模运算,得到的余数才能用来要存放的位置也就是对应的数组下标。但源码中这个数组下标的计算方法是“ (n - 1) & hash”。(n代表数组长度)。
因为当length是2的幂,有 hash%length==hash&(length-1)。
且&操作相对于%能够提高运算效率。
TreeSet类
- TreeSet是有序集合,对集合进行遍历时,每个值自动地安排序后的顺序呈现。底层使用红黑树实现。元素必须实现Comparable接口,或调构造函数时传入comparator对象。
- 性能:TreeSet添加元素比添加到HashSet慢。
- TreeSet与HashSet的选择:如果需要排序,再使用TreeSet,因为有额外开销。
SortedSet extends Set ,接口
NavigableSet extands SortedSet, 接口
扩展了SortedSet,具有了搜索匹配元素的方法。
Part3 队列
ArrayDeque implements Deque ,类;LinkedList implements Deque ,类
- 以上两个类实现了双端队列,并都可无限长度。ArrayDeque默认初始容量16。
- java.util.Queue 方法
- 入队 add/offer 抛异常/返回false
- 出队 remove/poll 抛异常/返回null
- 获得队首元素 element/peek 抛异常/返回null
- java.util.deque 方法
- addFrist/addLast
- 其他形式同上
PriorityQueue类
- 优先队列,底层实现堆。。堆是一个可以自我调整的二叉树,对堆执行add和remove操作,可以让最小的元素移动到根,而不必花费时间对元素进行排序。
- 优先级队列中元素必须实现Comparable接口,或构造器中提供实现了Comparator接口的对象。
- 使用优先级队列的典型示例是任务调度。
Part* 哈希表、红黑树、堆时间复杂度
哈希表:查找、插入、删除均为O(1)
堆:得到最大值最小值O(1)、插入删除O(logn)
红黑树:查找、插入、删除均为O(logn)
9.3 映射
基本操作
- get、put、containsKey
遍历map
scores.foreach(
(k, v)->{
//do something with k,v
}
);
更新value???
counts.merge(word,1,Integer::sum);
完成+1操作。word原来不存在也可以处理,不会出错。
映射的视图:是实现了Collection接口或某个子接口的对象。
Set<K> keySet() //key集合
Collection<V> values() //value集合
Set<Map.Entry<K,V>> entrySet() //key value 集合
例
Set<String> keys=map.keySet();
[Java核心技术]第九章-集合(Java集合框架、具体的集合、映射)的更多相关文章
- [Java核心技术]第九章-集合(映射-HashMap&TreeMap)
HashMap 基本操作 HashMap<Integer,Integer> firstAccurMap=new HashMap<Integer,Integer>(); firs ...
- “全栈2019”Java多线程第九章:判断线程是否存活isAlive()详解
难度 初级 学习时间 10分钟 适合人群 零基础 开发语言 Java 开发环境 JDK v11 IntelliJ IDEA v2018.3 文章原文链接 "全栈2019"Java多 ...
- “全栈2019”Java异常第九章:throws关键字详解
难度 初级 学习时间 10分钟 适合人群 零基础 开发语言 Java 开发环境 JDK v11 IntelliJ IDEA v2018.3 文章原文链接 "全栈2019"Java异 ...
- JAVA基础第一章-初识java
业内经常说的一句话是不要重复造轮子,但是有时候,只有自己造一个轮子了,才会深刻明白什么样的轮子适合山路,什么样的轮子适合平地! 从今天开始,我将会持续更新java基础知识,欢迎关注. java的诞生 ...
- 深入理解java虚拟机-第二章:java内存区域与内存泄露异常
2.1概述: java将内存的管理(主要是回收工作),交由jvm管理,确实很省事,但是一点jvm因内存出现问题,排查起来将会很困难,为了能够成为独当一面的大牛呢,自然要了解vm是怎么去使用内存的. 2 ...
- 学习java随笔第九篇:java异常处理
在java中的异常处理和c#中的异常处理是一样的都是用try-catch语句. 基本语法如下 try { //此处是可能出现异常的代码 } catch(Exception e) { //此处是如果发生 ...
- JAVA基础第二章-java三大特性:封装、继承、多态
业内经常说的一句话是不要重复造轮子,但是有时候,只有自己造一个轮子了,才会深刻明白什么样的轮子适合山路,什么样的轮子适合平地! 我将会持续更新java基础知识,欢迎关注. 往期章节: JAVA基础第一 ...
- Java核心技术点之集合框架
1. 概述 Java集合框架由Java类库的一系列接口.抽象类以及具体实现类组成.我们这里所说的集合就是把一组对象组织到一起,然后再根据不同的需求操纵这些数据.集合类型就是容纳这些对象的一个容 ...
- Java核心技术卷一基础技术-第13章-集合-读书笔记
第13章 集合 本章内容: * 集合接口 * 具体的集合 * 集合框架 * 算法 * 遗留的集合 13.1 集合接口 Enumeration接口提供了一种用于访问任意容器中各个元素的抽象机制. 13. ...
随机推荐
- 【特别篇】不为人知的U盘秘密
U盘是我们代码爱好者的必要东西,方便于我们更好的拷文件,使用一些已经配置好的东西,比如说:小编经常会将linux系统放进去,平时就可以随时用了. But 你的U盘真的正常吗?你了解多少? 关于U盘 ...
- Kubernetes实战指南(三十三):都0202了,你还在手写k8s的yaml文件?
目录 1. k8s的yaml文件到底有多复杂 2. 基于图形化的方式自动生成yaml 2.1 k8s图形化管理工具Ratel安装 2.2 使用Ratel创建生成yaml文件 2.2.1 基本配置 2. ...
- idea生成SpringBoot项目后再次调出依赖
插眼 https://www.cnblogs.com/cosmos-wong/p/12908580.html
- 如何选择一台适合Java开发的电脑
前言 最近在群里有同学求推荐Java开发用的电脑,所以胖哥就出个简单的专题,用我贫瘠的电脑知识来帮助大家选择适合开发的电脑配置.因为家里的主机已经带不动两个 IDEA 了,更别提开个 Docker 啥 ...
- 对于CSS里面我之前不太清楚的伪类,我做一些总结
格式: 标签 + : + 参数 +{ 可填背景颜色,字体颜色,鼠标样式,加粗等 } a:hover{ color:#f40;} :link表示鼠标点击之前的样式 :hover表示鼠标放上去的样式 :a ...
- 个人项目WC.exe Node.js+electron实现
前言 实现语言:Javascript 编译工具:webstorm GitHub:https://github.com/NPjuan/WC.git 项目要求 wc.exe 是一个常见的工具,它能统计文本 ...
- Jmeter+Ant+jenkins实现api自动化测试的持续集成
0基础上手教程 @jmeter的使用 jmeter是一个基于java语言编写的开源测试工具,广泛应用于接口测试,性能测试,自动化测试. 接口自动化的编写教程,将于后续分享. 问题一:为什么用ant,而 ...
- .NET Core3.1 Dotnetty实战第三章
一.概要 本章主要内容就是讲解如何在dotnetty的框架中进行网络通讯以及编解码对象.数据包分包拆包的相关知识点. 后续会专门开一篇避坑的文章,主要会描述在使用dotnetty的框架时会遇到的哪些问 ...
- 洛谷 P4343 [SHOI2015]自动刷题机
思路 二分答案 显然的二分答案,但是因为二分判定条件 \(\text{wa}\) 了好几遍-- 可以发现,\(n\) 越大,\(k\) 就越小,所以答案是有单调性的,因此可以用两个二分,一次求最大值, ...
- Vue开源项目使用探索
前言 本文记录一次使用Vue开源项目的过程. 寻找Vue开源项目 要使用Vue开源项目就必须先找到一个,我们去Github上搜索[后台],然后使用Vue分类进行检索,找到排名第一的开源框架进行下载—v ...