java SE 1.8中Collection介面分析
Collection介面作為List, Set, Queue等的父類,在平時還是非常常用的。Java8在之前Collection介面的基礎上,使用default關鍵字增加了一些非抽象方法。現在就著重來研究下。
首先看Collection介面的宣告
public interface Collection<E> extends Iterable<E>
首先,Collection是一個模板介面,意味著能夠接受各種物件作為元素型別。它繼承了Iterable,因此,可以使用迭代器來遍歷集合的元素。
下面具體看看宣告的方法。
1. int size() 方法
/**
* Returns the number of elements in this collection. If this collection
* contains more than <tt>Integer.MAX_VALUE</tt> elements, returns
* <tt>Integer.MAX_VALUE</tt>.
*
* @return the number of elements in this collection
*/
int size();
size() 方法返回Collection集合中元素的個數,返回值是int型別的,此方法的註釋中寫道,如果元素個數大於int能表示的最大數量,則只能返回int所能表示的最大數。
2. boolean isEmpty() 方法
這個很簡答,就不說了
3. boolean contain(Object o) 方法
如果Collection中包含至少一個o物件,則返回true。
4. Iterator<E> iterator() 方法
/**
* Returns an iterator over the elements in this collection. There are no
* guarantees concerning the order in which the elements are returned
* (unless this collection is an instance of some class that provides a
* guarantee).
*
* @return an <tt>Iterator</tt> over the elements in this collection
*/
Iterator<E> iterator();
返回此Collection的迭代器。迭代器並不能保證返回元素的順序,除非繼承Collection的實現類做了具體的實現來保證迭代器輸出的順序。
5. Object[] toArray() 方法
/**
* Returns an array containing all of the elements in this collection.
* If this collection makes any guarantees as to what order its elements
* are returned by its iterator, this method must return the elements in
* the same order.
*
* <p>The returned array will be "safe" in that no references to it are
* maintained by this collection. (In other words, this method must
* allocate a new array even if this collection is backed by an array).
* The caller is thus free to modify the returned array.
*
* <p>This method acts as bridge between array-based and collection-based
* APIs.
*
* @return an array containing all of the elements in this collection
*/
Object[] toArray();
此方法將Collection元素返回成陣列。值得注意的是,返回陣列是重新分配空間儲存的,實際就是所有元素的副本。呼叫者獲取資料之後可以隨意更改而不影響原集合。
6. <T> T[] toArray(T[] a) 方法
/**
* Returns an array containing all of the elements in this collection;
* the runtime type of the returned array is that of the specified array.
* If the collection fits in the specified array, it is returned therein.
* Otherwise, a new array is allocated with the runtime type of the
* specified array and the size of this collection.
*
* <p>If this collection fits in the specified array with room to spare
* (i.e., the array has more elements than this collection), the element
* in the array immediately following the end of the collection is set to
* <tt>null</tt>. (This is useful in determining the length of this
* collection <i>only</i> if the caller knows that this collection does
* not contain any <tt>null</tt> elements.)
*
* <p>If this collection makes any guarantees as to what order its elements
* are returned by its iterator, this method must return the elements in
* the same order.
*
* <p>Like the {@link #toArray()} method, this method acts as bridge between
* array-based and collection-based APIs. Further, this method allows
* precise control over the runtime type of the output array, and may,
* under certain circumstances, be used to save allocation costs.
*
* <p>Suppose <tt>x</tt> is a collection known to contain only strings.
* The following code can be used to dump the collection into a newly
* allocated array of <tt>String</tt>:
*
* <pre>
* String[] y = x.toArray(new String[0]);</pre>
*
* Note that <tt>toArray(new Object[0])</tt> is identical in function to
* <tt>toArray()</tt>.
*
* @param <T> the runtime type of the array to contain the collection
* @param a the array into which the elements of this collection are to be
* stored, if it is big enough; otherwise, a new array of the same
* runtime type is allocated for this purpose.
* @return an array containing all of the elements in this collection
* @throws ArrayStoreException if the runtime type of the specified array
* is not a supertype of the runtime type of every element in
* this collection
* @throws NullPointerException if the specified array is null
*/
<T> T[] toArray(T[] a);
這個方法和前一個方法方法名相同,但是區別很大。首先,此方法是一個模板方法,可以動態指定型別,前一個方法只返回Object型別的陣列;其次,前一個方法是新分配一段空間來儲存複製物件,而此方法接受一個陣列引數。
此函式接受一個陣列引數,會嘗試將元素放入指定的陣列,如果型別可以成功轉換,並且陣列引數T[] a的空間足以放下所有元素,則將元素放入a中,如果a還有剩餘空間,則填充為null。如果a空間不夠,則會新建一個陣列,並將元素轉換為指定型別加入到陣列中並返回。
例如
public void run() {
List<Order> orderList1 = new ArrayList<Order>();
orderList1.add(new Order("0001", "man", 100)); //Order(orderId, createdby, amount)
orderList1.add(new Order("0002", "man", 1000));
orderList1.add(new Order("0003", "man", 10000));
Order[] orderContainer1 = new Order[4];
Order[] orderContainer2 = orderList1.toArray(orderContainer1);
System.out.println(orderContainer1 == orderContainer2); //true
System.out.println(orderContainer1.length); //4
Order[] orderContainer3 = new Order[1];
Order[] orderContainer4 = orderList1.toArray(orderContainer3);
System.out.println(orderContainer1 == orderContainer3); //false
System.out.println(orderContainer3.length); //1
System.out.println(orderContainer4.length); //4
}
6. boolean add(E e) 方法
向Collection中新增一個元素。新增方式和具體實現相關,例如List可以新增重複元素,而向Set中新增重複元素返回就是false。
7. boolean remove(Object o) 方法
從Collection中移除一個元素。
8. boolean containsAll(Collection<?> c) 方法
如果Collection中包含所有c中的元素,則返回true。
9. boolean addAll(Collection<?> c) 方法
向Collection中新增所有c中的元素。
10. boolean removeAll(Collection<?> c) 方法
從Collection中刪除所有c中的元素。
11. default boolean removeIf(Predicate<? super E> filter) 方法
/**
* Removes all of the elements of this collection that satisfy the given
* predicate. Errors or runtime exceptions thrown during iteration or by
* the predicate are relayed to the caller.
*
* @implSpec
* The default implementation traverses all elements of the collection using
* its {@link #iterator}. Each matching element is removed using
* {@link Iterator#remove()}. If the collection's iterator does not
* support removal then an {@code UnsupportedOperationException} will be
* thrown on the first matching element.
*
* @param filter a predicate which returns {@code true} for elements to be
* removed
* @return {@code true} if any elements were removed
* @throws NullPointerException if the specified filter is null
* @throws UnsupportedOperationException if elements cannot be removed
* from this collection. Implementations may throw this exception if a
* matching element cannot be removed or if, in general, removal is not
* supported.
* @since 1.8
*/
default boolean removeIf(Predicate<? super E> filter)
此方法是java 1.8版本之後新增的。default關鍵字允許在介面類中存在非抽象方法。引數接受一個Predicate型別的函式,通常是lambda表示式。此函式作用是遍歷整個Collection,刪除符合Predicate filter的條目。
例如,
public void run() {
List<Order> orderList1 = new ArrayList<Order>();
orderList1.add(new Order("0001", "man", 100)); //Order(orderId, createdby, amount)
orderList1.add(new Order("0002", "man", 1000));
orderList1.add(new Order("0003", "man", 10000));
orderList1.removeIf((o)-> o.getAmount()> 100);
System.out.println(orderList1.size()); //1
}
上例中接受了lambda表示式(o)-> o.getAmount()> 100,此表示式判斷order amount是否大於100,如果大於100就返回true。配合removeIf可以刪除Collection中所有amount大於100的order。12. boolean retainAll(Collection<?> c) 方法
只保留引數c中存在的元素,其他Collection中的引數都刪除。
13. void clear() 方法
清楚Collection中所有元素。
14. boolean equals(Object o) 方法
判斷物件o是否和Collection相等,具體相等的判斷方法有實現類自己決定。
15. int hashCode() 方法
返回Collection的雜湊值。
16. default Spliterator<E> spliterator() 方法
這個又是Java 1.8 中新增的函式,使用default關鍵字提供了預設實現。此方法返回一個Spliterator,Spliterator也是Java 1.8 中引入的新的一種迭代器,除了擁有一般迭代器的遍歷Collection功能,還可以對目標集合進行分割,這種分割特性特別適合多執行緒處理Collection。對於Spliterator可以參考https://blog.logentries.com/2015/10/java-8-introduction-to-parallelism-and-spliterator/,我也會在以後發表分析Spliterator的文章。舉個小例子。
public void run() {
List<Order> orderList1 = new ArrayList<Order>();
Set<Order> orderSet1 = new HashSet<>();
for (int i = 0; i < 6; i++){
Order temp = new Order(String.valueOf(i), "man", 100);
orderList1.add(temp);
orderSet1.add(temp);
}
Spliterator<Order> orderSpliter = orderList1.spliterator();
Spliterator<Order> orderSpliter1 = orderSpliter.trySplit();
System.out.println(orderSpliter.getExactSizeIfKnown()); //結果3
System.out.println(orderSpliter1.getExactSizeIfKnown()); //結果3
}
以上程式碼使用Spliterator將一個陣列列表分割了一次,得到一個大小為3的新的Spliterator (orderSpliter1),而原來的Spliterator也被分割(orderSpliter),從6變成了3。
17. default Stream<E> stream() 和 default Stream<E> parallelStream() 方法
Java 1.8 的引入的方法,返回流物件,和我們之前的inputstream 和outputstream是不同的概念。借用Stream物件,可以方便的對集合進行聚合、大批量操作等等。它結合lambda表示式,可以簡化程式碼,使用parallelStream充分利用多核計算機的計算能力,提高處理效率。之後我的部落格也會詳細分析Stream的原理和使用。
Collection介面在Java 1.8 中新增了很多新的功能,包括Spliterator、Stream、和結合lambda表示式的操作。感覺Java 1.8 中引入了很多令人興奮的新內容,很值得我們仔細分析和研究。
相關文章
- Java™ 教程(Collection介面)Java
- Java Collection介面 ArrayList集合(容器)Java
- Java中Collection和Iterator介面Java
- Java學習--java中的集合框架、Collection介面、list介面Java框架
- Collection介面
- JAVA集合詳解(Collection和Map介面)Java
- 「譯」Java集合框架系列教程三:Collection介面Java框架
- Java學習關於集合框架的基礎介面--Collection介面Java框架
- Java集合系列之Collection與Map介面巨集觀把控Java
- Java集合-CollectionJava
- java se docJava
- [Java基礎]collectionJava
- Java:Collection集合、泛型Java泛型
- Java Collection集合面試題Java面試題
- JAVA SE基礎(二)Java
- Java SE 21 新增特性Java
- Java SE 20 新增特性Java
- Java se 複習05Java
- Java SE 22 新增特性Java
- Java SE 23 新增特性Java
- 集合原始碼分析[1]-Collection 原始碼分析原始碼
- 【Java】【集合】collection介面常見方法、集合轉陣列toArray()、帶ALL的方法Java陣列
- 【Java基礎】--Java容器剖析:collection容器Java
- Java 的 Collection 與 List 集合Java
- Java Collection或Map的同步Java
- Java Collection、Map集合總結Java
- Java Platform SE 8(Java™程式語言)JavaPlatform
- 【Java X 原始碼剖析】Collection的原始碼分析-JDK1.8-仍在更新Java原始碼JDK
- Java SE 基礎知識Java
- Java(SE)內容回顧Java
- Java SE 語法學習Java
- Java8 Lambda 之 Collection StreamJava
- Java 集合深入理解(3):CollectionJava
- 詳解java的Collection和MapJava
- 分析J2SE和J2EE的Java剖析程式JProfilerJava
- 深入理解Java中的Garbage CollectionJava
- Java的垃圾回收(Garbage Collection)機制Java
- Java SE 6 新特性: Java DB 和 JDBC 4.0JavaJDBC