手写ArrayList集合框架
Posted suyang-java
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了手写ArrayList集合框架相关的知识,希望对你有一定的参考价值。
List集合是我们平时常用的集合框架,List集合是有序的,在java中List接口主要有两个实现分别是ArrayList和LinkedList,其中ArrayList类主要是通过数组的方式实现的。因为ArrayList底层是通过数组的方式实现List集合,所以在访问集合中的数据时可以直接通过数组的下标访问,效率较高。由于在java中数组的大小必须在定义数组时确定并且不能修改,所以在对ArrayList集合添加和删除时需要考虑是否需要对数组扩容同时移动数组下标。
下面是我自己实现的List集合的代码:
1.首先我要定义一个List接口:
public interface List<E> { //返回此列表中的元素数。 int size(); //如果此列表不包含元素,则返回 true 。 boolean isEmpty(); //如果此列表包含指定的元素,则返回 true 。 boolean contains(Object o); //将指定的项目添加到滚动列表的末尾。 boolean add(E e); //从列表中删除指定元素的第一个出现(如果存在)。 boolean remove(Object o); //返回此列表中指定位置的元素。 E get(int index); //用指定的元素替换此列表中指定位置的元素。 E set(int index, E element); //在此列表中的指定位置插入指定的元素。 void add(int index, E element); //删除该列表中指定位置的元素。 E remove(int index); //返回此列表中指定元素的第一次出现的索引,如果此列表不包含元素,则返回-1。 int indexOf(Object o); //返回此列表中指定元素的最后一次出现的索引,如果此列表不包含元素,则返回-1。 更正式地,返回最高指数i ,使得(o==null ? get(i)==null : o.equals(get(i))) ,或-1如果没有这样的索引。 int lastIndexOf(Object o); }
然后再定义一个ListArray类来实现这个List接口。
public class ListArray<E> implements List<E> { private static final int DEFAULT_CAPACITY = 10; private int size; private Object[] elementData; public ListArray() { this.elementData = new Object[DEFAULT_CAPACITY]; } public ListArray(int initialCapacity){ if(initialCapacity>0){ this.elementData = new Object[initialCapacity]; }else{ this.elementData = new Object[DEFAULT_CAPACITY]; } } @Override public int size() { return size; } @Override public boolean isEmpty() { return size==0; } @Override public boolean contains(Object o) { boolean flag = false; if(elementData.length>0){ for(int i=0;i<elementData.length;i++){ if(elementData[i].equals(o)){ flag=true; break; } } } return flag; } @Override public boolean add(E e) { checkNeedExtends(size+1); this.elementData[size] = e; size++; return true; } @Override public boolean remove(Object o) { E e = remove(indexOf(o)); return e!=null; } @Override public E get(int index) { return (E)elementData[index]; } @Override public E set(int index, E element) { checkIndex(index); elementData[index] =element; return element; } @Override public void add(int index, E element) { checkNeedExtends(size+1); checkIndex(index); for(int j=size;j>index;j--){ elementData[j] = elementData[j-1]; } elementData[index] = element; size++; } private void checkIndex(int index) { if(index<0||index>elementData.length-1){ throw new RuntimeException("索引越界"); } } @Override public E remove(int index) { checkIndex(index); if(size==0){ return null; }else{ E result = get(index); for(int j=size-1;j>index;index++){ elementData[index] = elementData[index+1]; } elementData[size-1] = null; size--; return result; } } @Override public int indexOf(Object o) { if (o == null) { for (int i = 0; i < size; i++) if (elementData[i]==null) return i; } else { for (int i = 0; i < size; i++) if (o.equals(elementData[i])) return i; } return -1; } @Override public int lastIndexOf(Object o) { if (o == null) { for (int i = size-1; i >= 0; i--) if (elementData[i]==null) return i; } else { for (int i = size-1; i >= 0; i--) if (o.equals(elementData[i])) return i; } return -1; } private void checkNeedExtends(int minCapacity) { if(elementData.length - minCapacity<0){ grow(); } } private void grow() { int oldCapacity = elementData.length; int newCapacity = oldCapacity + (oldCapacity >> 1); Object[] newEle = new Object[newCapacity]; for(int i=0;i<size;i++){ newEle[i] = elementData[i]; } elementData = newEle; } }
这里DEFAULT_CAPACITY表示集合框架的初始容量,elementData表示用来存储数据的数组,size表示线性表的长度。通过代码我们知道在一个具有n个数据元素的数组插入和删除一个数据元素的时间复杂度为O(n),查询的时间复杂度为O(1)。所以ArrayList适用于查询不适用于添加和修改。
以上是关于手写ArrayList集合框架的主要内容,如果未能解决你的问题,请参考以下文章
JavaLearn#(15)集合提升训练:手写ArrayList单链表LinkedListHashMapHashSet新一代并发集合类
面试必会之ArrayList源码分析&手写ArrayList