List集合代表一個元素有序、可重複的集合,集合中每個元素都有其對應的順序索引。List集合允許使用重複元素,可以通過索引來通路指定位置的集合元素。List判斷兩個對象相等隻要通過equals方法比較傳回true即可。
List接口
Java 8改進了List接口和ListIterator接口:List作為Collection接口的子接口,當然可以使用Collection接口裡額全部方法。而且由于List是有序集合,是以List集合裡增加了一些根據索引來操作集合元素的方法,還為List接口添加了如下兩個預設方法:
void replaceAll(UnaryOperator operator)
:根據operator指定的計算規則重新設定List集合的所有元素。
void sort(Comparator c)
:根據Comparator參數對List集合的元素排序。sort方法需要一個Comparator對象來控制元素排序,程式可使用Lambda表達式來作為參數;而replaceAll方法需要一個UnaryOperator來替換所有集合元素,UnaryOperator也是一個函數式接口,是以程式也可使用Lambda表達式作為參數。
import java.util.ArrayList;
import java.util.List;
public class ListTest {
public static void main(String[] args) {
List books = new ArrayList();
// 向books集合中添加三個元素
books.add(new String("輕量級Java EE企業應用實戰"));
books.add(new String("瘋狂Java講義"));
books.add(new String("瘋狂Andriod講義"));
System.out.println(books);
// 将新字元串對象插入在第二個位置
books.add(1, new String("瘋狂Ajax講義"));
for(int i = 0; i < books.size(); i++){
System.out.println(books.get(i));
}
// 删除第三個元素
books.remove(2);
System.out.println(books);
// 判斷指定元素在List集合中的位置:輸出1,表明位于第二位
System.out.println(books.indexOf(new String("瘋狂Ajax講義")));
// 将第二個元素替換成新的字元串對象
books.set(1, new String("瘋狂Java講義"));
System.out.println(books);
// 将books集合的第二個元素(包括)到第三個元素(不包括)截取成子集合
System.out.println(books.subList(1, 2));
}
}
List book1 = new ArrayList();
// 向book1集合中添加4個元素
book1.add(new String("輕量級Java EE企業應用實戰"));
book1.add(new String("瘋狂Java講義"));
book1.add(new String("瘋狂Andriod講義"));
book1.add(new String("瘋狂iOS講義"));
// 使用目标類型為Comparator的Lambda表達式對List集合排序
book1.sort((o1,o2)->(((String)o1).length()-((String)o2).length()));
System.out.println(book1);
// 使用目标類型為UnaryOperator的Lambda表達式來替換集合中所有元素
// 該Lambda表達式控制使用每個字元串的長度作為新的集合元素
book1.replaceAll(ele->((String)ele).length());
System.out.println(book1);
程式試圖删除一個A對象,List将會調用該A對象的equals方法依次與集合元素進行比較,如果該equals方法以某個集合元素作為參數時傳回true,List将會删除該元素-A類重寫了equals方法,該方法總是傳回true。所有每次從List集合中删除A對象時,總是删除List集合中的第一個元素。
class A
{
@Override
public boolean equals(Object obj) {
return true;
}
}
public class ListTest {
public static void main(String[] args) {
List bookA = new ArrayList();
bookA.add(new String("輕量級Java EE企業應用實戰"));
bookA.add(new String("瘋狂Java講義"));
bookA.add(new String("瘋狂Andriod講義"));
System.out.println(bookA);
//删除集合中的A對象,将導緻第一個元素被删除
bookA.remove(new A());
System.out.println(bookA);
//删除集合中的A對象,再次删除集合中的第一個元素
bookA.remove(new A());
System.out.println(bookA);
}
}
ListIterator
與Set隻提供了一個iterator()方法不同,LIst還額外提供了一個listIterator方法,該方法傳回一個ListIterator對象,ListIterator接口繼承自Iterator接口,提供了專門操作List方法。ListIterator接口在Iterator接口基礎上增加了如下方法:boolean has Previous()傳回該疊代器關聯的集合是否還有上一個元素,Object previous()傳回該疊代器的上一個元素,void add(Object o)在指定位置插入一個元素。ListIterator增加了向前疊代的功能(Iterator隻能向後疊代),而且ListIterator還可以通過add()方法向List集合中添加元素(Iterator隻能删除元素)。
String[] book = {"輕量級Java EE企業應用實戰", "瘋狂Java講義", "瘋狂Andriod講義", "瘋狂iOS講義"};
List bookList = new ArrayList();
for(int i = 0; i < book.length; i++)
bookList.add(book[i]);
ListIterator lit = bookList.listIterator();
while(lit.hasNext())
System.out.println(lit.next());
System.out.println("===反向疊代===");
while(lit.hasPrevious())
System.out.println(lit.previous());
ArrayList和Vector實作類
ArrayList和Vector類都是基于數組實作的List類,是以ArrayList和Vector封裝了一個動态的允許再配置設定的Object[]數組。ArrayList和Vector對象使用initialCapacity參數來設定該數組的長度,當向ArrayList和Vector中添加元素超出了該數組的長度時,它們的initialCapacity會自動增加。如果向ArrayList和Vector集合中添加大量元素時,可使用ensureCapacity(int minCapacity)方法一次性地增加initialCapacity。這樣可以減少重配置設定的次數,提供性能。如果開始就知道ArrayList和Vector集合要儲存多少個元素,則可再建立它們時就指定initialCapacity大小。如果建立空的ArrayList或Vector集合時不指定initialCapacity參數,則Object[]數組的長度預設為10。ArrayList和Vector提供了如下兩個方法重新配置設定Object[]數組:void ensureCapacity(int minCapacity()将ArrayList和Vector集合的Object[]數組長度增加大于或等于minCapacity值,void trimToSize()調整ArrayList和Vector集合的Object[]數組長度為目前元素的個數。調用該方法可減少ArrayList和Vector集合對象占用的存儲空間。
Vector是一個古老的集合(從JDK 1.0就有了),那時候還沒有提供集合架構,是以Vector裡提供了一些方法名很長的方法,例如addElement(Object obj),實際上這個方法與add(Object obj)沒有任何差別。從JDK 1.2以後,Java提供了系統的集合架構,就将Vector改為實作List接口,作為List的實作之一,進而導緻Vector裡有一些功能重複的方法。Vector的系列方法中方法名更短的方法屬于後來新增的方法,方法名更長的方法則是Vector原有的方法。而ArrayList開始就作為List的主要實作類,是以沒有那些方法名很長的方法。ArrayList是線程不安全的,必須手動保證該集合的同步性;但Vector集合是線程安全的,無序保證同步性。
Vector還提供了一個Stack子類,用于模拟棧,提供可如下方法peek、pop、push。由于Stack繼承了Vector,是以也是古老的Java集合類,它同樣是線程安全的、性能較差的。
固定長度的List
public class FixedSizeList
{
public static void main(String[] args)
{
List fixedList = Arrays.asList("瘋狂Java講義", "輕量級Java EE企業應用實戰");
// 擷取實作類,輸出Arrays$ArrayList
System.out.println(fixedList.getClass());
// 使用方法引用周遊集合元素
fixedlist.forEach(System.out::println);
// 試圖增加、删除元素都會引發UnsupportedOperationException異常
fixedList.add("瘋狂Andriod講義");
fixedList.add("瘋狂Java講義");
}
}