摘記一下最近敲的關於集合方面的Demo,會陸續作成博客記錄下來的。算法
此次摘記的是:安全
foreach(T t : Collections c){ ... }
Collections c.forEach(obj-> ...)
Iterator
對象進行遍歷Set
接口的四種常見實現類:
這裏補充說明下,上述的四種Set都是非線程安全的,即須要使用代碼同步機制保證多線程訪問的安全性。想使用線程安全的Set,可採用_synchronizedSortedSet_(線程安全)。數據結構
如下爲筆者學習時採用的Demo,筆者將一些心得記錄放在了Demo的註釋中,若是有dalao能夠指點下小弟,歡迎私信:xb1997love@gmail.com多線程
public class SetDemo { static SetDemo mine = new SetDemo(); /** * 這是通常的Lambda表達式遍歷集合 */ public void LambdaEx() { Collection<Integer> i = new HashSet<Integer>(); i.add(1); i.add(2); i.add(3); i.add(4); i.forEach(obj -> System.out.println(obj)); } /** * 這是Lambda遍歷Iterator對象 */ public void LambdaIterator() { Collection<Integer> i = new HashSet<Integer>(); i.add(1); i.add(2); i.add(3); i.add(4); Iterator<Integer> it = i.iterator(); // 這是傳統的使用Iterator對象循環遍歷集合 // while(it.hasNext()) { // int num = (Integer)it.next(); // if(num == 3) { // it.remove(); // } // System.out.println(num); // } // 利用Lambda表達式循環輸出對象 it.forEachRemaining(obj -> System.out.println(obj)); } /** * 這個是用來顯示Java 8中的IntStream LongStream DoubleStream等流式接口 */ public void IntLongDoubleStream() { IntStream is = IntStream.builder().add(1).add(13).add(20).add(18).build(); Collection<Integer> c = new HashSet<Integer>(); c.add(1); c.add(2); c.add(3); c.add(4); // // 下面的彙集方法的代碼每次只能被調用一,就是下面的max() min() 等只能同時調用一個 // System.out.println("MAX: "+ is.max().getAsInt()); // System.out.println("MIN: "+is.min().getAsInt()); // // 這個是用於匹配is中的全部元素是否都知足所述的要求 // System.out.println("is 中全部元素的平方是否大於20:"+is.allMatch(ele->ele*ele>20)); // // 這是對is中全部的對象進行修改 // IntStream newIs = is.map(ele->ele*2); // newIs.forEach(ele->System.out.println(ele)); c.stream().filter(ele -> ele > 4); } /** * TreeSet Demo代碼 TreeSet * 會自動對插入的元素進行排序,假若數據是使用的自定義的類型,那麼那個類型須要實現Comparable接口(compareTo方法) TreeSet * 實際上應該是一顆徹底二叉樹,而且對插入的數據進行修改的話可能會致使Set混亂,由於會出現無序而且沒法找到元素的狀況 * 讀出數據的時候會採用中序遍歷的方式進行讀出 */ public void TreeSetDemo() { // 默認的,使用基本的數字類型的會按照遞增的順序排列 TreeSet<M> tSet = new TreeSet<M>((o1, o2) -> { M m1 = (M) o1; M m2 = (M) o2; // 遞減的排序 return m1.age > m2.age ? -1 : m1.age < m2.age ? 1 : 0; }); // 插入三條數據 tSet.add(new M(5)); tSet.add(new M(-3)); tSet.add(new M(9)); System.out.println(tSet); } /** * HashSet Demo代碼 * HashSet保存元素是無序且惟一的,若是企圖修改其中的元素會致使Set進入混亂的狀態,進而Set沒法識別對應的元素,沒法精肯定位元素 * 假若須要重寫equals方法切近最後也重寫hashCode方法,由於equals方法相等的對象,它們的hashCode也應該相同。而HashSet須要利用這兩個函數進行重複的判斷 */ public void HashSetDemo() { Set<R> hSet = new HashSet<R>(); hSet.add(new R(5)); hSet.add(new R(-3)); hSet.add(new R(9)); hSet.add(new R(-2)); hSet.add(new R(3)); // 初始狀態hSet System.out.println(hSet); // 這裏能夠給所引發加上一個type Iterator<R> it = hSet.iterator(); // 作了一個很危險的操做,將Set的第一個元素的值修改成-3 R first = (R) it.next(); first.count = -3; // 修改後狀態hSet System.out.println(hSet); System.out.println("hSet 是否包含-2的元素? " + hSet.contains(new R(-2))); // 試圖移除這個R(-3)對象 hSet.remove(new R(-3)); System.out.println(hSet); System.out.println("hSet 是否包含-3的元素? " + hSet.contains(new R(-3))); System.out.println("hSet 是否包含-2的元素? " + hSet.contains(new R(-2))); } /** * LinkedHashSet相較於HashSet的不一樣是,LinkedHashSet會以鏈表的形式維護插入元素的順序 */ public void LinkedHashSetDemo() { Set<String> lSet = new LinkedHashSet<String>(); // 重點是觀察其插入是具備有序性的,即LinkedHashSet會維持元素插入的順序 lSet.add("t1"); lSet.add("t2"); System.out.println(lSet); // 移除再從新插入,順序會改變 lSet.remove("t1"); lSet.add("t1"); System.out.println(lSet); } /** * EnumSet Demo代碼 EnumSet 採用的是位向量來存儲變量,進行批量操做(ContainsAll retainAll()方法)特別合適 * EnumSet 不容許插入null值 */ public void EnumSetDemo() { // 以一個枚舉類型建立一個EnumSet,此時會以枚舉的全部值填充此EnumSet EnumSet<Season> eSet = EnumSet.allOf(Season.class); // 以一個枚舉類型建立一個空的EnumSet,這裏只是單純地指定了枚舉的類型 EnumSet<Season> eSet2 = EnumSet.noneOf(Season.class); // 比較下兩種EnumSet的區別 System.out.println(eSet); System.out.println(eSet2); // 試圖插入一個枚舉值 eSet2.add(Season.SPRING); // 以指定的枚舉值建立EnumSet EnumSet<Season> eSet3 = EnumSet.of(Season.SPRING,Season.SUMMER); // 以枚舉類型中指定範圍的值建立EnumSet EnumSet<Season> eSet4 = EnumSet.range(Season.SPRING,Season.WINTER); // eSet5 + eSet4 -> Season中全部的枚舉值 EnumSet<Season> eSet5 = EnumSet.complementOf(eSet4); } public static void main(String[] args) { // TODO Auto-generated method stub // Lambda遍歷集合的方式 // mine.LambdaIterator(); // 使用Stream對象遍歷集合的方式 // mine.IntLongDoubleStream(); // 常見的三種Set接口實現類 // mine.TreeSetDemo(); // mine.HashSetDemo(); // mine.LinkedHashSetDemo(); // mine.EnumSetDemo(); } /** * 用於演示TreeSet的類,該類未實現Comparable接口,而是將比較的方式在構建TreeSet的時候以構造函數的形式注入了 * * @author Administrator * */ class M { int age = 0; public M(int age) { this.age = age; } public String toString() { return String.format("M[ age: %d]", age); } } /** * 用於演示HashSet的類,關鍵在於重寫equals和hashCode方法 * @author Administrator * */ class R { int count; public R(int count) { this.count = count; } @Override public String toString() { // TODO Auto-generated method stub return String.format("R[count:%d]", count); } @Override public boolean equals(Object obj) { // TODO Auto-generated method stub if (this == obj) { return true; } if (obj != null && obj.getClass() == R.class) { R r = (R) obj; return this.count == r.count; } return false; } @Override public int hashCode() { // TODO Auto-generated method stub return this.count; // return super.hashCode(); } } /** * 用於演示EnumSet的類 * @author Administrator * */ enum Season{ SPRING,SUMMER,FAIL,WINTER } }