此文包含Java中所有集合知识点:使用方式和代码,还有各种注意事项
集合
一、类集概述
集合是数据的容器。 java 对数据结构成熟的实现。
Collection和Map是同一级的,一个是单值存储,一个是双值存储,接下来的内容中会重点学习。

链表和二叉树都属于数据结构。
前期Java程序员不需要过于关注数据结构,因为Java内置了一套成熟的数据结构
二、链表和二叉树
1、链表
链表节点
class Node {
Object data;
Node next;
}
链表,linked list:按特定的顺序链接在一起的抽象数据类型。
-
数组的优点
- 存取速度快
-
数组的缺点:
- 事先必须知道数组的长度
- 插入删除元素很慢
- 空间通常是有限制的
- 需要大块连续的内存块
- 插入删除元素的效率很低
-
链表的优点
- 空间没有限制
- 插入删除元素很快
-
链表的缺点
- 存取速度很慢
-
可以通过练习编写链表的增删遍历代码对链表进行深入了解。
2、二叉树

链表只有下一个,二叉树有左下一个和右下一个。
二叉树节点
class Node {
Object data;
Node left;
Node right;
}
通常二叉树都是有序的,根节点向下分叉,存储的数据与根节点作比较,比根节点小存到左下,反之存到右下。之后每存储一个数据就按照这个存储顺序依次向下分叉。
-
二叉树的遍历方式
-
先序遍历
先访问根节点,然后访问左节点,最后访问右节点,顺序:中左右
-
中序遍历
先访问左节点,然后访问根节点,最后访问右节点,顺序:左中右
-
后序遍历
先访问左节点,然后访问右节点,最后访问根节点,顺序:左右中
-
-
可以通过练习编写二叉树的遍历代码对二叉树进行深入了解。
三、常见数据结构
数据存储常用结构有:栈、队列、数组、链表和红黑树。
1、栈
stack,又称堆栈,是一种限定存储的结构。限定仅在整个结构的尾部进行添加、删除操作的线性表。
特点:
- 先进后出:例如将子弹压入弹夹之中,先压进去的子弹在下面,后压进去的子弹在上面,开枪时先弹出上面的子弹,后弹出下面的子弹。
- 栈的入口和出口都是栈的顶端位置
此处有两个名词:
-
压栈:存元素
-
弹栈:取元素
栈在Java类集中用得不多。
2、队列
queue,就像排队,先排的先走。队列是一种特殊的线性表,只允许在表的一端插入,另一端删除。
特点:
- 先进先出:例如火车过山洞,车头先进去、车尾后进去;车头先出来,车尾后出来。
- 队列的入口、出口各占一侧。有单端队列和双端队列。
3、数组
Array,有序的元素序列。
特点:
- 查找元素通过索引找,特别快。
- 增删元素慢:需要创建新的数组,根据下标进行增加和删除,进行数据的移动
4、链表
linked list,由一系列节点node组成,每一个节点除了要存储数据,还要存储下一个节点的位置,像一个链链接起来。分为单向、双向链表和单向、双向循环链表。
特点:
- 查找元素慢:依次查找
- 增删元素快:只需要修改连接下个元素的地址
5、红黑树
二叉树:binary tree,每个节点不超过2的有序树。红黑树又称平衡二叉树。
特点:
-
尽量保持平衡,不会将数据只存在一端
-
速度特别快,趋近于平衡,查找叶子元素最少和最多次数不多于二倍
四、Collection接口(重点)
单值存储从此处开始。
在整个 Java 类集中保存单值的最大操作父接口,里面每次操作的时候都只能保存一个对象的数据。此接口定义在 java.util 包中。单值存储。用得最多的是List和Set接口。
Collection接口的常用方法:
| No. | 方法名称 | 类型 | 描述 |
|---|---|---|---|
| 1 | public booleanadd(Ee) | 普通 | 向集合中插入一个元素 |
| 2 | public boolean addAll(Collection<?extends E> c) | 普通 | 向集合中插入一组元素 |
| 3 | public void clear() | 普通 | 清空集合中的元素 |
| 4 | public boolean contains(Object o) | 普通 | 查找一个元素是否存在 |
| 5 | public boolean containsAll(Collection<?> c) | 普通 | 查找一组元素是否存在 |
| 6 | public boolean isEmpty() | 普通 | 判断集合是否为空 |
| 7 | public Iterator<E> iterator() | 普通 | 为 Iterator 接口实例化 |
| 8 | public boolean remove(Object o) | 普通 | 从集合中删除一个对象 |
| 9 | boolean removeAll(Collection<?> c) | 普通 | 从集合中删除一组对象 |
| 10 | boolean retainAll(Collection<?> c) | 普通 | 判断是否没有指定的集合 |
| 11 | public intsize() | 普通 | 求出集合中元素的个数 |
| 12 | public Object[] toArray() | 普通 | 以对象数组的形式返回集合中的全部内容 |
| 13 | <T>T[]toArray(T[] a) | 普通 | 指定操作的泛型类型,并把内容返回 |
| 14 | public boolean equals(Object o) | 普通 | 从 Object 类中覆写而来 |
| 15 | public int hashCode() | 普通 | 从 Object 类中覆写而来 |
-
为什么要学习集合?
因为集合是Java中成熟的数据结构的实现,使用集合可以更合理地存储数据。便于对数据更好地进行管理。
1、List接口(重点)
List中所有的内容都允许重复。
对接口Collection的扩充方法:
| No. | 方法名称 | 类型 | 描述 |
|---|---|---|---|
| 1 | public void add(int index,E element) | 普通 | 在指定位置处增加元素 |
| 2 | boolean addAll(int index,Collection<?extends E>c) | 普通 | 在指定位置处增加一组元素 |
| 3 | public E get(int index) | 普通 | 根据索引位置取出每一个元素 |
| 4 | public int indexOf(Object o) | 普通 | 根据对象查找指定的位置,找不到返回-1 |
| 5 | public int lastIndexOf(Object o) | 普通 | 从后面向前查找位置,找不到返回-1 |
| 6 | public List Iterator<E> list Iterator() | 普通 | 返回 List Iterator |
| 7 | public List Iterator<E> listIterator(int index) | 普通 | 返回从指定位置的 ListIterator 接口的实例 |
| 8 | public E remove(int index) | 普通 | 删除指定位置的内容 |
| 9 | public E set(int index,E element) | 普通 | 修改指定位置的内容 |
| 10 | List<E> subList(int fromIndex,int toIndex) | 普通 | 返回子集合 |
-
List中有许多实现类:ArrayList、Vector和LinkedList(双向链表)。
Vector是ArrayList早期实现,ArrayList线程不安全,Vector线程安全。(线程后续学习)
1.ArrayList集合(重点)
ArrayList是List接口的子类:有序、可重复。使用数组结构,增删慢、查找快。
创建数组:
ArrayList<Integer> data = new ArrayList<>();
接下来查看ArrayList的源码,我们看到ArrayList创建的数组,初始值为一个常量。
/**
* Constructs an empty list with an initial capacity of ten.
*/
public ArrayList() {
this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA;
}
再点进去这个常量,我们看到它是一个长度为0的数组。
/**
* Shared empty array instance used for default sized empty instances. We
* distinguish this from EMPTY_ELEMENTDATA to know how much to inflate when
* first element is added.
*/
private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {
};
**添加数据:**用上面的data调用add方法
data.add(100);
- 存储时需要存储Integer类型数据,传入的int型会自动装箱为Integer类型数据。此时数组长度为0,若想存储数据,需要进行扩容,而add就对数据进行扩容操作。
点开add源码,结果return的是true。
/**
* Appends the specified element to the end of this list.
*
* @param e element to be appended to this list
* @return {@code true} (as specified by {@link Collection#add})
*/
public boolean add(E e) {
modCount++;
add(e, elementData, size);
return true;
}
- 只要调用add方法,永远返回true。
再点开add中传入3个参数的add方法:
/**
* This helper method split out from add(E) to keep method
* bytecode size under 35 (the -XX:MaxInlineSize default value),
* which helps when add(E) is called in a C1-compiled loop.
*/
private void add(E e, Object[] elementData, int s) {
if (s == elementData.length)
elementData = grow();
elementData[s] = e;
size = s + 1;
}
- 如果目前寸的数据和数组长度一致,说明存满了,此时用grow方法对其进行扩容,重新赋值给elementData。
最后点开grow方法,看到底是如何对数组进行扩容的。
/**
* Increases the capacity to ensure that it can hold at least the
* number of elements specified by the minimum capacity argument.
*
* @param minCapacity the desired minimum capacity
* @throws OutOfMemoryError if minCapacity is less than zero
*/
private Object[] grow(int minCapacity) {
return elementData = Arrays.copyOf(elementData,
newCapacity(minCapacity));
}
private Object[] grow() {
return grow(size + 1);
}
- 如果数组满了,最少给数组长度+1。定义一个新的数组长度,再使用Arrays.copyOf将旧数组的值,通过新的数组长度,赋值给旧数组。
查看newCapacity方法,用来计算新的长度:
/**
* Returns a capacity at least as large as the given minimum capacity.
* Returns the current capacity increased by 50% if that suffices.
* Will not return a capacity greater than MAX_ARRAY_SIZE unless
* the given minimum capacity is greater than MAX_ARRAY_SIZE.
*
* @param minCapacity the desired minimum capacity
* @throws OutOfMemoryError if minCapacity is less than zero
*/
private int newCapacity(int minCapacity) {
// overflow-conscious code
int oldCapacity = elementData.length;
int newCapacity = oldCapacity + (oldCapacity >> 1);
if (newCapacity - minCapacity <= 0) {
if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA)
return Math.max(DEFAULT_CAPACITY, minCapacity);
if (minCapacity < 0) // overflow
throw new OutOfMemoryError();
return minCapacity;
}
return (newCapacity - MAX_ARRAY_SIZE <= 0)
? newCapacity
: hugeCapacity(minCapacity);
}
private static int hugeCapacity(int minCapacity)
这篇博客深入探讨了Java集合框架,包括链表、二叉树的基本概念,以及Collection接口及其子接口List、Set的重点内容。详细介绍了ArrayList、Vector、LinkedList、HashSet、TreeSet等集合类的特性和使用场景,同时讲解了Map接口及HashMap、Hashtable、TreeMap的区别。还涵盖了JDK9中的集合新特性。
最低0.47元/天 解锁文章
1162

被折叠的 条评论
为什么被折叠?



