这是我参与11月更文挑战的第6天,活动详情查看:2021最后一次更文挑战 !
list我们平时在写代码时用的是非常非常多了,但他的实现方式不断的被官放优化,以此来不断提高代码运行效率, 这篇文章将带着大家一起,来自己写一个linkedList,他底层实现逻辑是:
双向链表,故基于链表的特性,我们可以得知其增删效率高,查询效率就极低,因此,我们可根据实际业务场景,考虑是否用它。
此处仅实现LinkedList部分方法
1.首先,新建一个接口List类,其中包含了size、isEmpty、contains、toArray、add、remove、clear、index方法,:
import java.util.ArrayList;
import java.util.Collection;
public interface List<E> {
// 求长度
int size();
// 集合内是否有元素
boolean isEmpty();
// 某个元素是否在集合内
boolean contains(Object o);
// 把集合内元素转换为数组
Object[] toArray();
// 向集合内添加元素
boolean add(E e);
// 删除集合内的某个元素
boolean remove(Object o);
// 删除某个位置的元素
E remove(int index);
// 清空集合内元素
void clear();
// 根据下标得到集合内某个元素
E get(int index);
// 在某个位置添加元素
void add(int index, E element);
}
此图方便大家理解(使用学生类测试,学生类有id和name属性),
2.前面讲到,他是通过一个双向链表实现的,故我们需要新建一个结构体,在Java中就相当于一个内部类,其中有3个参数:
-
E item; //存储当前节点的元素
-
Node prev; //后继节点
-
Node prev; //前继节点 `
public class LinkList implements List { private int size; Node first = null; Node last = null;//方便新增节点,可直接调用next public LinkList() { } @Override public int size() { return this.size; }
@Override public boolean isEmpty() { return (size == 0); } @Override public boolean contains(Object o) { return false; } public int indexOf(Object o) { //判断要找下标的元素是否为空 if (o == null) { return -1; } int index = 0; //遍历找到当前元素的下标 for (Node<E> x = first; x != null; x = x.next) { if (o.equals(x.item)) { return index; } index++; } return -1; } @Override public Object[] toArray() { Object[] result = new Object[size]; int i = 0; //循环遍历将每个元素都放入声明好的数组中 for (Node<E> x = first; x != null; x = x.next) { result[i + 1] = x.item; } return result; } void linkLast(E e) { Node<E> oldLast = last; Node<E> newNode = new Node<>(oldLast, e, null); last = newNode; if (oldLast == null) { first = newNode; } else { oldLast.next = newNode; } size++; } @Override public boolean add(E e) { linkLast(e); return true; } public void addLast(E e) { linkLast(e); } private void linkFirst(E e) { Node<E> oldFirst = first; Node<E> newNode = new Node<>(null, e, oldFirst); first = newNode; if (oldFirst == null) {// 如果集合内没有元素 last = newNode;// 当前元素也是最后一个元素 } else { oldFirst.prev = newNode; } size++; } public void addFirst(E e) { linkFirst(e); } @Override public void add(int index, E e) { // 范围验证 if (index >= 0 && index <= size) { throw new IndexOutOfBoundsException("Index: " + index + ", Size: " + size); } if (index == size) { linkLast(e); } else { Node<E> oldNode = node(index); } } public Node<E> node(int index) {// 根据位置寻找元素 Node<E> e = first; for (int i = 0; i < index; i++) { e = e.next; } return e; } @Override public boolean remove(Object o) { for (Node<E> x = first; x != null; x = x.next) { if (o.equals(x.item)) { // 开始删除\ Node<E> p = x.prev; Node<E> n = x.next; p.next = n; n.prev = p; x.prev = null; x.next = null; size--; return true; } } return false; } @Override public E remove(int index) { // 范围验证 if (!(index >= 0 && index <= size)) { throw new IndexOutOfBoundsException("Index: " + index + ", Size: " + size); } E e = get(index); remove(e); return e; } @Override public void clear() { size = 0; first = null; last = null; } @Override public E get(int index) { Node<E> e = first; for (int i = 0; i < index; i++) { e=e.next; } return e.item; } public E removeFirst() { Node<E> oldFirst = first; //如果只有一个元素 if (size == 1) { first = null; last = null; } else { first = first.next; first.prev = null; } oldFirst.next = null; oldFirst.prev = null; size --; return oldFirst.item; } public E removeLast() { Node<E> oldLast = last; //如果只有一个元素 if (size == 1) { first = null; last = null; } else { last = oldLast.prev; last.next = null; } oldLast.next = null; oldLast.prev = null; size--; return oldLast.item; } public E getFirst() { if (first == null) { return null; } else { return last.item; } }} `
笔者开始写公众号啦,感兴趣的可以关注下: