免费视频淫片aa毛片_日韩高清在线亚洲专区vr_日韩大片免费观看视频播放_亚洲欧美国产精品完整版

打開APP
userphoto
未登錄

開通VIP,暢享免費電子書等14項超值服

開通VIP
Java迭代 : Iterator和Iterable接口

從英文意思去理解


 


Iterable :故名思議,實現(xiàn)了這個接口的集合對象支持迭代,是可迭代的。able結(jié)尾的表示 能...樣,可以做...。

Iterator:   在英語中or 結(jié)尾是都是表示 ...樣的人 or ... 者。如creator就是創(chuàng)作者的意思。這里也是一樣:iterator就是迭代者,我們一般叫迭代器,它就是提供迭代機制的對象,具體如何迭代,都是Iterator接口規(guī)范的。




Iterable


一個集合對象要表明自己支持迭代,能有使用foreach語句的特權(quán),就必須實現(xiàn)Iterable接口,表明我是可迭代的!然而實現(xiàn)Iterable接口,就必需為foreach語句提供一個迭代器。

這個迭代器是用接口定義的 iterator方法提供的。也就是iterator方法需要返回一個Iterator對象。

 foreach只能用于數(shù)組和實現(xiàn)了Iterable接口的類


 



//Iterable JDK源碼
//可以通過成員內(nèi)部類,方法內(nèi)部類,甚至匿名內(nèi)部類去實現(xiàn)Iterator

public
interface Iterable<T>{ Iterator<T> iterator();}


 


 


Iterator


 包含3個方法: hasNext ,  next , remove。remove按需求實現(xiàn),一般它很少用到,以至于Eclipse接口方法自動補全時,都忽略了remove放方法。


1、每次在迭代前   ,先調(diào)用hasNext()探測是否迭代到終點(本次還能再迭代嗎?)。

2、next方法不僅要返回當前元素,還要后移游標cursor

3、remove()方法用來刪除最近一次已經(jīng)迭代出的元素


4、 迭代出的元素是原集合中元素的拷貝(重要)

5、配合foreach使用


 



//Iterator接口的JDK源碼,注釋為整理建議使用Iterator的正確姿勢

public
interface Iterator<E> { boolean hasNext(); //每次next之前,先調(diào)用此方法探測是否迭代到終點 E next(); //返回當前迭代元素 ,同時,迭代游標后移 /*刪除最近一次已近迭代出出去的那個元素。 只有當next執(zhí)行完后,才能調(diào)用remove函數(shù)。 比如你要刪除第一個元素,不能直接調(diào)用 remove() 而要先next一下( ); 在沒有先調(diào)用next 就調(diào)用remove方法是會拋出異常的。 這個和MySQL中的ResultSet很類似 */ void remove()
{
throw new UnsupportedOperationException("remove"); }}


 


 


 


 迭代的具體細節(jié)


需要理解的地方


1、hasNext , next  , remove 的調(diào)用順序


2、迭代出來的是原集合元素拷貝!


 


下面是手動迭代的例子,foreach的原理和它一樣。



public static void main(String[] args){        List<Integer> li = new ArrayList<>();                li.add(1);        li.add(2);        li.add(3);        
//不使用foreach 而手動迭代 Iterator
<Integer> iter = li.iterator(); //獲取ArrayList 的迭代器 while(iter.hasNext()) //①先探測能否繼續(xù)迭代 { System.out.println(iter.next()); //②后取出本次迭代出的元素 //invoke remove() //③最后如果需要,調(diào)用remove } }


 


 


AbstractList中實現(xiàn)的迭代器類,可以借鑒參考。


我們實現(xiàn)自己的迭代器的情況很少,畢竟JDK集合足夠強大。


源碼中有一些保護機制,為了便于理解我刪改了。



private class Itr implements Iterator<E> 
{ /*
AbstractList 中實現(xiàn)的迭代器,刪除了一些細節(jié)。不影響理解
Itr為一個priavate成員內(nèi)部類

*/
int cursor = 0; //馬上等待被迭代元素的index //最近一次,已經(jīng)被迭代出的元素的index,如果這個元素迭代后,被刪除了,則lastRet重置為-1 int lastRet = -1; public boolean hasNext() { return cursor != size(); //當前游標值 等于 集合的size() 說明已經(jīng)不能再迭代了。 } public E next() { int i = cursor; E next = get(i); lastRet = i; //lastRet 保存的是最近一次已經(jīng)被迭代出去的元素索引 cursor = i + 1; //cursor為馬上等待被迭代的元素的索引 return next; } public void remove() { if (lastRet < 0) //調(diào)用remove之前沒有調(diào)用next throw new IllegalStateException(); //則拋異常。這就是為什么在使用remove前,要next的原因 OuterList.this.remove(lastRet); //從集合中刪除這個元素 if (lastRet < cursor) //集合刪除元素后,集合后面的元素的索引會都減小1,cursor也要同步后移 cursor--; lastRet = -1; //重置 }}


 


 


 


迭代出來的元素都是原來集合元素的拷貝


Java集合中保存的元素實質(zhì)是對象的引用(可以理解為C中的指針),而非對象本身。


迭代出的元素也就都是 引用的拷貝,結(jié)果還是引用。那么,如果集合中保存的元素是可變類型的,我們就可以通過迭代出的元素修改原集合中的對象。


而對于不可變類型,如String  基本元素的包裝類型Integer 都是則不會反應(yīng)到原集合中。


 


為了便于理解,畫張圖:


 


         


 


 


 


驗證代碼:


 



public class Main{    public static void main(String[] args)    {        List<Person> li = new ArrayList<>();                Person p = new Person("Tom");                li.add(p);                        for(Person ap: li)        {            ap.setName("Jerry");        }                System.out.println(li.get(0).getName());     //Jerry  not Tom            }}class Person{        public Person(String name)    {        this.name = (name==null?"":name);            }        private  String name;    public String getName()    {        return name;    }    public void setName(String name)    {        if(name == null)             name = "";        this.name = name;    }    }


 


 


 


 


小試牛刀,讓自己的類支持迭代。



public class Main{    public static void main(String[] args)    {        MyString s = new MyString("1234567");                        for(char c:s)        {            System.out.println(c);        }            }}class MyString implements Iterable<Character>{        private int length = 0;    private String ineers = null;        public MyString(String s)    {        this.ineers = s;        this.length = s.length();            }            @Override    public Iterator<Character> iterator()    {                        class iter  implements Iterator<Character>     //方法內(nèi)部類        {            private int cur= 0;                                    @Override            public boolean hasNext()            {                return cur != length;            }            @Override            public Character next()            {                                Character c = ineers.charAt(cur);                cur++;                return c;            }                        public void remove()            {                 // do nothing                             }        }        return new iter();     //安裝Iterable接口的約定,返回迭代器                       }    }


 

本站僅提供存儲服務(wù),所有內(nèi)容均由用戶發(fā)布,如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點擊舉報。
打開APP,閱讀全文并永久保存 查看更多類似文章
猜你喜歡
類似文章
java iterator
JDK源碼之ArrayList-Iterator
一道面試題引發(fā)的思考
java.util.ConcurrentModificationException
Java集合 iterator.remove()方法詳解
java提高篇(三十)
更多類似文章 >>
生活服務(wù)
分享 收藏 導(dǎo)長圖 關(guān)注 下載文章
綁定賬號成功
后續(xù)可登錄賬號暢享VIP特權(quán)!
如果VIP功能使用有故障,
可點擊這里聯(lián)系客服!

聯(lián)系客服