集合【迭代器、增強for、泛型】

来源:http://www.cnblogs.com/caigq/archive/2017/06/16/7019537.html
-Advertisement-
Play Games

java.util.Collection介面 是集合的最頂層的介面,定義了集合共性的方法 介面無法直接創建對象,使用多態的方式創建對象 Collection<集合中的數據類型(泛型)> coll = new ArrayList<集合中的數據類型(泛型)>(); 迭代器 集合中存儲數據的方式(數據類型 ...


java.util.Collection介面
是集合的最頂層的介面,定義了集合共性的方法
介面無法直接創建對象,使用多態的方式創建對象
Collection<集合中的數據類型(泛型)> coll = new ArrayList<集合中的數據類型(泛型)>();

迭代器
集合中存儲數據的方式(數據類型)不一樣,取出集合中元素的方式也不同,java給我們提供了一種公共的取出元素的方式,叫迭代器
描述迭代器的介面:java.util.Iterator

介面中的抽象方法:
boolean hasNext() 如果仍有元素可以迭代,則返回 true。 判斷集合中還有沒有元素,有返回true,沒有返回false
E next() 返回迭代的下一個元素。 取出集合中的下一個元素

迭代器是一個介面,需要找到迭代器的實現類,迭代器的實現類是每個集合的內部類
在Collection介面中有一個方法: iterator方法返回的就是迭代器
Iterator<E> iterator() 返回在此 collection 的元素上進行迭代的迭代器。
ArrayList集合實現了Collection介面,重寫iterator方法,方法的返回值就是迭代器的實現類對象

註意:我們只需要知道iterator方法返回的而是迭代器的實現類就行了,不需要關註返回的是哪個實現類對象,這種變成方式叫做面向介面編程

迭代器的使用步驟:
1.創建集合對象,往集合中添加元素
2.使用集合中的方法iterator獲取迭代器的實現類對象,使用Iterator介面接收(多態)
3.使用iterator中的方法hasNext和next方法進行迭代,取出集合中的元素

 1 public static void main(String[] args) {
 2         //1.創建集合對象,往集合中添加元素
 3         //Collection<String> coll = new ArrayList<String>();
 4         Collection<String> coll = new HashSet<String>();
 5         coll.add("姚明");
 6         coll.add("喬丹");
 7         coll.add("詹姆斯");
 8         coll.add("科比");
 9         coll.add("艾弗森");
10         //2.使用集合中的方法iterator獲取迭代器的實現類對象,使用Iterator介面接收(多態)
11         //集合中的數據類型是什麼,迭代器的數據類型就是什麼,跟著集合走
12         Iterator<String> it = coll.iterator();
13         //3.使用iterator中的方法hasNext和next方法進行迭代,取出集合中的元素
14         //boolean hasNext() 如果仍有元素可以迭代,則返回 true。
15         /*boolean b = it.hasNext();
16         System.out.println(b);
17         //E(String) next() 返回迭代的下一個元素。
18         String s = it.next();
19         System.out.println(s);
20         
21         b = it.hasNext();
22         System.out.println(b);
23         s = it.next();
24         System.out.println(s);
25         
26         b = it.hasNext();
27         System.out.println(b);
28         s = it.next();
29         System.out.println(s);
30         
31         b = it.hasNext();
32         System.out.println(b);
33         s = it.next();
34         System.out.println(s);
35         
36         b = it.hasNext();
37         System.out.println(b);
38         s = it.next();
39         System.out.println(s);
40         
41         b = it.hasNext();
42         System.out.println(b);//false,沒有元素了
43         s = it.next();//沒有元素了,在取就報NoSuchElementException沒有元素異常
44         System.out.println(s);*/
45         
46         /*
47          * 發現以上迭代的過程是一個重覆的過程,可以使用迴圈優化
48          * 我們不知道集合中有多少元素,所以可以使用while迴圈
49          * while迴圈的結束條件:hasNext();返回false
50          */
51         while(it.hasNext()){
52             String s = it.next();
53             System.out.println(s);
54         }
55         System.out.println("-------------------");
56         /*
57          * for迴圈方式迭代器,使用不多
58          */
59         /*for(Iterator<String> it2 = coll.iterator();it2.hasNext();){
60             String s = it2.next();//取出元素,移動指針到下一位
61             System.out.println(s);
62         }*/
63     }

併發修改異常
在迭代的過程中,對集合的長度進行了修改,就會發生併發修改異常
遍歷的過程中,集合的長度進行了修改,但是迭代器並不知道,就會產生ConcurrentModificationException

解決方法:
1.迭代就是迭代,不要對集合進行修改
2.使用迭代器Iterator的子介面ListIterator中的方法add/remove,讓迭代器自己增加往集合中增加元素/移除元素
這樣迭代器本身知道了集合的變化,就不會產生併發修改異常了

void add(E e) 將指定的元素插入列表(可選操作)。
void remove() 從列表中移除由 next 或 previous 返回的最後一個元素(可選操作)。

 1  public static void main(String[] args) {
 2         ArrayList<String> list = new ArrayList<String>();
 3         
 4         list.add(null);
 5         list.add("abc1");
 6         list.add("abc2");
 7         list.add("abc3");
 8         list.add("abc4");
 9         
10         /*
11          * 使用迭代器遍歷集合
12          */
13         //獲取迭代器
14         Iterator<String> it = list.iterator();
15         //使用while遍歷集合
16         while(it.hasNext()){
17             String s = it.next();
18             
19             /*
20              * 判斷集合中有沒有"abc3"這個元素
21              * 如果有,增加一個元素"itcast"
22              * 編程技巧:使用equals判斷的時候,要把已知的變數寫在前邊,未知的寫在後邊,防止空指針異常
23              */
24             //if(s.equals("abc3")){
25             if("abc3".equals(s)){
26                 //1.迭代就是迭代,不要對集合進行修改
27                 //list.add("itcast");
28             }
29             
30             System.out.println(s);
31         }
32         
33         System.out.println("------------------");
34         
35         /*
36          * 2.使用迭代器Iterator的子介面ListIterator中的方法add/remove,讓迭代器自己增加往集合中增加元素/移除元素
37          */
38         ListIterator<String> listIt = list.listIterator();
39         while(listIt.hasNext()){
40             String s = listIt.next();
41             if("abc3".equals(s)){
42                 listIt.add("itcast");
43             }
44             System.out.println(s);
45         }
46         System.out.println(list);
47     }

增強for
內部是一個迭代器,簡化了迭代的代碼,使遍歷更加簡單

Collection介面繼承Iterable,所以Collection介面的所有實現類都可以是用增強for

註意:增強for是JDK1.5之後出現的

格式:
for(數據類型(集合/數組的數據類型) 變數名 : 集合名/數組名){
  syso(變數名);
}

Java中的泛型
就是數據類型,在創建對象的時候確定

Java中的泛型是一個偽泛型:在編譯的時候有(寫代碼.java中),運行的時候(.class)沒有
隨機數:偽隨機數

泛型的好處:
1.避免強轉,可以直接使用元素特有的方法
2.把運行期的異常,轉換編譯期異常(編譯失敗)

定義含有泛型的類
模仿ArrayList集合
public class ArrayList<E>{}
E:是一個未知的數據類型,可能是Integer,可能是String,可能Person
創建類對象的時候確定數據類型

定義格式:
修飾符 class 類名<E>{

}

 1 public class GenericClass<E> {
 2     private E name;
 3 
 4     public E getName() {
 5         return name;
 6     }
 7 
 8     public void setName(E name) {
 9         this.name = name;
10     }
11     
12     public void method(E e){
13         System.out.println(e);
14     }

定義含有泛型的介面
格式:
修飾符 interface 介面名<泛型>{
  抽象方法(參數<泛型>);
}

1  public interface GenericInterface<E> {
2     public abstract void method(E e);
3 }
 1 /*
 2  * 1.定義介面的實現類,不管泛型,介面泛型是怎麼寫的,實現類也怎麼寫
 3  *  public class ArrayList<E> implements List<E>{}
 4  *  創建實現類對象的時候確定泛型的數據類型
 5  */
 6 class GenericInterfaceImpl1<E> implements GenericInterface<E>{
 7 
 8     @Override
 9     public void method(E e) {
10         System.out.println(e);
11     }
12 }

含有泛型的方法
不是類上定義的泛型,是方法自己定義的泛型
定義格式:在修飾符和返回值類型之間要定義泛型,才能使用
修飾符 <泛型> 返回值類型 方法名(參數<泛型>){
}
方法上的泛型,在調用方法的時候確定數據類型,傳遞的是什麼類型的數據,泛型就是什麼類型(和類上的泛型沒有關係)

 1 public class GenericMethod<E> {
 2 
 3     /*
 4      * 定義方法,使用類上的泛型
 5      */
 6     public void method(E e){
 7         System.out.println(e);
 8     }
 9     
10     /*
11      * 定義一個含有泛型的方法
12      */
13     public <T> void function(T t){
14         System.out.println(t);
15     }

泛型的通配符:?,代表任意的數據類型

上限限定:? extends E代表只要是E類型的子類即可
下限限定:? super E代表只要是E類型的父類即可

ArrayList集合的構造方法
ArrayList(Collection<? extends E> c)
參數是一個集合,集合的數據類型有要求,只能是ArrayList泛型的子類或者是本身

ArrayList(Collection<? extends E> c)
參數是一個集合,集合的數據類型有要求,只能是ArrayList泛型的子類或者是本身

 1 /*
 2  * 鬥地主案例:
 3  * 1.準備牌
 4  * 2.洗牌
 5  * 3.發牌
 6  * 4.看牌
 7  */
 8 public class DouDiZhu {
 9     public static void main(String[] args) {
10         //1.準備牌
11         //創建存儲54張牌的集合
12         ArrayList<String> poker = new ArrayList<String>();
13         //存儲大王小王
14         poker.add("大王");
15         poker.add("小王");
16         //存儲52張牌
17         //創建序號的數組
18         String[] numbers = {"2","A","K","Q","J","10","9","8","7","6","5","4","3"};
19         //創建花色數組
20         String[] colors = {"?","?","?","?"};
21         //嵌套遍歷兩個數組
22         for (String number : numbers) {
23             for (String color : colors) {
24                 //System.out.println(color+number);
25                 //把組合的牌放入到集合中
26                 poker.add(color+number);
27             }
28         }
29         //System.out.println(poker);
30         
31         /*
32          * 2.洗牌
33          * 使用Collections中的方法
34          * static void shuffle(List<?> list)  
35          */
36         Collections.shuffle(poker);
37         //System.out.println(poker);
38         
39         /*
40          * 3.發牌
41          * 創建4個集合
42          * 遍歷poker集合
43          * 使用poker集合的索引%3發牌
44          */
45         ArrayList<String> player01 = new ArrayList<String>();
46         ArrayList<String> player02 = new ArrayList<String>();
47         ArrayList<String> player03 = new ArrayList<String>();
48         ArrayList<String> diPai = new ArrayList<String>();
49         //遍歷poker集合
50         for (int i = 0; i < poker.size(); i++) {
51             //獲取牌
52             String s = poker.get(i);
53             //先判斷索引是否為底牌的索引 51 52 53
54             if(i >=51){
55                 //給底牌發牌
56                 diPai.add(s);
57             }else if(i%3==0){
58                 //給玩家1發牌
59                 player01.add(s);
60             }else if(i%3==1){
61                 //給玩家1發牌
62                 player02.add(s);
63             }else if(i%3==2){
64                 //給玩家1發牌
65                 player03.add(s);
66             }
67         }
68         //4.看牌
69         System.out.println("劉德華:"+player01);
70         System.out.println("周潤發:"+player02);
71         System.out.println("周星馳:"+player03);
72         System.out.println("底牌:"+diPai);
73     }
74 }

 


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 在centos上使用別名和是用密鑰登錄: vim /root/.ssh/config #輸入下列內容 Host * User root #以root登錄 ServerAliveInterval 60 #存活時間 #test1 Host q0 #登錄的別名 HostName 10.10.10.1 #i ...
  • 首先需要在centos系統下安裝好mysql,這個我已經安裝好了,這裡就不把過程貼出來了。 第一步:使用root用戶登錄到mysql資料庫: 第二步:創建一個mysql資料庫。當第一步登錄成功後,便會出現mysql命令:mysql> 第三步:在已經創建好的資料庫裡面創建一個簡單的數據表 第四步:為數 ...
  • 本文目錄: 4.1 文件系統的組成部分 4.2 文件系統的完整結構 4.3 Data Block 4.4 inode基礎知識 4.5 inode深入 4.6 單文件系統中文件操作的原理 4.7 多文件系統關聯 4.8 ext3文件系統的日誌功能 4.9 ext4文件系統 4.10 ext類文件系統的 ...
  • 公司有幾台美國的伺服器,平時也比較空閑,利用ssh搭了個隧道作為自己fq使用 辦公網路是一臺windows主機,不過上面裝了一個linux虛擬機,平時習慣使用虛擬機做開發機 辦公網路可以直接ssh通過內網地址鏈接美國伺服器 linux 虛擬機使用NAT模式上網ip:192.168.56.100 辦公 ...
  • http://blog.chinaunix.net/uid-7828352-id-4472376.html 寫的不錯,尤其是uboot向linux內核傳遞參數的過程寫的比較詳細。 ...
  • 由於我們有時候沒法預估或者說錯誤的盤符分區的時候,常常會導致我們後面的操作出現極大的不方便,這裡我就記錄下一個錯誤分區後對home和根分區存儲空間大小調整的整個過程!      ①查看我們現有機器的分區狀況 ...
  • 自 VS2010 起,微軟就在 CRT 中集成了併發運行時(Concurrency Runtime),並行模式庫(PPL,Parallel Patterns Library)是其中的一個重要組成部分。7 年過去了,似乎大家都不怎麼Care這個事情,相關文章少少且多是蜻蜓點水。實際上這個庫的設計相當精 ...
  • 這是我之前開發的文件夾自動同步工具,主要實現開發機和伺服器之間的文件夾同步。 項目地址: https://github.com/mike-zhang/autoSync 問題描述 在windows下修改代碼,到伺服器上去編譯,但每次都要通過winscp之類的工具拖拽上去(當然你也可以通過scp命令行的 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...