java集合框架共有三大类接口:List,Set,Map
List接口:存储一组不唯一,有序的对象
ArrayList类实现了长度可变的数组,在内存中分配连续的空间,遍历元素和随机访问元素的效率比较高
LinkedList类采用链条表存储方法,插入,删除元素时效率高
ArrayList常用的方法
LinkedList常用方法
ArrayList与LinkedList对比
ArrayList和LinkedList分别在何时使用?
AttayList:
遍历元素和随机访问元素的效率比较高
插入,删除等操作频率时性能低下
LinkedList:
插入,删除元素时效率较高
查找效率低
Set接口
Set接口存储一组,唯一,无序的对象
HashSet 是Set接口常用的实现类
HashSet允许集合元素值为null
操作数据的方法与List相似,Set接口不存在get()方法
Iterator:
Iterator接口表示对集合进行迭代的迭代器,专门实现集合的遍历
方法:
hasNext();判断是否存在另一个可访问的元素
next();返回要访问的下一个元素
HashMap:
HashMap是Map接口最常见的实现类
HashMap如何存储数据,有什么优势;
存储一组成对的键值对象,提供key(键)到value(值)的映射,通过key来索引
key不允许重复
value允许重复
添加的对象将转换为Object类型
HashMap的常用方法
Collections类
Collections和Collection不同,前者是集合的操作类,后者是集合接口
Collections提供的静态方法
sort():排序
binarySearch();查找
fill();替换
集合
一、概念
就是各种工具类,方便开发
三大接口: List 、 Set、 Map
这三种接口的数据结构是不一样的
长度可变的数组 链条(单项和双向)hash表(数组+链表+红黑树)
红黑树:自平衡二叉树
二叉树:一分二、二分四、四分八一种数据结构
java编程思想,数据结构学习
二、API
要会查API文档
类似于字典
java。util就是工具包的意思
List放在util的意思就是这个接口就是个工具,开发的时候可以使用。
学会用里面的方法,然后学习底层
三、List接口;
List存储一组不唯一,有序的元素
不唯一:同一个元素可以添加多次
有序:先添加的在前面,后添加的在后面
因为他是一个数组
ArrayList
直译:数组集合
底层是一个长度可变的数组
以后不在使用数组,因为数组长度是固定的
实例化的时候,创建一个空的,初始长度是10的集合。
加减乘除经过CPU,左移右移不经过CPU,
List:存储不唯一元素可以重复,有序
ArrayList常见方法:"
add(E e):E 泛型,可以添加任意类型的数据
list可以添加任何类型的数据
添加的数据最好是一致的
add(intindex,E element);把元素放在集合的指定位置
addAll:用的非常少,一个元素添加到另外一个集合中
clear();清空数组中的所有元素
clone():克隆,拷贝,把一个数组中的元素,拷贝一份放在另外一个集合中.
get(int index):返回指定位置的元素
//contains判断集合中是否有这个元素
indexof(Object o) 返回元素的下标,如果不存在返回-1,存在返回查到的重复的第一个元素
isEmpty:是空的,如果是空的返回true,判断集合是否为空
lastlindex()返回最后一个元素的下标
remove()移除下标
size()元素的长度,集合中有集合元素
subList() 截取集合,sub的意思就在子的意思
toArray()把集合转换为数组
ArrayList:优点,空间连续的,有下标,
修改和查找慢
缺点:删除和新增慢
删除第一个元素,从第二个元素往前移所以很慢
LinkedList:
也是List,一定符合:元素不唯一,有序
LinkedList的底层数据结构跟ArrayList的不一样
缺点:查找比较慢,找一个需要寻址
优点,删除和新增快,没有涉及到元素的移动,直接改指针即可
什么时候使用合适的集合?
如果新增和删除较多,使用LinkedlIst
如果查找和修改较多,使用ArrayList
开发中基本都是使用ArrayList
Set接口:
set也是一个集合,用来存放一组唯一,无序
唯一:相同的元素只能存放成功一次,也可以存放相同的,但是会被覆盖,只能输出一次
无序,不是按照先后信息存放的
它的底层是HashMap
HashSet的底层结构:
唯一:
无序:
最终转换为json类型在给前端
不需要删除和新增
LinkedList方法:
当我们new HashSet的时候,底层new了一个HashMap
想set中添加元素的时候,底层想map中添加了一个元素
想搞清楚HashSet,先搞清楚HashMap
HashMap的底层
从上面的代码可以看出,HashMap是由数组+链表+红黑树组成的
jdk1.7之前,HashMap由数组+链表组成
1.8(包含)之后HashMap由数组+链表+红黑树
数组经过hash运算后可能或有重复的值,就形成了链表到达8之后会自动转换为红黑树
1亿条数据算出来红黑树多少层.Math.pow(2,i)>=10000000
链表长度大于8之后,这个链条会自动变成红黑树
这样做得目的是提高查询效率
红黑树可以根据左旋,右旋,减少两边的深度差
如果我们不人为干涉,二叉树可能是链表结构
可以通过左旋,或者右旋,让这个二叉树变成一个平衡的二叉树
红黑树就是平衡的二叉树
0.75是到75%扩容初始值16
HashMap为什么有数组和链表.而不是单纯的数组?
为了解决Hash冲撞问题
我们要能明白一个问题.想Hashmap放值得逻辑是什么?
根据key,计算hash值,在根据hash值除以数组的长度,取余数
余数就是要存放的下标
例子:map.put("孙悟空")
根据孙悟空字符串算出hash值,值除以16取余数,余数一定是0-15
假设余数是10,那么下标就放在10的位置
如果元素数量到达数组的75%会自动扩容,(假设原来16,现在是32)
所有的元素都要rehash(重新计算hash值)
hash值要除以新的容量(32)取余数,要保证新增的下标和旧的下标保持一致
例子:map.put("孙悟空")
得到一个hash值,hash值除以16取余数,假设余数是10
过一会扩容了,容量变成了32
再计算hash除以32,取余数,还要保证这个余数正好是10
hash冲撞
map.put(""大师兄,"孙悟空") | 可能=10
map.put(""二师兄,"猪八戒") | 可能=10
如果不做处理,那么这两个元素可能放在同一个位置,后面的元素必定覆盖前面的元素
为了解决这个问题,就引入了列表
大师兄就放在链表的第一个节点,二师兄就放在第二个节点
这就是数组加链条
最后加红黑树
Set 唯一,链表集合
1.HashSet常用方法
//HashSet无序
//HashTreeSet有序,自然升序/查找效率高
//LinkedHashSet可以保证插入的顺序和遍历的循序一致
HashSet set = new HashSet();
set.add();//将指定的元素添加到集合(如果尚未存在)
set.clear()//从此集合中删除所有元素
set.clone();//返回此,HashSet实例的浅层副本,元素本身不被克隆
set.contains();//如果此集合包含指定的元素,则返回true
set.isEmapty()//如果此集合不包含元素,则返回true
set.iterator()//返回此集合中元素的迭代器
set.remove();//如果存在,则从该集合中删除指定的元素
set.size();返回此集合中的元素数(其基数)
set.spLiterator();在此集合中的元素尚创建Iate-binding和故障快速Spliteratior
2.HashMap的常用方法
//无序 k值惟一,不重复
v值可以重复,
HashMap<String> hp = new HashMap<>();
hp.clear();//从这张地图中删除所有映射
hp.cloont();//返回此,HashMap实例的浅拷贝,键和值本身不被克隆
hp.compute();//尝试计算用于指定键和当前
3.复习HashMap list底层数组结构
list底层数据结构//不唯一,允许重复,有序
ArrayList底层是基于数组实现的查找和修改快
LinkedList基于链表实现,新增和删除快,
Set底层数据结构/唯一,不允许重复,无序
基于hashmap实现的
HashSet,,唯一
TreeSet有序的,自然升序,查找快
LinkedHashSet可以保证插入的循序和遍历的顺序是一致的
Map<K,v>k值是唯一,不重复
v是可以重复的,是成对出现的
HashMap线程不安全,无序
TreeMap有序,自然升序基于红黑树实现的Map接口
LinkedHashmap
泛型:
什么是泛型;
在实例化集合的时候,最好给集合对象指定类型,如果不指定类型的话,集合中的元素都会默认向上转型成Object这样比较麻烦.