JavaSE——类集(上)(Collection、List、Iterator、forEach)
第2節 集合(上)
因為已經有數據結構的基礎,前面有關數據結構的知識就不單獨整理了,直接上Java的集合類的知識。
一、類集(集合類)
1.1 集合概述
集合: 集合是java中提供的一種容器,可以用來存儲多個數據。
集合和數組的區別:
-
數組的長度固定,集合的長度可變;
-
數組中存儲的是同一個類型的元素,可以存儲基本數據類型值,集合存儲的都是對象,而且對象的類型可以不一致,在開發中一般當對象多的時候,使用集合來進行存儲。
對象數組有哪些問題?普通的對象數組的最大問題在于數組中的元素個數是固定的,不能動態的擴充大小,所以最早的時候可以通過鏈表實現一個動態對象數組,但是這樣畢竟太復雜了,所以在Java中為了方便用戶操作各個數據結構,引入了類集的概念,有時候就可以把類集稱為java對數據結構的實現 。
1.2 集合框架
JavaSE提供了滿足各種需求的API,在使用這些API前,先了解其繼承與接口操作架構,才能了解何時采用哪個類,以及類之間如何彼此合作,從而達到靈活運用。
集合按照其存儲結構可以分為兩大類,分別是單列集合java.util.Collection和雙列集合java.util.Map。
類集中最大的幾個操作接口:Collection、Map、Iterator,這三個接口為以后要使用的最重點的接口。所有的類集操作的接口或類都在java.util包中。
Java類集的結構圖:
二、Collection接口
2.1 Collection介紹
Collection接口是在整個Java類集中保存單值 的最大操作父接口(Map是保存雙值/鍵值對的最大操作父接口),里面每次操作的時候都只能保存一個對象的數據,此接口定義在java.util包中。
有兩個重要的子接口,分別是java.util.List和java.util.Set。其中,List的特點是元素有序、元素可重復;Set的特點是元素無序,而且不可重復。List接口的主要實現類有 java.util.ArrayList和 java.util.LinkedList , Set接口的主要實現類有 java.util.HashSet和java.util.TreeSet 。
此接口定義如下:
public interface Collection<E> extends Iterable<E>注意這里使用了泛型,所以后面在使用具體實現類的時候都需要傳入具體類型。
常用方法:
其中像add、iterator、size等方法很常用,此接口的全部子類或子接口就將全部繼承以上的方法。
但是,在開發中不會直接使用 Collection接口,而比較常使用它的子接口 List和 Set。
三、List接口
3.1 List概述
習慣性地會將實現了List接口的對象稱為List集合,在List集合中允許出現重復元素,所有的元素是以一種線性方式存儲的,可以通過索引來訪問集合中的指定元素。
List接口的特點:
它是一個元素存取有序 的集合,例如:存元素的順序是11、22、33,那么集合中元素的存儲就是按照11、22、33的順序完成的。(與Set相對)
它是一個帶有索引 的集合,通過索引可以精確地操作集合中的元素(與數組的索引是一個道理)。
集合中可以有重復 的元素,通過元素的equals方法,來比較是否為重復的元素。
3.2 常用方法
除了繼承了Collection接口的方法外,還有如下常用的擴充方法:了解了List接口之后,需要找到此接口的實現類,常用的實現類由如下三個:
ArrayList(95%) 、 Vector(4%) 、 LinkedList(1%)
3.3 ArrayList類
ArrayList是 List接口的子類, 此類的定義如下:
public class ArrayList<E> extends AbstractList<E> implements List<E>, RandomAccess, Cloneable, SerializableArrayList集合數據存儲的結構是數組結構,元素增刪慢,查找快,由于日常開發中使用的最多的功能為查詢數據、遍歷數據,所以ArrayList是最常用的集合。
3.3.1 構造方法
這里涉及到一個容易被問的地方,初始容量是一開始就給了容量為10的空間嗎?
這要從源碼來解釋:
ArrayList<String> all = new ArrayList<String>();從創建ArrayList開始,進入空參數構造方法:
public ArrayList() {this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA; }來查看DEFAULTCAPACITY_EMPTY_ELEMENTDATA的值:
private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {};是一個空的對象數組,所以使用無參構造方法新創建的ArrayList對象,初始容量是0。
但是一旦add一個數據進入,會發生什么,進入add看一下:
不論是哪種方式的add,當元素存滿了的時候,總要調用grow方法,下面來看grow方法:
private Object[] grow(int minCapacity) {return elementData = Arrays.copyOf(elementData, newCapacity(minCapacity)); }private Object[] grow() {return grow(size + 1); }無參grow方法會調用有參grow,并且傳入當前容量+1作為擴容的最小容量,有參grow內部是調用了Arrays.copyOf函數,將擴容后的數組給了elementData,再看newCapacity(minCapacity):
新擴容的容量為原來的1.5倍,如果比給定的最小容量小或相等,判斷elementData==DEFAULTCAPACITY_EMPTY_ELEMENTDATA,而DEFAULTCAPACITY_EMPTY_ELEMENTDATA就是空數組,所以一個新創建的ArrayList必然會進入到這里,返回了DEFAULT_CAPACITY, minCapacity兩個中的較大值,而新創建的minCapacity為1,這時來看一下DEFAULT_CAPACITY:
這才是初始容量為10的地方。
綜上,使用無參構造方法新創建的ArrayList對象起始的elementData為空數組,只有在加入一個元素的時候才會初始化為10.
3.3.2 具體使用
使用格式:
ArrayList<Integer> data = new ArrayList<>();例子:
package org.listdemo.arraylistdemo; import java.util.ArrayList; import java.util.List; public class ArrayListDemo01 {public static void main(String[] args) {List<String> all = new ArrayList<String>(); // 實例化List對象, 并指定泛型類型all.add("hello "); // 增加內容, 此方法從Collection接口繼承而來all.add(0, "LAMP ");// 增加內容, 此方法是List接口單獨定義的all.add("world"); // 增加內容, 此方法從Collection接口繼承而來System.out.println(all); // 打印all對象調用toString()方法} }結果如下: [LAMP , hello , world] package org.listdemo.arraylistdemo; import java.util.ArrayList; import java.util.List; public class ArrayListDemo02 {public static void main(String[] args) {List<String> all = new ArrayList<String>(); // 實例化List對象, 并指定泛型類型all.add("hello "); // 增加內容, 此方法從Collection接口繼承而來all.add(0, "LAMP ");// 增加內容, 此方法是List接口單獨定義的all.add("world"); // 增加內容, 此方法從Collection接口繼承而來all.remove(1); // 根據索引刪除內容, 此方法是List接口單獨定義的all.remove("world");// 刪除指定的對象System.out.print("集合中的內容是: ");for (int x = 0; x < all.size(); x++) { // size()方法從Collection接口繼承而來System.out.print(all.get(x) + "、 "); // 此方法是List接口單獨定義的}} }結果如下: 集合中的內容是: LAMP 、3.4 Vector類
3.4.1 概述與使用
與 ArrayList 一樣, Vector 本身也屬于 List 接口的子類, 此類的定義如下:
public class Vector<E> extends AbstractList<E> implements List<E>, RandomAccess, Cloneable, Serializable它的使用及操作與使用ArrayList本身基本沒有什么區別:
package org.listdemo.vectordemo; import java.util.List; import java.util.Vector; public class VectorDemo01 {public static void main(String[] args) {List<String> all = new Vector<String>(); // 實例化List對象, 并指定泛型類型all.add("hello "); // 增加內容, 此方法從Collection接口繼承而來all.add(0, "LAMP ");// 增加內容, 此方法是List接口單獨定義的all.add("world"); // 增加內容, 此方法從Collection接口繼承而來all.remove(1); // 根據索引刪除內容, 此方法是List接口單獨定義的all.remove("world");// 刪除指定的對象System.out.print("集合中的內容是: ");for (int x = 0; x < all.size(); x++) { // size()方法從Collection接口繼承而來System.out.print(all.get(x) + "、 "); // 此方法是List接口單獨定義的}} }結果為: 集合中的內容是: LAMP 、Vector 屬于 Java 元老級的操作類, 是最早的提供了動態對象數組的操作類, 在 JDK 1.0 的時候就已經推出了此類的使用,只是后來在 JDK 1.2 之后引入了 Java 類集合框架。但是為了照顧很多已經習慣于使用 Vector 的用戶,所以在JDK 1.2 之后將 Vector 類進行了升級了, 讓其多實現了一個 List 接口, 這樣才將這個類繼續保留了下來。
3.4.2 Vector與ArrayList類的區別(重點)
3.5 LinkedList類
3.5.1 概述
LinkedList集合數據存儲的結構是鏈表結構,方便元素添加、刪除的集合。
LinkedList是一個雙向鏈表。
3.5.2 使用
除了繼承的List中的方法外,還有一些關于隊列或棧操作的方法,以及涉及到首尾操作:
例子:
import java.util.LinkedList; import java.util.Queue; public class TestDemo {public static void main(String[] args) {Queue<String> queue = new LinkedList<String>();queue.add("A");queue.add("B");queue.add("C");int len=queue.size();//把queue的大小先取出來, 否則每循環一次, 移除一個元素, 就少一個元素, 那么queue.size()在變小, 就不能循環queue.size()次了。for (int x = 0; x <len; x++) {System.out.println(queue.poll());}System.out.println(queue);} }結果如下: A B C []四、Iterator迭代器(接口)
4.1 Iterator概述
在程序開發中,經常需要遍歷集合中的所有元素,針對這種需求,JDK專門提供了一個接口java.util.Iterator。也是Java集合中的一員,但是它與Collection、Map接口有所不同,Collection接口與Map接口主要用于存儲元素,而Iterator主要用于迭代訪問(即遍歷)Collection中的元素,因此Iterator對象也被稱為迭代器。
此接口定義如下: public interface Iterator<E>要想使用此接口, 則必須使用 Collection 接口, 在 Collection接口中規定了一個 iterator()方法, 可以用于為 Iterator 接口進行實例化操作,其實要到ArrayList類這一級別(因為是接口的實現類)中才對Iterator接口進行了實現。
4.2 方法
此接口定義了以下三個方法:
通過Collection接口為其進行實例化之后,一定要記住,Iterator中的操作指針是在第一條元素之上, 當調用next()方法的時候, 獲取當前指針指向的值并向下移動, 使用 hasNext()可以檢查序列中是否還有元素。
看個例子:
import java.util.ArrayList; import java.util.Collection; import java.util.Iterator; public class IteratorDemo01 {public static void main(String[] args) {Collection<String> all = new ArrayList<String>();all.add("A");all.add("B");all.add("C");all.add("D");all.add("E");Iterator<String> iter = all.iterator();while (iter.hasNext()) {// 判斷是否有下一個元素String str = iter.next(); // 取出當前元素System.out.print(str + "、 ");}} }結果如下: A、 B、 C、 D、 E、Iterator接口本身可以完成輸出的功能, 但是此接口只能進行由前向后的單向輸出。 如果要想進行雙向輸出, 則必須使用其子接口 —— ListIterator。
4.3 ListIterator(理解)
ListIterator是可以進行雙向輸出的迭代接口,是 Iterator的子接口, 此接口中定義了以下的操作方法:
看一下它的輸出:
import java.util.ArrayList; import java.util.List; import java.util.ListIterator; public class ListIteratorDemo01 {public static void main(String[] args) {List<String> all = new ArrayList<String>();all.add("A");all.add("B");all.add("C");all.add("D");all.add("E");ListIterator<String> iter = all.listIterator();System.out.print("從前向后輸出: ");while (iter.hasNext()) {System.out.print(iter.next() + "、 ");} System.out.print("\n從后向前輸出: ");while (iter.hasPrevious()) {System.out.print(iter.previous() + "、 ");}} }結果如下: 從前向后輸出: A、 B、 C、 D、 E、 從后向前輸出: E、 D、 C、 B、 A、但是, 此處有一點需要注意的是, 如果要想進行由后向前的輸出, 則首先必須先進行由前向后的輸出。
而且它的add方法也是在指向的位置插入,不是在末尾插入,總之,此接口一般使用較少,理解為主。
五、增強for循環
forEach:增強for循環,最早出現在C#中,用于迭代數組 或 集合(只能是Collection下的集合)
語法: for(數據類型 變量名:集合或數組的名稱) {}
作用: 代替傳統for循環的復雜寫法,進行了簡化。
看一段代碼即可,注意只能用于數組或Collection下的集合 :
package com.kaikeba.coreclasslibrary.set; import java.util.ArrayList; import java.util.Collection;public class foreach {public static void main(String[] args) {int[] arr = {6,5,4,2,1};//傳統for循環遍歷/*for(int i=0; i<arr.length; i++) {System.out.println(arr[i]);}*///forEach循環遍歷for(int a:arr) {System.out.println(a);}System.out.println("------------------------");ArrayList<String> data = new ArrayList<>();data.add("鋤禾日當午");data.add("汗滴禾下土");data.add("誰知盤中餐");data.add("粒粒皆辛苦");for(String s:data) {System.out.println(s);}} }結果如下: 6 5 4 2 1 ------------------------ 鋤禾日當午 汗滴禾下土 誰知盤中餐 粒粒皆辛苦總結
以上是生活随笔為你收集整理的JavaSE——类集(上)(Collection、List、Iterator、forEach)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: MATLAB编辑GUI界面
- 下一篇: JavaSE——异常处理(异常简介、tr