文章目录
集合的概要
Java 集合框架 Java Collection Framework ,又被称为容器 container ,是定义在 java.util 包下的一组接口 interfaces和其实现类 classes

ArrayList集合原理
ArrayList是线性表,而线性表有:顺序表(ArrayList)、链表(LinkedList)、栈(Stack)、队列(Queue)…
顺序表:一般情况下采用数组存储,在数组上完成数据的增删查改。

ArrayList自我实现
我这里将框架给大家。大家可以自己实现一下。
public class SeqList {
private int[] array;
private int size;
// 默认构造方法
SeqList(){
}
// 将顺序表的底层容量设置为initcapacity
SeqList(int initcapacity){
}
// 新增元素,默认在数组最后新增
public void add(int data) {
}
// 在 pos 位置新增元素
public void add(int pos, int data) {
}
// 判定是否包含某个元素
public boolean contains(int toFind) {
return true;
}
// 查找某个元素对应的位置
public int indexOf(int toFind) {
return -1;
}
// 获取 pos 位置的元素
public int get(int pos) {
return -1;
}
// 给 pos 位置的元素设为 value
public void set(int pos, int value) {
}
//删除第一次出现的关键字key
public void remove(int toRemove) {
}
// 获取顺序表长度
public int size() {
return 0;
}
// 清空顺序表
public void clear() {
}
// 打印顺序表,注意:该方法并不是顺序表中的方法,为了方便看测试结果给出的
public void display() {
}
}
我进行的ArrayList的数据结构
public class MyArraylist {
public int[] elem;
public int usedSize;//0
//默认容量
private static final int DEFAULT_SIZE = 10;
public MyArraylist() {
this.elem = new int[DEFAULT_SIZE];
}
/**
* 打印顺序表:
* 根据usedSize判断即可
*/
public void display() {
for (int i = 0; i < usedSize; i++) {
System.out.println(elem[i]);
}
}
// 新增元素,默认在数组最后新增
public void add(int data) {
if (isFull()) {
Arrays.copyOf(elem, elem.length * 2);
}
elem[usedSize] = data;
usedSize++;
}
/**
* 判断当前的顺序表是不是满的!
*
* @return true:满 false代表空
*/
public boolean isFull() {
if (usedSize < elem.length) {
return true;
} else {
return false;
}
}
private boolean checkPosInAdd(int pos) {
return true;//合法
}
// 在 pos 位置新增元素
public void add(int pos, int data) {
if (isFull()) {
Arrays.copyOf(elem, elem.length * 2);
}
int tmp = 0;
for (int i = pos + 1; i < usedSize; i++) {
tmp = elem[i];
elem[i] = elem[i - 1];
}
elem[usedSize] = tmp;
usedSize++;
}
// 判定是否包含某个元素
public boolean contains(int toFind) {
for (int i = 0; i < usedSize; i++) {
if (elem[i] == toFind) {
return true;
}
}
return false;
}
// 查找某个元素对应的位置
public int indexOf(int toFind) {
for (int i = 0; i < usedSize; i++) {
if (elem[i] == toFind) {
return i;
}
}
return -1;
}
// 获取 pos 位置的元素
public int get(int pos) throws RuntimeException {
if (pos < 0 || pos > elem.length) {
return -1;
}
//这里应该写抛出位置异常的,不过算了
return elem[pos];
}
private boolean isEmpty() {
if (usedSize == 0) {
return true;
}
return false;
}
// 给 pos 位置的元素设为【更新为】 value
public void set(int pos, int value) {
if (pos < 0 || pos > elem.length) {
return;
}
//这里应该写抛出位置异常的,不过算了
elem[pos] = value;
}
/**
* 删除第一次出现的关键字key
*
* @param key
*/
public void remove(int key) {
for (int i = 1; i < elem.length; i++) {
if (key == elem[i]) {
int tmp = elem[i];
elem[i - 1] = elem[i];
}
}
usedSize--;
}
// 获取顺序表长度
public int size() {
return elem.length;
}
// 清空顺序表
public void clear() {
usedSize = 0;
}
ArrayList具体的操作
| 返回值 | 方法 | 解释 |
|---|---|---|
| boolean | add(E e) | 尾插 e |
| void | add(int index, E element) | 将 e 插入到 index 位置 |
| boolean | addAll(Collection<? extends E> c) | 尾插 c 中的元素 |
| E | remove(int index) | 删除 index 位置元素 |
| boolean | remove(Object o) | 删除遇到的第一个 o |
| E | get(int index) | 获取下标 index 位置元素 |
| E | set(int index, E element) | 将下标 index 位置元素设置为 element |
| void | clear() | 清空 |
| boolean | contains(Object o) | 判断 o 是否在线性表中 |
| int | indexOf(Object o) | 返回第一个 o 所在下标 |
| int | lastIndexOf(Object o) | 返回最后一个 o 的下标 |
| List | subList(int fromIndex, int toIndex) | 截取部分 list |
注意:
这里的E代表泛型,目前可以理解为所有类型都可以去填充容器(具体问题会在泛型的相关文章中体现)链接:
public static void main(String[] args) {
List<String> list = new ArrayList<>();
for (int i = 0; i < 10; i++) {
list.add(i+"");
}
// 获取list中有效元素个数
System.out.println(list.size());
// 获取和设置index位置上的元素,注意index必须介于[0, size)间
System.out.println(list.get(1));
list.set(1, "k");
// 在list的index位置插入指定元素,index及后续的元素统一往后搬移一个位置
list.add(2, "l");
// 删除指定元素,找到了就删除,该元素之后的元素统一往前搬移一个位置
list.remove("3");
// 删除list中index位置上的元素,注意index不要超过list中有效元素个数,否则会抛出下标越界异常
list.remove(list.size()-1);
// 检测list中是否包含指定元素,包含返回true,否则返回false
if(!list.contains("9")){
list.add("9");
}
}
ArrayList扩容机制
ArrayList关于容量扩容机制

源码总结:
- 检测是否真正需要扩容,如果是调用grow准备扩容
- 预估需要库容的大小
1.初步预估按照1.5倍大小扩容
2.如果用户所需大小超过预估1.5倍大小,则按照用户所需大小扩容
3.真正扩容之前检测是否能扩容成功,防止太大导致扩容失败 - 使用copyOf进行扩容
小结
ArrayLIst太过于简单,操作数组,其实大家都会,我这里给大家说一些后面会用到的。
- ArrayList不是线程安全的,单线程可用
- 在多线程中可以选择Vector或者CopyOnWriteArrayList
- ArrayList底层是一段连续的空间,并且可以动态扩容,是一个动态类型的顺序表
十一、其他文章接口
1.String方法(重要,对于操作字符串有巨大的帮助)
2.java常用的接口及其方法(包含拷贝,比较,排序,构造器)
3.初阶数据结构
3.1 顺序表:ArrayList
3.2 链表:LinkedList
3.3 栈:Stack
3.4 队列:Queue
3.5 二叉树:Tree
3.6 优先级队列:PriorityQueue(堆排序)
3.7 Map和Set
HashMap和HashSet,TreeMap和TreeSet
文章链接
4. 排序(7种方式)
4.1 插入排序(两种)
4.2 选择排序(两种)
4.3 快速排序
4.4 堆排序
里面有堆排序的实现和逻辑
文章链接
文章详细介绍了ArrayList的基本概念、内部原理,包括其作为线性表的特性,以及如何自我实现一个简单的顺序表。还探讨了ArrayList的扩容机制,并提供了具体的添加、删除、查找等操作示例。此外,提到了ArrayList在多线程环境中的线程不安全问题。
826

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



