在类集以前,想保存数组的话就只能是使用对象数组。可是数组有长度的限制,而若是使用链表这种数据结构的话,又会比较麻烦。类集框架就是来解决上面的问题的,就是实现一个动态的数组,包装上数据结构,所以就会有类集的出现。类集接口有collection,map,List,set,Iterator,ListIterator,Enumeraation,java
SortedMap,Queue,Map.Entry,在面试时就会常常遇到前面四个的问题。面试
1、Collection接口数组
Collection接口的定义以下安全
public interface Collection<E> extends Iterable<E>
从接口的定义能够看出来,这里是使用的泛型的定义,避免发生ClassCastException的异常。Collection接口是单值的存放最大父接口,能够向其中保存多个对象。继承于Iterable接口,Iterable接口已是最大的接口了, 它主要是告诉咱们它是能够进行迭代的。数据结构
public interface Iterable<T> {
Collection接口的全部方法以下:框架
/*2017/11/3:这两天在看码的时候才注意到一个小细节,那就是这个集合定义的许多方法都是返回的boolean类型,以前都没有注意到过。看下面的代码,其中的一个add方法,增长值的时候是这样增长的,先把这个list的容量加1,而后把数据才赋进去,前面两步没有问题的时候才会返回true,表面增长成功。源码中大部分的方法都是这样的。*/dom
public boolean add(E e) { ensureCapacityInternal(size + 1); // Increments modCount!! elementData[size++] = e; return true; }
遍历Collection接口,不论Collection的实际类型如何,由于他是继承于Iterable接口,因此它都支持一个iterator()的方法,该方法返回一个迭代子,使用该迭代子便可逐一访问Collection中每个元素:异步
Iterator it=collection.iterator();//得到一个迭代子 while(it.hasNext()){ Objectobj=it.next();//获得下一个元素 }
也可使用foreach输出函数
for(元素类型t 元素变量x : 遍历对象obj){ 引用了x的java语句; } for (String x : list) { System.out.println(x); }
Collection接口虽然是集合的最大接口,可是若是直接使用Colllection接口进行操做,则表示操做的含义不明确,所以会通常使用他的子接口。Collection的子接口有List,Set,Queue,和SortedSet四个。List能够存放重复的内容,Set不能存放重复的内容,全部重复的内容靠hashCode()和equals()两个方法区别。测试
2、List接口
List是Collection的子接口,其中能够保存各个重复的内容。接口的定义:
public interface List<E> extends Collection<E>
List接口扩充了Collection接口,拥有比其更为普遍的方法,List接口的全部扩展方法以下:
一、ArrayList子类
ArrayList子类能够为List接口进行实例化。ArrayList继承了AbstractList类,
public class ArratList<E> extends AbstractList<E> implements List<E> ,RandomAccess,Cloneable,Serializable
而AbstractList类实现了List接口。
public abstract class AbstractList<E> extends AbstractCollection <E> implements List<E>
所以能够直接使用ArrayList为List接口进行实例化。
public class ArrayListAdd { public static void main(String []args){ List<String> allList=new ArrayList<String>(); Collection<String> allCollection=new ArrayList<String>(); allList.add("hello"); allList.add(0,"world");//在0位置添加元素 System.out.println(allList);//[world, hello] allCollection.add("hi"); allCollection.add("MLDN"); allList.addAll(allCollection);//在最后添加元素 allList.addAll(0, allCollection);//在0位置添加元素 System.out.println(allList);//[hi, MLDN, world, hello, hi, MLDN] } }
每个list都会被赋一个初始的容量,初始容量为10
/** * Constructs an empty list with an initial capacity of ten. */
从上面的结果能够看出来,使用List中的add(int index,E)方法能够在集合中的指定位置增长元素,而add(E)只是在最后面添加。
remove()方法能够去除指定位置的元素,或者去除指定内容的元素。
allList.remove(0);//移除 System.out.println(allList);//[MLDN, world, hello, hi, MLDN] allList.remove("MLDN"); System.out.println(allList);//[world, hello, hi, MLDN] allList.remove("MLDN"); System.out.println(allList);//[world, hello, hi]
每次能够去除一个对象remove(Object o),每次去除一组对象removeAll(Collection<?> c),若是有多个相同类型的元素则须要屡次去除;
经过取得长度的方法size(),而后使用get()方法能够将集合的指定位置的内容输出。
System.out.println(allList.size());//3 System.out.println(allList.get(1));//hello
经过头Array()方法能够将集合变为数组。以及截取集合subList(int,int)方法,是否为空isEmpty()方法,查找字符串位置indexOf(String)方法等。
二、Vector子类
Vector子类是比较老的一个类了,一样是继承于AbstractList<E>接口,
public class Vector<E> extends AbstractList<E> implements List<E>, RandomAccess, Cloneable, java.io.Serializable {
由于和arraylist的区别不大,测试代码就不写了,arraylist是异步处理,是非线程安全的,只能使用Iterable和foreach输出。而Vector是同步出来,是线程安全的,可使用Iterable,Enumeration和foreach输出
三、Linkedlist
LinkedList是一个链表的操做类,定义以下
public class LinkedList<E> extends AbstractSequentialList<E> implements List<E>, Deque<E>, Cloneable, java.io.Serializable
这个类不只实现了list接口还实现了Duque接口,双向队列(Deque),是Queue的一个子接口,双向队列是指该队列两端的元素既能入队(offer)也能出队(poll),若是将Deque限制为只能从一端入队和出队,则可实现栈的数据结构。对于栈而言,有入栈(push)和出栈(pop),遵循先进后出原则,Queue接口是队列接口,是先进先出的方式。也就是说LinkedList类是双向列表,列表中的每一个节点都包含了对前一个和后一个元素的引用.
public interface Deque<E> extends Queue<E> { /**A linear collection that supports element insertion and removal at * both ends. The name <i>deque</i> is short for "double ended queue"
最后Queue接口是实现了Collection接口
public interface Queue<E> extends Collection<E> {
经过上面能够看到LinkedList类是双向列表,列表中的每一个节点都包含了对前一个和后一个元素的引用.这个类的两个构造方法
public LinkedList() { }//生成空的链表 public LinkedList(Collection<? extends E> c) { this(); addAll(c); }// 复制构造函数
其实现的方法也比较多,这里就不一一介绍了,须要用的时候查一下就好了。
三 set接口
set接口也是collection接口的子接口,可是和他们不同的地方就是它不能包含不同的重复的对象元素。
一、HashSet子类
hashset是set接口的子类,存放的元素是无序但不可重复。
public static void main(String[] args) { // TODO 自动生成的方法存根 Set<String> allSet=new HashSet<String>(); allSet.add("a"); allSet.add("a"); allSet.add("b"); allSet.add("b"); allSet.add("b"); allSet.add("c"); allSet.add("f"); allSet.add("s"); allSet.add("d"); System.out.println(allSet);//调用tostring()方法 } 输出[a, b, c, s, d, f]
二、TreeSet子类
TreeSet子类是set接口的子类,存放的元素是有序并且也不能够重复。这里的有序是指在输入数据之后他会进行一个自动的排序。
public class TreeSet<E> extends AbstractSet<E> implements NavigableSet<E>, Cloneable, java.io.Serializable {
他是继承了AbstractSet类,AbstractSet类又实现了Set接口
public abstract class AbstractSet<E> extends AbstractCollection<E> implements Set<E> {
下面是最简单的一个TreeSet的测试
Set<String> allset=new TreeSet<String>(); allset.add("s"); allset.add("a"); allset.add("a"); allset.add("b"); allset.add("b"); allset.add("b"); allset.add("c"); allset.add("f"); allset.add("s"); allset.add("d"); System.out.println(allset); 输出结果 [a, b, c, d, f, s]
TreeSet的排序看起来就是这样,它会将全部非重复的元素就行排序,而后存储起来。咱们看它的源码,在调用add方法之后,首先经过判断已经存储了这个值,而后他会返回一个boolean值。
public boolean add(E e) { return m.put(e, PRESENT)==null; }
未完待续。。。。