List笔记

List中常用的2个子类,ArrayList擅长随机访问,但是添加或移除元素较慢和LinkedList代价较低的增加和删除,优化了顺序访问。在随机访问相对比较慢,特性较ArrayList多

List接口方法:

int size();返回元素个数

ArrayList,LinkedList

public int size() {
	return size;//返回实时记录添加或者减少元素的个数,此属性设计为私有方法,是不能随意更改的
}
boolean isEmpty();是否为空

ArrayList,LinkedList

public boolean isEmpty() {
	return size == 0;//重写了AbstractCollection的isEmpty方法,其实现为size()==0;LinkedList则没有重写
 }
int indexOf(Object o);//返回下标,要重写equels方法

ArrayList

public int indexOf(Object o) {
	if (o == null) {  //根据源码传入空也能查出下标,防止空指针,对空做特殊处理查找
	    for (int i = 0; i < size; i++)  //因为elementData的长度比size大,size才是真正的长度
		if (elementData[i]==null)   //返回第一个为空的
		    return i;
	} else {
	    for (int i = 0; i < size; i++)
		if (o.equals(elementData[i]))  //Object最好重写equles方法
		    return i;
	}
	return -1;
}
public int indexOf(Object o) {
        int index = 0;
        if (o==null) {
            for (Entry e = header.next; e != header; e = e.next) {   //header是LinkedList的头部,头部的下一个开始循环
                if (e.element==null)    //如果为空返回第几个,index是局部变量记录的
                    return index;
                index++;
            }
        } else {
            for (Entry e = header.next; e != header; e = e.next) {
                if (o.equals(e.element))
                    return index;
                index++;
            }
        }
        return -1;
}
E get(int index);得到第几个

ArrayList

public E get(int index) {
	RangeCheck(index);//index是否大于size

	return (E) elementData[index];根据数组下标得到第几个
}

LinkedList

private Entry<E> entry(int index) {
        if (index < 0 || index >= size)
            throw new IndexOutOfBoundsException("Index: "+index+    //检查是否超出个数
                                                ", Size: "+size);
        Entry<E> e = header;                                          //得到头部
        if (index < (size >> 1)) {                                    //查询速度优化,如果长度是10二进制为1010,右移1位101,index<5从前面开始找,循环到i等于index为止
            for (int i = 0; i <= index; i++)
                e = e.next;
        } else {                                                      //如果大于则从后面开始,说明LinkedList是一个圈
            for (int i = size; i > index; i--)                        //从size开始减循环到i>index时,确定e的值,在得到Element
                e = e.previous;
        }
        return e;
    }
List

boolean add(E e);添加一个元素

ArrayList

public boolean add(E e) {
	ensureCapacity(size + 1);  // 扩大数组的空间,如果新加一个,放不下了,则原数组大小*3/2+1扩张
	elementData[size++] = e;   //第size+1个放入es
	return true;               //返回成功
    }
LinkedList

private Entry<E> addBefore(E e, Entry<E> entry) {//直接调用的addBefore(e,header)在开始的前面加一个,因为是一个圈,所以相当于在最后加了一个
	Entry<E> newEntry = new Entry<E>(e, entry, entry.previous);   //Entry的构造方法(当前值,下一个的值,上一个的值)因为本来就是一个圈,新加入的值的下一个
	newEntry.previous.next = newEntry;                            //就是LinkedList的头,上一个是原来头部的上一个,现在新加进来的上一个和下一个已经关联起来了
	newEntry.next.previous = newEntry;                            //但是原来的投的上一个还是未插入进来的上一个,所以把newEntry的下一个的上一个指向本身,
       size++;                                                       //把newEntry的下一个的上一个指向本身
	modCount++;
	return newEntry;
}

List Object[] toArray();

ArrayList

public Object[] toArray() {
        return Arrays.copyOf(elementData, size);   //Arrays的方法把ArrayList内部属性数组直接复制给新的数组
}
LinkedList

public Object[] toArray() {
	Object[] result = new Object[size];      //创建一个与LinkedList等长的数组
        int i = 0;
        for (Entry<E> e = header.next; e != header; e = e.next)
            result[i++] = e.element;            //循环List,赋值
	return result;
}
boolean remove(Object o);

ArrayList

private void fastRemove(int index) {   //通过循环找到与Object相等的下标,在调用这个方法
        modCount++;
        int numMoved = size - index - 1;
        if (numMoved > 0)
            System.arraycopy(elementData, index+1, elementData, index,   //把下标+1后面的数据加到本数据index后面,然后把最后一个置为空
                             numMoved);
        elementData[--size] = null; // Let gc do its work
}

LinkedList

private E remove(Entry<E> e) {        //通过循环找到相等的Entry
	if (e == header)
	    throw new NoSuchElementException();

        E result = e.element;         //先保存当前element,用于返回
	e.previous.next = e.next;     //当前的上一个的下一个替换成当前的下一个
	e.next.previous = e.previous; //当前的下一个的上一个替换为当前的上一个
        e.next = e.previous = null;   //当前中的值全部置为null
        e.element = null;
	size--;
	modCount++;
        return result;
    }

boolean removeAll(Collection<?> c);

AbstractCollection

public boolean removeAll(Collection<?> c) {
	boolean modified = false;                    //是否修改了
	Iterator<?> e = iterator();
	while (e.hasNext()) {                        //循环每一个
	    if (c.contains(e.next())) {              //里面是否存在于c
		e.remove();                          //Iterator删除
		modified = true;
	    }
	}
	return modified;
}

public void remove() {
	    if (lastRet == -1)
		throw new IllegalStateException();
            checkForComodification();

	    try {
		AbstractList.this.remove(lastRet);  //删除循环到的最后一个
		if (lastRet < cursor)
		    cursor--;                       //游标-1
		lastRet = -1;                       
		expectedModCount = modCount;        //多线程
	    } catch (IndexOutOfBoundsException e) {
		throw new ConcurrentModificationException();
	    }
}

boolean containsAll(Collection<?> c);

public boolean containsAll(Collection<?> c) {
	Iterator<?> e = c.iterator();        
	while (e.hasNext())                   //循环C
	    if (!contains(e.next()))          //如果本集合中不包括其中一个则返回false
		return false;
	return true;
    }





  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值