1.2 链表手动实现
1.介绍
动态数组缺点:可能会造成内存空间的大量浪费
- 链表能做到用多少就申请多少内存
- 链表是一种链式存储的线性表,所有元素的内存地址不一定是连续的
1.ArrayList与LinkedList 有许多相同的方法名(add, remove, size,clear等),
写一个接口List,封装这些相同的方法 ->public interface List<E>{}
2.又他俩有几个相同的方法,方法内部代码也同(如rangeCheck,size,isEmpty等),
弄个父类AbstractList,封装这些方法,让他俩都继承AbstractList。
3.AbstractList作为父类 最后去实现List接口。
4.由于父类只想放具有相同代码的方法,对于List接口里的那些只有方法名相同的方法,
不想去实现,所以AbstractList 定义为abstract(抽象的)
1 | public interface List<E>{} |
2.List接口
1 | public interface List<E> { |
3.AbstractList 父类,抽象类
1 | public abstract class AbstractList<E> implements List<E> { |
4.常量
static final int ELEMENT_NOT_FOUND = -1; //元素未找到
因为需要外界调用ELEMENT_NOT_FOUND
,即它要对外界可见,所以不能放在AbstractList
中.
要放在list
里面,由于接口里面的东西都是公共的,所以不用加public
AbstractList
属于中间人,对外界不可见(外界不能调用)
如对外界可见的则三个类:List<Integer> list1 = new MyArrayList<>();
List<Integer> list2 = new MyLinkedList<>();
5.链表设计1 - 结点实现
1 | // 在MyArrayList类里定义以下 |
6.清空链表 - (和ArrayList清空方式不同)
1 | public void clear() { |
6.返回索引对应的结点对象
1 | private Node<E> node(int index){ |
7.获取index位置元素(首先要找到结点)
1 | public E get(int index) { |
8.设置index位置元素
1 | public E set(int index, E element) { |
9.添加(要注意0位置 试分析添加到末尾,为什么能通过)
1 | public void add(int index, E element) { |
10.删除 (注意0位置)
1 | public void remove(int index) { |
11.查元素对应的索引(涉及到遍历链表)
1 | public int indexOf(E element) { |
12.重写toString
1 | public String toString() { |
13.测试
1 | List<Integer> list = new MyLinkedList<>(); |