首頁 > Java > java教程 > 主體

迭代器、增強for、泛型用法集合

巴扎黑
發布: 2017-06-26 11:32:51
原創
1369 人瀏覽過

java.util.Collection介面
是集合的最頂層的介面,定義了集合共性的方法
介面無法直接建立物件,使用多態性的方式建立物件
Collection<集合中的資料型別(泛型)> coll = new ArrayList<集合中的資料型別(泛型)>();

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

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

迭代器是一個介面,需要找到迭代器的實作類別,迭代器的實作類別是每個集合的內部類別
在Collection介面中有一個方法: iterator方法傳回的是迭代器
Iterator 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();返回false50          */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:是一個未知的資料類型,可能是Integer,可能是String,可能Person
建立類別物件的時候確定資料類型

# 定義格式:
修飾符 class 類別名稱{

}

 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 c)
参数是一个集合,集合的数据类型有要求,只能是ArrayList泛型的子类或者是本身

ArrayList(Collection 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 5354             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 }
登入後複製

 

以上是迭代器、增強for、泛型用法集合的詳細內容。更多資訊請關注PHP中文網其他相關文章!

相關標籤:
來源:php.cn
本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板