JavaSE之Collection集合
阿新 • • 發佈:2018-12-10
Collection集合
-
java.util.Collection 集合
集合可以儲存一組元素,並且提供了操作元素的相關方法。
-
常用的子介面:
- java.util.List 線性表 可重複 並且有序
- java.util.Set 不可重複
- 是否重複指的是元素是否可以重複,而判定是否重複的標準是依靠元素自身equals比較的結果。
public class CollectionDemo {
public static void main(String[] args) {
Collection c = new ArrayList();
/*
* boolean add(E e)
* 將給定元素新增到集合當中,當成功新增後方法
* 會返回true,新增失敗返回false
*/
c.add("one");
c.add("two");
c.add("three");
c.add("four");
c.add("five");
System.out.println(c);
/*
* int size()
* 獲取當前集合元素個數
*/
int size = c.size();
System.out.println("size:"+size);
/*
* boolean isEmpty()
* 判斷當前集合是否為空集(不含有任何元素)
*/
boolean isEmpty = c.isEmpty ();
System.out.println("是否為空集:"+isEmpty);
/*
* void clear()
* 清空集合
*/
c.clear();
System.out.println("集合已清空");
System.out.println("size:"+c.size());
System.out.println("isEmpty:"+c.isEmpty());
System.out.println(c);
}
}
-
集合只能存放引用型別元素,並且儲存的元素的引用(地址)
public class CollectionDemo2
-
集合操作
public class CollectionDemo3 { public static void main(String[] args) { Collection c1 = new ArrayList(); c1.add("java"); c1.add("c"); c1.add("c++"); Collection c2 = new ArrayList(); c2.add("android"); c2.add("ios"); /* * boolean addAll(Collection c) * 新增完畢後,當前集合元素髮生改變則返回true */ c1.addAll(c2); System.out.println("c1:"+c1); Collection c3 = new ArrayList(); c3.add("java"); c3.add("ios"); // c3.add("php"); /* * boolean containsAll(Collection c) * 判斷當前集合是否包含給定集合中的所有元素 */ boolean contains = c1.containsAll(c3); System.out.println("全包含:"+contains); /* * boolean removeAll(Collection c) * 刪除當前集合與給定集合的公有元素 */ c1.removeAll(c3); System.out.println("c1:"+c1); } }
-
boolean contains(Object o) 判斷當前集合是否包含給定元素
public class ContainsDemo { public static void main(String[] args) { Collection c = new ArrayList(); c.add(new Point(1, 2)); c.add(new Point(3, 4)); c.add(new Point(5, 6)); System.out.println(c); Point p = new Point(1, 2); /* * contains的判定標準是看給定的物件p是否與 * 集合現有元素存在equals比較為true的,若有 * 則認為包含,否則為不包含。 * 所以元素equals方法決定這集合判斷包含的結果 */ boolean contains = c.contains(p); System.out.println("包含:"+contains); } }
-
遍歷 Collection提供了統一的遍歷集合的方式:迭代器模式 對應方法: Iterator iterator( ) 該方法可以返回一個用於遍歷當前集合的迭代器
public class IteratorDemo { public static void main(String[] args) { Collection c = new ArrayList(); c.add("one"); c.add("#"); c.add("two"); c.add("#"); c.add("three"); c.add("#"); c.add("four"); c.add("#"); c.add("five"); System.out.println(c); //獲取迭代器 Iterator it = c.iterator(); /* * boolean hasNext() * 判斷集合是否還有下一個元素可以迭代。 * 問的過程 */ while(it.hasNext()){ /* * E next() * 通過迭代器獲取集合下一個元素。 * 取的過程 */ String str = (String)it.next(); System.out.println(str); /* * 在遍歷的過程中刪除#操作 * 需要注意: * 迭代器有一個要求,就是在遍歷的過程中不得 * 使用集合的方法增刪元素,否則會丟擲異常。 * 可以通過迭代器自身提供的remove方法刪除 * 元素。該方法不需要傳入引數,刪除的是通過 * next方法取出的元素。 */ if("#".equals(str)){ it.remove(); } } System.out.println(c); } }
-
增強for迴圈,也稱為新迴圈或for each 新迴圈是用來遍歷集合或陣列使用的,所以功能上不取代傳統for迴圈的工作,並且該特性是編譯器認可,而非虛擬機器認可。編譯器最終會將使用新迴圈遍歷改為傳統遍歷方式。
public class NewForDemo1 { public static void main(String[] args) { String[] array = {"one","two","three","four"}; for(int i=0;i<array.length;i++){ String str = array[i]; System.out.println(str); } /* * 最終編譯器會將程式碼改編為普通for迴圈遍歷方式 */ for(String str : array){ System.out.println(str); } } } public class NewForDemo2 { public static void main(String[] args) { Collection c = new ArrayList(); c.add("one"); c.add("two"); c.add("three"); c.add("four"); c.add("five"); System.out.println(c); /* * 新迴圈遍歷集合最終會被編譯器改編為迭代器遍歷 * 所以在使用新迴圈遍歷集合的過程中不要通過集合 * 的方法增刪元素。 */ for(Object o : c){ String str = (String)o; System.out.println(str); } } }
-
刪除元素
public class RemoveDemo { public static void main(String[] args) { Collection c = new ArrayList(); c.add(new Point(1, 2)); c.add(new Point(3, 4)); c.add(new Point(5, 6)); System.out.println(c); Point p = new Point(1, 2); /* * 刪除也是刪除集合中與給定元素equals比較為true的元素, * 對於List而言,重複元素只刪除第一個 */ c.remove(p); System.out.println(c); } }
-
集合的執行緒安全
集合的工具類Collections可以將現有的集合轉換為一個執行緒安全的,對於集合自身的操作如:add,
remove等都可以保證併發安全。但是API手冊也有說明,一個併發安全的集合也不與使用迭代器遍歷操作做互斥,這意味著併發操作中遍歷與集合自身操作並非併發安全的,需要自行維護互斥關係。
List的常用實現類:ArrayList,LinkedList都不是執行緒安全的,可以通過Collections將List轉換為執行緒安全的
public class SyncCollectionDemo { public static void main(String[] args) { List<String> list = new ArrayList<String>(); list.add("one"); list.add("two"); list.add("three"); System.out.println(list); list = Collections.synchronizedList(list); System.out.println(list); //HashSet也不是執行緒安全的 Set<String> set = new HashSet<String>(list); set = Collections.synchronizedSet(set); System.out.println(set); } }
-
泛型
泛型是JDK1.5之後推出的另一個特性,泛型也稱為引數化型別,指在使用某個類時為其屬性,方法引數,方法返回值 的型別指定實際型別。這在實際開發中可以大大提高程式碼的靈活度。
泛型應用最廣的地方就是集合,用來約束集合的元素型別。泛型的實際型別為Object,當不指定泛型時,預設就使用原型Object。
泛型允許呼叫者使用時決定一個類中屬性,引數,返回值等的型別,從而提高程式碼的靈活性。
public class Type<T> { private T x; private T y; public Type(T x, T y) { super(); this.x = x; this.y = y; } public T getX() { return x; } public void setX(T x) { this.x = x; } public T getY() { return y; } public void setY(T y) { this.y = y; } @Override public String toString() { return "("+x+","+y+")"; } } public class TypeDemo { public static void main(String[] args) { //建立集合時通過泛型約束集合的元素型別 Collection<String> c = new ArrayList<String>(); c.add("one");//此時集合只能存放String c.add("two"); c.add("three"); c.add("four"); System.out.println(c); //獲取迭代器時也通過泛型告知迭代器元素型別 Iterator<String> it = c.iterator(); while(it.hasNext()){ //獲取元素時無需再造型 String str = it.next(); System.out.println(str); } //新迴圈也可以直接使用String接收集合元素了 for(String str:c){ System.out.println(str); } } } //泛型應用 public class TypeDemo2 { public static void main(String[] args) { /* * Type中的x,y都是泛型<T>,而泛型的實際型別是 * Object,所以x,y實際上就是Object型別 * * 在使用時,指定T為Integer,那麼編譯器會依靠該型別 * 檢查對x,y賦值時的實際值的型別是否符合要求。 * 並且在獲取它們的值時,編譯器會自動新增造型程式碼 */ Type<Integer> t = new Type<Integer>(1,2); //編譯器會檢查實參是否滿足泛型所指定型別的要求 t.setX(2); //獲取時,無需造型(編譯器會自動補全) int x = t.getX(); System.out.println("x:"+x); System.out.println(t); Type<Double> t2 = new Type<Double>(1.1,2.2); t2.setX(2.2); double x2 = t2.getX(); System.out.println("x2:"+x2); System.out.println(t2); Type<String> t3 = new Type<String>("一","二"); t3.setX("三"); String x3 = t3.getX(); System.out.println("x3:"+x3); System.out.println(t3); } } //泛型是編譯器認可,非虛擬機器認可。 public class TypeDemo3 { public static void main(String[] args) { Type<Integer> t1 = new Type<Integer>(1,2); //編譯器會檢查實參型別是否符合泛型要求 t1.setX(3); //編譯器會自動補充造型回Integer的程式碼 int x1 = t1.getX(); System.out.println("x1:"+x1); System.out.println("t1:"+t1); //當不指定泛型時,編譯器預設認為是原型Object Type t2 = t1; System.out.println("t2:"+t2); t2.setX("一"); System.out.println("t2:"+t2); //類造型異常! x1 = t1.getX(); System.out.println("x1:"+x1); System.out.println("t1:"+t1); } }