Java容器之Collection与ArrayList一些理解及自己用代码实现ArrayList

1、Collection是java.util的一个接口,它继承了Iterable接口(可以使用for each循环来遍历),它有三个子接口:List,Set与Queue。

2、Collection接口主要接口有:

  • int size():返回容器大小。
  • boolean isEmpty():判断容器是否为空。
  • void clear():清除容器中的元素。
  • boolean contains(E x):判断容器是否含有元素x。
  • boolean add(E x):向容器添加元素x。
  • boolean remove(E x):从容器中删除元素x。
  • Iterator<E> iterator():获得容器的迭代器对象。

其中Iterator接口实现了迭代器,有hasNext(),next(),remove()方法。所以Collection也可以用iterator来遍历。

3、List接口继承了Collection接口,它多了两个方法:

  • E get(int i):查询下标为i的元素并返回。
  • E set(int i,E x):修改i位置的元素,并将老元素返回。

4、List有两个实现类ArrayList和LinkedList,前者查改效率高,后者增删效率高。

5、自己实现ArrayList:

import java.util.Iterator;
import java.util.NoSuchElementException;
 
public class MyArrayList<AnyType> implements Iterable<AnyType> {
 
    private static final int DEFAULT_CAPACITY = 10;
    private AnyType[] theItems;
    private int theSize;
 
    public MyArrayList(){
        doClear();
    }
    private void doClear(){
        theSize = 0;
        ensureCapacity(DEFAULT_CAPACITY);
    }
    //确保容量
    private void ensureCapacity(int newCapacity){
        //这里防止用户传入小于集合长度的参数
        if (newCapacity < theSize){
            return;
        }
        //保存原来的数组
        AnyType[] old = theItems;
        //分配新的数组
        theItems = (AnyType[]) new Object[newCapacity];
        /*
            注意:如果是调用构造或者清空方法后进入的该方法,此时size()已经是0,
            所以for循环条件不成立,虽然old引用了空对象,但不会产生空指针异常
         */
        for (int i = 0; i < size(); i++) {
            theItems[i] = old[i];
        }
 
    }
    //清空集合
    public void clear(){
        doClear();
    }
    //返回集合大小
    public int size(){
        return theSize;
    }
    //判断集合是否为空
    public boolean isEmpty(){
        return theSize == 0;
    }
    //去掉集合中多申请的空间
    private void trimToSize(){
        ensureCapacity(size());
    }
    //获取集合中的值
    public AnyType get(int index){
        if (index < 0 || index >= size()){
            throw new ArrayIndexOutOfBoundsException();
        }
        return theItems[index];
    }
    //往集合中设置值,返回原来的值
    public AnyType set(int index, AnyType newVal){
        if (index < 0 || index >= size()){
            throw new ArrayIndexOutOfBoundsException();
        }
        AnyType oldVal = theItems[index];
        theItems[index] = newVal;
        return oldVal;
    }
    //添加元素
    public boolean add(AnyType x){
        add(size(), x);
        return true;
    }
    //在指定位置添加元素
    public void add(int index, AnyType x){
        if (index < 0 || index > size()){
            throw new ArrayIndexOutOfBoundsException();
        }
        //注意,添加元素的时候有两种情况,一是内部数组满了,二是内部数组没有满
        if (theItems.length == size()){
            ensureCapacity(size()*2 + 1);
        }
        //仅仅是移动元素
        for (int i = size();i > index;i--){
            theItems[i] = theItems[i-1];
        }
        //插入元素
        theItems[index] = x;
        theSize++;
    }
    //删除指定位置的元素
    public AnyType remove(int index){
        if (index < 0 || index > size()){
            throw new ArrayIndexOutOfBoundsException();
        }
        AnyType removeItem = theItems[index];
        //注意:这里的条件是size()-1,如果是size(),theItem[i+1]会出现越界异常
        for (int i = index; i < size()-1; i++) {
            theItems[i] = theItems[i+1];
        }
        theSize--;
        return removeItem;
    }
    @Override
    public Iterator<AnyType> iterator() {
        return new ArrayListIterator();
    }
    //内部类
    private class ArrayListIterator implements Iterator<AnyType>{
        //当前迭代器位置
        private int current = 0;
        @Override
        public boolean hasNext() {
            return current < size();
        }
 
        @Override
        public AnyType next() {
            if (!hasNext()){
                throw new NoSuchElementException();
            }
            return theItems[current++];
        }
 
        public void remove(){
            MyArrayList.this.remove(--current);
        }
    }
}

 

posted @ 2020-04-24 23:42  HankTown  阅读(573)  评论(0编辑  收藏  举报