java-Collection类源码

一、接口的API

1Collection<E>

int size();

boolean isEmpty();

boolean contains(Object o);

Iterator<E> iterator();

Object[] toArray();

<T> T[] toArray(T[] a);//?

boolean add(E e);

boolean remove(Object o);

boolean containsAll(Collection<?> c);

boolean addAll(Collection<? extends E> c);

boolean removeAll(Collection<?> c);

boolean retainAll(Collection<?> c);//取交集

void clear();

boolean equals(Object o);

int hashCode();

2、List<E>

boolean addAll(int index, Collection<? extends E> c);

    E get(int index);

    E set(int index, E element);

    void add(int index, E element);

    E remove(int index);

    int indexOf(Object o);

    int lastIndexOf(Object o);

    ListIterator<E> listIterator();

    ListIterator<E> listIterator(int index);

List<E> subList(int fromIndex, int toIndex);

List接口继承与Collection接口。由上可见,List相比于Collection,额外提供的方法均与index有关。即List是一个有序集合,内部的每一个元素都可以通过下标直接定位。

3、Set<E>

Set提供的方法与Collection完全一致。Set规范:元素不可重复。

4、SortedSet<E>

Comparator<? super E> comparator();

    SortedSet<E> subSet(E fromElement, E toElement);

    SortedSet<E> headSet(E toElement);

    SortedSet<E> tailSet(E fromElement);

    E first();

E last();

顾名思义,有序的Set。但与LinkedHashSet不同的是,前者通过Comparator比较元素的大小来进行排序,后者则是维护元素的插入顺序。

SortedSet的这种维护是时刻维护的(就跟堆维护堆序一样),每次插入元素的时候就会根据其大小放入合适的位置。

实现类有TreeSet

5、Queue<E>

boolean add(E e);

    boolean offer(E e);

    E remove();

    E poll();

    E element();

E peek();

队列:先进先出。注意,这里的“进”并不一定是按照时间顺序来衡量,有可能是按照其他顺序来模拟时间上的先后。

 

 

抛出异常

返回特殊值

插入

add(e)

offer(e)

移除

remove()

poll()

检查

element()

peek()

 

6、Deque<E>

    void addFirst(E e);

    void addLast(E e);

    boolean offerFirst(E e);

    boolean offerLast(E e);

    E removeFirst();

    E removeLast();

    E pollFirst();

    E pollLast();

    E getFirst();

    E getLast();

    E peekFirst();

    E peekLast();

    boolean removeFirstOccurrence(Object o);

    boolean removeLastOccurrence(Object o);

    boolean add(E e);

    boolean offer(E e);

    E remove();

    E poll();

    E element();

    E peek();

    void push(E e);

    E pop();

    boolean remove(Object o);

    boolean contains(Object o);

    public int size();

    Iterator<E> iterator();

Iterator<E> descendingIterator();

继承于Queue,是一个双向队列。


二、实现类

1、ArrayList<E>

public class ArrayList<E> extends AbstractList<E>

        implements List<E>, RandomAccess, Cloneable, java.io.Serializable

 

1、ArrayList存储元素的数据结构实际上是一个数组,数组本身的大小是不可变的。因此,在向ArrayList中插入元素时,如果满足触发条件,会将ArrayList进行扩容。扩容后的数组大小通常满足:newCapacity = oldCapacity + (oldCapacity >> 1);

2、ArrayList是有最大存储容量的:

private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8;

private static int hugeCapacity(int minCapacity) {

        if (minCapacity < 0) // overflow

            throw new OutOfMemoryError();

        return (minCapacity > MAX_ARRAY_SIZE) ?

            Integer.MAX_VALUE :

            MAX_ARRAY_SIZE;

}

3、modCount??

4、在删除ArrayList中的元素后,将数组的后边的元素置为null,以使GC回收,避免内存泄漏。如:

public void clear() {

         modCount++;

         // clear to let GC do its work

         for (int i = 0; i < size; i++)

             elementData[i] = null;

         size = 0;

}

5、ArrayList中对数组的操作是通过System类的

public static native void arraycopy(Object src,  int  srcPos,

                                        Object dest, int destPos,                                         int length);

执行的。

6、迭代器

7、线程不安全举例以及解决方案见Vector思考2.

