今天我们来讲讲容器,何为容器?一个可以存放东西的物品。在JAVA世界里的容器,自然是能存储数据的物品。在百度百科上是这么描述的:JAVA容器可以管理对象的生命周期、对象与对象之间的依赖关系,您可以使用一个配置文件(通常是XML),在上面定义好对象的名称、如何产生(Prototype 方式或Singleton 方式)、哪个对象产生之后必须设定成为某个对象的属性等,在启动容器之后,所有的对象都可以直接取用,不用编写任何一行程序代码来产生对象,或是建立对象与对象之间的依赖关系。
一、java容器有哪些?
答:java容器包含List、ArrayList、Vector,Map、HashTable、HashMap、HashSet
二、Collection和Collections有什么区别?
答:最大的区别就是,前者是集合接口,后者是类,我们从源码分析,先来一张关系图
上面的关系图也许看着有点晕,那我拿些源码出来看,大家边看图,边看源码,会理解更深,今天我们就拿List做关系分解public interface List<E> extends Collection<E>{} //List继承Collection,看上面的继承线
AbstractCollection抽象类实现Collection接口public abstract class AbstractCollection<E> implements Collection<E> {}
AbstractList抽象类继承AbstractCollectionpublic abstract class AbstractList<E> extends AbstractCollection<E> implements List<E> {
ArrayList实现类继承AbstractList抽象类并且实现List集合接口public class ArrayList<E> extends AbstractList<E>
implements List<E>, RandomAccess, Cloneable, java.io.Serializable
{
Cloneable:一个标记接口,他是一个空的接口,没有方法也没有属性,他的作用只是为了防止对象在调用clone克隆方法时抛出CloneNotSupportedException异常,而ArrayList这个实现类,就有一个这样的接口。我们都知道,集合是一个可变数组,在你对集合进行增删时,集合的内部就是一个克隆新增的操作。实现 Cloneable来表示该对象能被克隆,能使用Object.clone()方法.
RandomAccess:也是一个标记接口,代表着实现类可以调用随机访问的方法。/**说明:List的clone方法
* Returns a shallow copy of this <tt>ArrayList</tt> instance. (The
* elements themselves are not copied.)
*
* @return a clone of this <tt>ArrayList</tt> instance
*/
public Object clone() {
try {
ArrayList<?> v = (ArrayList<?>) super.clone();
v.elementData = Arrays.copyOf(elementData, size);
v.modCount = 0;
return v;
} catch (CloneNotSupportedException e) {
// this shouldn"t happen, since we are Cloneable
throw new InternalError(e);
}
}
Collection源码:它是一个接口类,支持集合泛型,并且继承于Iterable迭代接口。* @param <E> the type of elements in this collection
*
* @author Josh Bloch
* @author Neal Gafter
* @see Set
* @see List
* @see Map
* @see SortedSet
* @see SortedMap
* @see HashSet
* @see TreeSet
* @see ArrayList
* @see LinkedList
* @see Vector
* @see Collections
* @see Arrays
* @see AbstractCollection
* @since 1.2
*/
public interface Collection<E> extends Iterable<E> {
}
Collection是各集合的继承类,如List,Set等,都继承Collection。集合继承了父类的迭代遍历功能。
List源码: * @param <E> the type of elements in this list
*
* @author Josh Bloch
* @author Neal Gafter
* @see Collection
* @see Set
* @see ArrayList
* @see LinkedList
* @see Vector
* @see Arrays#asList(Object[])
* @see Collections#nCopies(int, Object)
* @see Collections#EMPTY_LIST
* @see AbstractList
* @see AbstractSequentialList
* @since 1.2
*/
public interface List<E> extends Collection<E> {
}
Collection接口提供了13个功能,我们可以重写这个接口。Collection下的集合子类都具有这些功能,大家可以看一下这些方法,是不是很熟悉,我们拿List来看,常用的如获取集合的大小 list.size(),判断集合长度是否为0 list.isEmpty()public static void main(String [] args) {
Collection<List> collection = new Collection<List>() {
@Override
public int size() {
return 0;
}
@Override
public boolean isEmpty() {
return size() == 0;
}
@Override
public boolean contains(Object o) {
Iterator<E> it = iterator();
if (o==null) {
while (it.hasNext())
if (it.next()==null)
return true;
} else {
while (it.hasNext())
if (o.equals(it.next()))
return true;
}
return false;
}
@Override
public Iterator<List> iterator() {
return null;
}
@Override
public Object[] toArray() {
return new Object[0];
}
@Override
public <T> T[] toArray(T[] a) {
return null;
}
@Override
public boolean add(List list) {
return false;
}
@Override
public boolean remove(Object o) {
return false;
}
@Override
public boolean containsAll(Collection<?> c) {
return false;
}
@Override
public boolean addAll(Collection<? extends List> c) {
return false;
}
@Override
public boolean removeAll(Collection<?> c) {
return false;
}
@Override
public boolean retainAll(Collection<?> c) {
return false;
}
@Override
public void clear() {
}
};
}
从以上源码可以看出,Collection是一个接口,一个集合接口的父类,从关系图看着就像集合的祖辈。我后面会一一对Collection下的各集合接口进行源码介绍。接着我们讲讲Collections。
Collections源码: * <p>This class is a member of the
* <a href="{@docRoot}/../technotes/guides/collections/index.html">
* Java Collections Framework</a>.
*
* @author Josh Bloch
* @author Neal Gafter
* @see Collection
* @see Set
* @see List
* @see Map
* @since 1.2
*/
public class Collections {
// Suppresses default constructor, ensuring non-instantiability.
private Collections() {
}
}
Collections是一个工具类,他实现了很多集合方法,而且都是静态多态方法。比如我们常用的排序,因为是静态方法,所以我们不需要实例化Collections,可以直接调用,如:public static void main(String [] args) {
Collections.sort(new ArrayList<T>());
}
上面方法,是调用了List自己的默认方法,大家看到下面的语句是否会有些奇怪?前面我们分析了,List只是一个接口,ArrayList才是实现List的实现类。接口怎么能有实现方法呢?答案是JAVA8后允许接口方法有默认实现方式,从而大大提高了JAVA程序的向后兼容性问题。有兴趣的可以进入List源码看,除了两个默认实现方法外,其他都是需要实现的接口。default void sort(Comparator<? super E> c) {
Object[] a = this.toArray();
Arrays.sort(a, (Comparator) c);
ListIterator<E> i = this.listIterator();
for (Object e : a) {
i.next();
i.set((E) e);
}
}
default void replaceAll(UnaryOperator<E> operator) {
Objects.requireNonNull(operator);
final ListIterator<E> li = this.listIterator();
while (li.hasNext()) {
li.set(operator.apply(li.next()));
}
}
到此,大致介绍了一下Collection和Collections的区别。现在大家知道他俩的区别了吧?一个是集合接口,是集合的父亲,下面有了堆的集合孩子。而Collections就是这些孩子的好朋友,提供了集合的了些工具,一些很方便的方法。后续我会一一带大家进行各集合的源码分析。让原理实现不再神秘。最后附上一张大图