在Java集合類框架中提供了兩大核心接口:Collection
接口和Map
接口,這兩個接口是相對獨立的。
Collection接口的操作形式與之前編寫鏈表的操作形式類似,每一次進行數據操作的時候只對單個對象進行處理。
Collection接口是單個集合保存的最大父接口。
定義:
public interface Collection<E> extends Iterable<E>
JDK1.5之後Collection追加有泛型,避免了ClassCastException,裏面所有保存的數據應該是相同的。
當然,在開發過程中,我們還是很少會直接使用Collection接口,因爲Collection接口只是一個存儲數據的標準,並不能區分存儲類型。
所以它有兩個子接口:List
接口和Set
接口,繼承關係如下:
Collection中兩個重要的方法add()和iterator(),子接口中都有
List接口
在實際開發過程中,List的使用頻率可以達到Collection使用的80%,在進行集合處理的時候優先考慮List。
List接口有兩個重要的擴充方法,如下:
List接口與Collection接口相比最大的特點就在於,List接口有一個get()方法,可以根據索引獲取值
,由於List本身還是接口,要對它進行實例化,就要用到子類。List有三個子類:ArrayList,Vector,LinkedList,結構如下:
ArrayList子類(優先考慮)
通過代碼來看一下ArrayList的一些方法:
public class TestArrayList {
public static void main(String[] args) {
List<String > list=new ArrayList<String>();
list.add("hello");
//重複元素
list.add("hello");
list.add("Java");
System.out.println("集合大小爲:"+list.size()+" 集合是否爲空:"+list.isEmpty());
for (int i=0;i<list.size();i++){
//get()方法
System.out.println(list.get(i));
}
System.out.println("刪除hello後");
list.remove("hello");
System.out.println("集合大小爲:"+list.size()+" 集合是否爲空:"+list.isEmpty());
for (int i=0;i<list.size();i++){
System.out.println(list.get(i));
}
System.out.println(list.contains("hello"));
System.out.println(list.contains("ABC"));
System.out.println(list);
}
}
通過上述代碼我們可以發現,List允許保存重複數據。
另外,get()方法是List子接口提供的。如果現在操作的是Collection接口,那麼對於此時的數據取出只能夠將集合變爲對象數組操作。如下:
Collection<String > list=new ArrayList<String>();
list.add("hello");
list.add("hello");
list.add("Java");
// 操作以Object爲主,有可能需要向下轉型,就有可能產生ClassCastException
Object[] objects=list.toArray();
System.out.println(Arrays.toString(objects));
用Collection接口很容易產生ClassCastException異常,因此在開發過程中儘量少用。
Vector子類(舊的子類,使用較少)
Vector是從JDK1.0提出的,而ArrayList是從JDK1.2提出的。
用例:
List<String > list=new Vector<String>();
list.add("hello");
list.add("hello");
list.add("Java");
System.out.println(list);
ArrayList和Vector的區別
歷史時間:ArrayList是從JDK1.2提出的,Vector是從JDK1.0提出的
處理形式:ArrayList是異步處理,性能較高,而Vector是同步處理,性能較低
數據安全:ArrayList是線程不安全的,而Vector是線程安全的。
輸出形式:ArrayList支持Iterator、ListIterator、foreach;Vector支持Iterator、ListIterator、foreach、Enumeration。
LinkedList子類
範例
package www.bit.java.test;
import java.util.LinkedList;
import java.util.List;
public class TestDemo {
public static void main(String[] args) {
List<String> list = new LinkedList<>() ;
list.add("hello") ;
list.add("hello") ;
list.add("bit") ;
System.out.println(list) ;
list.remove("hello") ;
System.out.println(list) ;
}
}
ArrayList和LinkedList的區別
- 觀察ArrayList源碼,可以發現ArrayList裏面存放的是一個數組,如果實例化此類對象時傳入了數組大
小,則裏面保存的數組就會開闢一個定長的數組,但是後面再進行數據保存的時候發現數組個數不夠了
會進行數組動態擴充。 所以在實際開發之中,使用ArrayList最好的做法就是設置初始化大小。- LinkedList:是一個純粹的鏈表實現,與之前編寫的鏈表程序的實現基本一樣(人家性能高)。
ArrayList封裝的是數組;LinkedList封裝的是鏈表。ArrayList時間複雜度爲1,而LinkedList的複雜度爲
n。
Set接口
Set接口和List接口的最大區別在於Set接口中的內容是不允許重複的,並且Set接口並沒有對Collection接口進行擴充,而List接口對Collection接口擴充了。因此Set接口中沒有get()方法。
Set也有兩個子接口:HashSet(無序存儲)
和TreeSet(有序存儲)
HashSet子類
看一段代碼:
Set<String> set=new HashSet<String>();
set.add("hello");
set.add("hello");
set.add("Java");
System.out.println(set);
可以發現:結果只有一個hello,而且輸出的順序是無序的。
TreeSet子類
使用範例:
Set<Integer> set=new TreeSet<Integer>();
set.add(1);
set.add(1);
set.add(2);
set.add(3);
set.add(4);
set.add(5);
System.out.println(set);
可以看到,TreeSet同樣不允許重複,輸出的結果是有序的,並且是升序的。
對象判斷必須兩個方法equals()、hashCode()返回值都相同才判斷爲相同