2、LinkedList<E>

public class LinkedList<E>

    extends AbstractSequentialList<E>

    implements List<E>, Deque<E>, Cloneable, java.io.Serializable

LinkedList实现了Deque接口,是一个双向队列。

 

1、LinkedList的实现是建立在内部静态类

private static class Node<E> {

        E item;

        Node<E> next;

        Node<E> prev;

 

        Node(Node<E> prev, E element, Node<E> next) {

            this.item = element;

            this.next = next;

            this.prev = prev;

        }

}

的基础上的。

2、LinkedList是有序的,而且是双向的,可以储存重复的元素,甚至是多个null

3、学习LinkedList的源码,发现在向LinkedList中插入、删除元素时,需时刻注意操作前后相邻两个元素关系的维护,避免“链子”断掉。对于每一个节点,不仅要维护自己的next,还要维护自己的prev。同时还要注意当前节点的next或者prev是不是null

4、注意,向LinkedList中插入null时,只代表这个Nodeitem属性是null,而这个Node却一定不是null。其实,LinkedList这条由Node串联起来的“链条”根本不存在为nullNode,但是存在为Null的元素(元素只是Nodeitem属性)。

5、LinkedList实现了List接口,因此支持按index进行的元素的操作,但他没有实现RandomAccess,也就是说它不支持随机访问,它的按index操作实际是通过由链条的两端向中间一个一个访问实现的。

6、LinkedList实现了Deque接口,因此同时具备队列的特点,支持poll(),offer()等方法。

7、迭代器:实现很简单,看源码就行。

3、Vector<E>

public class Vector<E>

    extends AbstractList<E>

    Implements List<E>, RandomAccess, Cloneable, java.io.Serializable

1、VectorArrayList实现的接口完全一致。推断功能也会类似。

2、Vector的扩容:

int newCapacity = oldCapacity + ((capacityIncrement > 0) ?

                                         capacityIncrement : oldCapacity);

如果没指定扩容参数,每次自动扩充一倍。

3、Vector的方法大部分被synchronized 修饰,因此Vector是线程安全的。

思考:1ArrayListVector的区别在哪?

Vector是线程安全的,因此性能较低,已逐渐被弃用;而ArrayList是线程不安全的,但性能比Vector高。Vector每次扩容一倍,而ArrayList每次扩容一半。

思考2ArrayList线程不安全举例,如何解决?

ArrayList线程不安全举例:

package com.lv.Number;

 

import java.util.ArrayList;

import java.util.List;

 

public class ArrayListInThread implements Runnable {

 

// 线程不安全

private List<String> threadList = new ArrayList<String>();

// 线程安全

// private List<string> threadList = Collections.synchronizedList(new

// ArrayList<string>());

 

@Override

public void run() {

try {

Thread.sleep(10);

} catch (InterruptedException e) {

e.printStackTrace();

}

// 把当前线程名称加入list

threadList.add(Thread.currentThread().getName());

}

 

public static void main(String[] args) throws InterruptedException {

ArrayListInThread listThread = new ArrayListInThread();

 

for (int i = 0; i < 100; i++) {

Thread thread = new Thread(listThread, String.valueOf(i));

thread.start();

}

 

// 等待子线程执行完

Thread.sleep(2000);

 

System.out.println(listThread.threadList.size());

// 输出list中的值

for (int i = 0; i < listThread.threadList.size(); i++) {

if (listThread.threadList.get(i) == null) {

System.out.println();

}

System.out.print(listThread.threadList.get(i) + "  ");

}

}

}

解决方式:private List<string> threadList = Collections.synchronizedList(new

 ArrayList<string>());

public static <T> List<T> synchronizedList(List<T> list) {

        return (list instanceof RandomAccess ?

                new SynchronizedRandomAccessList<>(list) :

                new SynchronizedList<>(list));

    }

4、Stack<E>

public

class Stack<E> extends Vector<E>

基于Vector扩充实现了一个栈(后进先出)的数据结构。同时也具备Vector(动态数组)的功能。

5、HashSet

public class HashSet<E>

    extends AbstractSet<E>

implements Set<E>, Cloneable, java.io.Serializable

基于HashMap类。

6、LinkedHashSet

基于LinkedHashMap类。

7、TreeSet

基于TreeMap类。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值