数组的特点
1.数组中保存的元素都是有序的,可以通过下标快速访问.
2.数组中保存的数据必须是同一类型(可以通过创建object数组实现数据类型不同)
3.数组的长度在定义后无法更改
4.数组无法获取其中保存元素实际数量
集合的特点
1.能保存一组数据,可以有序也可以无序.
2.集合容量可变
3.集合中可以保存不同类型的数据
4.可以获取集合中保存的元素实际数量
集合框架(集合家族)
Collection还有父接口Iterable,但Iterable接口不算严格意义上的集合的根接口,它称为迭代器,是用于与遍历集合元素的一个工具接口,所以集合的根接口为Collection接口和Map接口,位于java.util包中
以上所有实现类都是线程不安全的,在多线程环境下使用,都会产生不确定的结果
Collection接口
该接口有两个子接口,List与Set.
这两个接口都可以保存一组数据.
List接口保存数据时,是有序可重复的.
Set接口保存数据时,是无序不重复的.
常用方法 | 返回值 | 作用 |
---|---|---|
add(E e) | boolean | 將元素添加到集合末尾,返回添加是否成功 |
size() | int | 返回集合元素数量 |
isEmpty() | boolean | 判断元素是否为空 |
clear() | void | 清空集合 |
contains(Object obj) | boolean | 判断集合中是否存在指定的元素 |
remove(Object obj) | boolean | 移除集合中指定元素,返回是否成功 |
toArray() | Object[ ] | 将集合转换为数组 |
iterator() | iterator | 获取该集合的迭代器对象,用于遍历集合 |
List接口(有序可重复)
有序集合,元素可以重复,允许保存null,可以通过索引获取对应位置上的元素.
在该接口中又定义了一些操作元素的方法.具体如下:
常用方法 | 返回值 | 作用 |
---|---|---|
get(int index) | Objec | 返会指定索引(index)的元素 |
set(int index,Objec obj) | Objec | 替换集合中指定索引的元素,返回被替换的元素 |
add(int index ,Objec obj) | void | 在指定位置(idnex)上添加元素 |
remove(int index) | Objec | 删除指定索引的元素,并且返回该元素,同时该索引之后的元素自动向前移动一位 |
indexOf(Objec obj) | int | 得到某元素第一次出现的索引,没有返回-1 |
lastIndexOf(Objec obj) | int | 得到某元素最后一次出现的索引,没有返回-1 |
subList(int from, int to) | List | 截取索引为(from,to)区间的元素 |
以上Collection与List接口中的方法在ArrayList中都有实现
ArrayList实现类
1.采用数组实现的集合
2.可以通过索引访问元素,可以改变集合大小,如果要在其中插入或删除元素时,会影响后续元素,
3.该集合中保存的都是引用类型,即便保存了数字123,也是保存的对应类型的包装类对象
4.该集合查询效率高,中途添加和删除效率低.
构造方法
常用构造方法 | 作用 |
---|---|
ArrayList(int initialCapacity) | initialCapacity:指定长度的初始值,创建一个指定容量的Object数组 |
ArrayList() | 不带参创建时,创建一个Object类型的空数组,在调用添加方法后才会更改数组大小为10 |
LinkedList实现类
采用了双向链实现集合
集合中保存的每个元素也成为节点,除首尾节点外,其余节点都保存了自己的信息外,还保存了其前一个和后一个节点的地址
在双向链表的数据结构中插入或删除操作节点时,不会影响其他节点的未知,如添加新节点时,只需要重新定义新节点的前后节点位置即可
如果要查询某个节点是,需要从首节点或尾节点开始一步步得到节点的位置
双向链表的插入和删除效率高,查询效率低
构造方法
常用构造方法 | 说明 |
---|---|
LinkedList() | 创建一个空链表 |
常用方法
由于LinkedList即实现了List接口又实现了Deque接口,所以还有Deque接口中的一些方法
可参考List与Collection的常用方法
实现Deque接口的方法 | 返回值 | 作用 |
---|---|---|
addFirst(E e) | boolean | 添加指定元素在链表首位 |
addLast(E e) | boolean | 添加指定元素在链表末位 |
getFirst() | E | 获取首位节点的元素 |
getLast() | E | 获取尾位节点的元素 |
removeFirst() | E | 移除首节点,返回被移除的元素 |
removeLast() | E | 移除尾节点,返回被移除的元素 |
remove() | E | 移除首节点,实际调用的removeFirst() |
pop() | E | 移除首节点,实际调用的removeFirst() |
push(E e) | void | 添加首节点,实际调用的addFirst() |
peek() | E | 获取首位节点的元素 |
poll() | E | 移除首节点,返回被移除的元素 |
offer(E e) | boolean | 添加指定元素在链表末位 |
ArrayList与LinkedList的的区别
1.都是List接口的实现类,保存的元素有序可重复,运行需保存null
2.ArrayList采用的时数组实现,随机读取效率高,插入删除效率低,常用于查询
3.LinkedList采用双向链表实现,插入删除时不影响其他元素,随机读取效率低,常用于频繁更新集合的情况
Set接口(无序不重复)
无序集合,元素不可以重复,允许保存一个null,没有索引
Set接口中没有自己定义的方法,都是继承于Collection接口中的方法(具体参照Collection常用方法)
要保存的数据称为原始值,这个原始值通过一个函数得到一个新的数据,这个函数称为哈希函数,这个新数据称为哈希码,哈希码和原始值之间有一个映射关系,这个关系称为哈希映射,可以构造一张映射表,这个表称为哈希表,在哈希表中,可以通过哈希码快速的访问对应的原始值
假设原本的数据为左侧的数组,如果要查询10,则需要遍历数组,效率不高
通过一个特定的函数 原始值%5 ,得到一组新数据,让心数据重新对应元素,保存到新数组中,这时如果要查询10,由于哈希函数是通过%5得到了0,所以直接查询哈希表中0对应的元素即可.
整个过程中,这个函数称为哈希函数,的打斗的新数据称为哈希码,新数组称为哈希表,对应关系成为哈希映射
这个哈希函数,有一定的机率让多个原始值得到相同的哈下,这种情况称为哈希冲突(哈希码一致,实际值不同)
为了解决哈希冲突,可以使用 拉链法 ,将2这个哈希码所在的位置向链表一样进行延申.
哈希码的特点
1.如果两个对象的hashCode不同,这两个对象一定不同
2.如果两个对象的hashCode相同,这两个对象不一定相同
1) hashCode相同,对象不同,这种现象称为哈希冲突 如:"通话"与"重
地"的 hashCode 相同,但是不是一个对象
HaseSet实现类
常用构造方法 | 作用 |
---|---|
HaseSet() | 实际上是new了一个HashMap类 |
HaseSet没有自定义的方法,常用方法参考父接口Collection中的方法
TreeSet实现类
特殊的Set实现类,数据可以有序的保存,可以重复,不能添加null
采用红黑树(自平衡二叉树)实现的集合,比根节点大的在右侧,比根节点小的在左侧,他会尽量的保持两端的平衡,自适应的调节根节点.
只能添加同一种类型的对象,且该类型实现了Comparable接口
每次添加时,都会调用该参数的comparableTo方法
comparableTo方法的返回值决定了是否可以添加新元素和新元素的位置
负数,将新元素添加到现有元素之后(新元素比现有元素小)
0,视为与现有元素为同一个元素,不能重复添加
正数,将新元素添加到现有元素之前(新元素比现有元素大)
具体的大小判断取决于该对象重写的comparableTo方法内容
构造方法
常用构造方法 | 说明 |
---|---|
TreeSet() | 无参构造方法,创建一个空的集合,实际是船舰了一个TreeMap对象 |
常用方法
属于Ser的实现类,所以能使用Collection和Set中的方法
常用方法 | 作用 | |
---|---|---|
fisrt() | 得到集合中的第一个元素 | |
last() | 得到集合中的第一个元素 | |
cell(Object obj) | 得到比指定元素obj大的元素中的最小元素 | |
floor(Object obj) | 得到比指定元素obj小的元素中的最大元素 |
Map接口
Map称为映射,是使用键值对的方式存元素的集合,键称为Key,值称为Value,键不能重复,允许出现一个null作为键,值没有限制
保存的是键与值的对应关系
其中键和值都是引用类型
常用方法
常用方法 | 作用 | |
---|---|---|
size() | 得到键值对的数量 | |
clear() | 清空该集合(清空所有键值对关系) | |
put(Object key,Object value) | 向集合中添加一组键值对 | |
get(Object key) | 根据键得到值 | |
remove(Object key)/(Object key,Object value) | 根据键或键值对 移除对应的键值对 | |
keySet() | 获取键的集合 | |
valueSet() | 获取值的集合 | |
containsKey(Object obj) | 判断集合中是否有obj键 | |
containsValue(Object obj) | 判断集合中是否有value值 | |
entrySet() | 得到所有键值对集合 |
遍历Map集合
使用valueSet()获取所有键的一个Set集合,然后通过变脸键的集合通过 get方法遍历集合所有内容
Set<String> keySey = USER_MAP.keySet();
for (String string : keySey) {
System.out.println(USER_MAP.get(string );
}
使用entrySet()方法,得到当前HashMap对象中所有键值对集合.
for (Map.Entry<String, User> entry : USER_MAP.entrySet()) {
System.out.println(entry);
}
HashMap实现类
HashMap ---> jdk.1.8之后,采用"数组","链表","红黑树"实现
当没有哈希冲突时,元素保存在数组中
如果出现哈希冲突,在对应的位置上创建一个链表,保存冲突的元素地址,元素保存到链表中
如果链表长度大于8,将链表转换为红黑树
常用构造方法 | 作用 | |
---|---|---|
HashMap() | 新建一个默认大小为16,阈值为0.75的空集合 | |
HashMap(int initialCapacity) | 新建一个自定大小,阈值为0.75的空集合 |
遍历集合元素的方式
遍历List集合的三种方式
List <String> stringList = new ArrayList();
stringList.add("张三");
stringList.add("李四");
stringList.add("王五");
stringList.add("赵六");
//方式一:普通for循环
for (int i = 0; i < stringList.size(); i++) {
//根据get(下标)依次输出元素
String name = stringList.get(i);
System.out.println(name);
}
//方式二:增强for循环
for (String s : stringList) {
System.out.println(s);
}
//方式三:获取迭代器对象----> 任何集合对象.iterator();
Iterator<String> stringIterator = stringList.iterator();
//判断是否存在下一个元素
System.out.println(stringIterator.hasNext());
//获取下一个元素,如果没有下一个元素时抛出NoSuchElementException异常
System.out.println(stringIterator.next());
//遍历方式,使用迭代器遍历
while (stringIterator.hasNext()){
String name = stringIterator.next();
System.out.println(name);
}
遍历Set集合只能使用迭代器与增强for循环
Set<String> set= new HashSet();
set.add("张三");
set.add("李四");
set.add("王五");
set.add("赵六");
//方式一:增强for循环
for (String s : set) {
System.out.println(s);
}
//方式:获取迭代器对象----> 任何集合对象.iterator();
Iterator<String> stringIterator = ssetiterator();
//判断是否存在下一个元素
System.out.println(stringIterator.hasNext());
//获取下一个元素,如果没有下一个元素时抛出NoSuchElementException异常
System.out.println(stringIterator.next());
//遍历方式,使用迭代器遍历
while (stringIterator.hasNext()){
String name = stringIterator.next();
System.out.println(name);
}
Collections集合工具类
常用方法 | 作用 |
---|---|
shuffle(List list) | 随机打乱list的顺序 |
swap(List list,int i, int j) | 交换list中索引i和索引j的位置 |
replaceAll(List list,T old, T new) | 将list中所有的old元素替换为new元素 |
sort(List list) | 将list进行comparableTo排序(必须实现comparable接口) |
reverse(List list) | 将list的元素顺序反转 |
fill(List list,T t) | 使用指定元素 填充List集合 |
rotate(List list,int n) | 将集合中最后n个元素放在最前 |
max/min(Collection col) | 得到集合中的最大最小值(必须实现comparable接口) |
集合与数组之间的转换
集合----->>数组 使用toArray()方法
数组----->>集合 使用Arrays工具类中的asList(一组数)方法
当asList(),参数是数组是,方法的泛型将会变成数组,所以使用参数是一个数组时,会转换成一个长度为一的,集合[0]的值是数组的集合.