java常見的4個類集接口collection,map,List,set

在類集以前,想保存數組的話就只能是使用對象數組。可是數組有長度的限制,而若是使用鏈表這種數據結構的話,又會比較麻煩。類集框架就是來解決上面的問題的,就是實現一個動態的數組,包裝上數據結構,所以就會有類集的出現。類集接口有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;
    }

未完待續。。。。

相關文章
相關標籤/搜索