Java基础23-集合类2(Set接口,Iterator迭代器)
一、Set接口簡介
根據API,Set接口是一個不包含重復元素的 collection。更確切地講,set 不包含滿足 e1.equals(e2) 的元素對 e1 和 e2,并且最多包含一個 null 元素。正如其名稱所暗示的,此接口模仿了數學上的 set 抽象。
?
二、Set接口特性
1.不允許重復(HashCode/equals方法)
2.不記錄添加順序(沒有添加順序,但不代表元素排列沒有順序)
?三、實現類
(1).HashSet
此類實現 Set 接口,由哈希表(實際上是一個 HashMap 實例)支持。它不保證 set 的迭代順序;特別是它不保證該順序恒久不變。此類允許使用 null 元素。?
1.常用方法
public static void main(String[] args) {Set<String> set=new HashSet<>();set.add("o");set.add("0");set.add("-1");set.add("s");//以下的有序排列是因為它們的hashcode是有序的,是根據hashcode來進行排序的set.add("a");set.add("b");set.add("c");set.add("d");set.add("e");//相同的元素hashcode相同,后邊這個會將前邊的覆蓋掉set.add("0");System.out.println(set);//[0, a, b, s, c, -1, d, e, o]Set<String> set1=new HashSet<>();set1.add("6");set1.add("8");//將set1里邊的值放到set中 set.addAll(set1);//set.clear();for (String ele : set) {System.out.println(ele);//0 a b s c -1 d e 6 8 o }System.out.println("--------------");Iterator<String> it = set.iterator();while(it.hasNext()) {System.out.println(it.next());}System.out.println(set.remove("-1"));//true set.removeAll(set1);System.out.println(set);//[0, a, b, s, c, d, e, o] } HshSet是set接口最常用的實現類,底層采用了哈希表(散列/hash)算法
其底層其實也是一個數組,存在的意義是提供查詢速度,插入速度以比較快,但是適用于少量數據的插入操作
?2.在HshSet中如何判斷兩個對象是否相同的問題
1).兩個對象的equals比較相等,返回true則說明相同對象
?2).兩個對象的hashcode方法返回值相等
?對象的hashcode值決定了在哈希表中的存儲位置
3. 當往hashset集合中添加新的對象時,先判斷該對象中的hashcode
- 如果不等:直接把新的對象存儲到hashcode指定的位置
- 如果相等:再繼續判斷新對象和集合對象中的equals做比較
若hashcode相同,equals為false:非常麻煩,存儲在之前對象同槽位的鏈表上(操作比較麻煩)
3.對象的hashcode和equals方法的重要性:
?每一個存儲到hash表中的對象,都得提供hashcode和equals方法,用來判斷是否是同一個對象
?存儲在哈希表中的對象,都應該覆蓋equals方法和hashcode方法并且保證equals相等的時候,hashcode也應該相等
(2).LinkedHashSet
此實現與 HashSet 的不同之外在于,后者維護著一個運行于所有條目的雙重鏈接列表。此鏈接列表定義了迭代順序,即按照將元素插入到 set 中的順序(插入順序)進行迭代。注意,插入順序不 受在 set 中重新插入的 元素的影響。(如果在 s.contains(e) 返回 true 后立即調用 s.add(e),則元素 e 會被重新插入到 set s 中。)?
Set<String> set2=new LinkedHashSet<>();set2.add("o");set2.add("0");set2.add("-1");set2.add("s");set2.add("a");set2.add("b");set2.add("c");set2.add("d");set2.add("e");//鏈表算法(保證添加順序,但無索引)System.out.println(set2);//[o, 0, -1, s, a, b, c, d, e](3)TreeSet
基于 TreeMap 的 NavigableSet 實現。使用元素的自然順序對元素進行排序,或者根據創建 set 時提供的 Comparator 進行排序,具體取決于使用的構造方法。
主要是用于排序,但實際開發中主要是在數據庫中進行排序等操作。
TreeSet也不能存放重復對象,但是TreeSet會自動排序,如果存放的對象不能排序則會報錯,所以存放的對象必須指定排序規則。排序規則包括自然排序和自定義排序。
①自然排序:TreeSet要添加哪個對象就在哪個對象類上面實現java.lang.Comparable接口,并且重寫comparaTo()方法,返回0則表示是同一個對象,否則為不同對象。
②自定義排序:建立一個第三方類并實現java.util.Comparator接口。并重寫方法。定義集合形式為TreeSet ts = new TreeSet(new 第三方類());
//TreeSet集合底層才有紅黑樹算法,會對存儲的元素默認使用自然排序(從小到大);
//注意:必須保證TreeSet集合中的元素對象是相同的數據類型,否則報錯
//在TreeSet的自然排序中,認為如果兩個對象作比較的compareTo方法返回的是0,則認為是同一個對象
①自然排序
實現Comparable接口
重寫hashcode和equals方法
重寫compareTo方法
TreeSet<Person> set4=new TreeSet();set4.add(new Person("路飛",18));set4.add(new Person("索隆",26));set4.add(new Person("山治",23));set4.add(new Person("娜美",22));System.out.println(set4);//[Person [name=路飛, age=18], Person [name=娜美, age=22], Person [name=山治, age=23], Person [name=索隆, age=26]]?
三、Iterator迭代器
對 collection 進行迭代的迭代器。迭代器取代了 Java Collections Framework 中的 Enumeration。迭代器與枚舉有兩點不同:
- 迭代器允許調用者利用定義良好的語義在迭代期間從迭代器所指向的 collection 移除元素。
- 方法名稱得到了改進。?
它 提供一種方法訪問一個容器(container)對象中各個元素,而又不需暴露該對象的內部細節。 從定義可見,迭代器模式是為容器而生。很明顯,對容器對象的訪問必然涉及到遍歷算法。
?
public class IteratorDemo { /*把集合中的元素一個一個的遍歷出來。* 迭代器對象* * */public static void main(String[] args) {List list=new ArrayList();list.add("a");list.add("b");list.add("c");//方式1:for循環//方式2:for-each 增強for循環//for(元素類型 ele:數組名/Iterable實現類對象)for (Object object : list) {System.out.println(object);}//方式3:使用while循環操作迭代器IteratorIterator it=list.iterator();while(it.hasNext()) {System.out.println(it.next());}//方式3:for循環操作迭代器for(Iterator it1=list.iterator();it.hasNext();) {System.out.println(it.next());}//深入分析foreach和迭代器//1.foreach操作數組:底層依然是采用for循環+索引來獲取數組元素int[] arr= {1,2,3};for (int i : arr) {System.out.println(i);}//2.foreach可以操作iterable的實例:底層其實采用的iterator迭代器for (Object object : list) {System.out.println(object);if("c".equals(object)) {list.remove(object);//并發修改異常 java.util.ConcurrentModificationException//當使用迭代器時,當前線程A中,會單獨創建一個新的線程B//A線程負責繼續迭代,B線程負責去刪除//B線程每次都會去檢查和A線程中的元素是否個數相同,如果不是則報錯,并發修改異常//如何解決呢?//不要使用集合對象的刪除方法//在collection接口中存在刪除指定元素的方法boolean remove//該方法只能從集合中刪除元素,不能把迭代器中指定的元素進行刪除//正確 -使用iterator中的remove方法 }}while(it.hasNext()) {Object ele=it.next();if("c".equals(ele)) {//list.remove(ele);//錯誤,不能使用集合對象的removeit.remove();//正確,保證了兩個線程的同步 }System.out.println(ele);}//結論:直接使用foreach迭代數組和集合元素即可,簡單。//當需要遍迭代集合元素,邊刪除指定的元素時,此時只能使用迭代器 } }?
轉載于:https://www.cnblogs.com/LuckyGJX/p/9116735.html
總結
以上是生活随笔為你收集整理的Java基础23-集合类2(Set接口,Iterator迭代器)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 一站式机器学习平台TI-ONE是什么?—
- 下一篇: vue java 使用AES 前后端加密