| 從英文意思去理解
 Iterable :故名思議,實(shí)現(xiàn)了這個(gè)接口的集合對(duì)象支持迭代,是可迭代的。able結(jié)尾的表示 能...樣,可以做...。 Iterator:   在英語(yǔ)中or 結(jié)尾是都是表示 ...樣的人 or ... 者。如creator就是創(chuàng)作者的意思。這里也是一樣:iterator就是迭代者,我們一般叫迭代器,它就是提供迭代機(jī)制的對(duì)象,具體如何迭代,都是Iterator接口規(guī)范的。 Iterable一個(gè)集合對(duì)象要表明自己支持迭代,能有使用foreach語(yǔ)句的特權(quán),就必須實(shí)現(xiàn)Iterable接口,表明我是可迭代的!然而實(shí)現(xiàn)Iterable接口,就必需為foreach語(yǔ)句提供一個(gè)迭代器。 這個(gè)迭代器是用接口定義的 iterator方法提供的。也就是iterator方法需要返回一個(gè)Iterator對(duì)象。 foreach只能用于數(shù)組和實(shí)現(xiàn)了Iterable接口的類(lèi) 
 //Iterable JDK源碼 
 
 Iterator包含3個(gè)方法: hasNext , next , remove。remove按需求實(shí)現(xiàn),一般它很少用到,以至于Eclipse接口方法自動(dòng)補(bǔ)全時(shí),都忽略了remove放方法。 1、每次在迭代前   ,先調(diào)用hasNext()探測(cè)是否迭代到終點(diǎn)(本次還能再迭代嗎?)。 2、next方法不僅要返回當(dāng)前元素,還要后移游標(biāo)cursor 3、remove()方法用來(lái)刪除最近一次已經(jīng)迭代出的元素 4、 迭代出的元素是原集合中元素的拷貝(重要) 5、配合foreach使用 
 //Iterator接口的JDK源碼,注釋為整理建議使用Iterator的正確姿勢(shì) 
 
 
 迭代的具體細(xì)節(jié)需要理解的地方 1、hasNext , next , remove 的調(diào)用順序 2、迭代出來(lái)的是原集合元素拷貝! 
 下面是手動(dòng)迭代的例子,foreach的原理和它一樣。 public static void main(String[] args) { List<Integer> li = new ArrayList<>(); li.add(1); li.add(2); li.add(3); 
 
 AbstractList中實(shí)現(xiàn)的迭代器類(lèi),可以借鑒參考。 我們實(shí)現(xiàn)自己的迭代器的情況很少,畢竟JDK集合足夠強(qiáng)大。 源碼中有一些保護(hù)機(jī)制,為了便于理解我刪改了。 private class Itr implements Iterator<E> 
 
 
 迭代出來(lái)的元素都是原來(lái)集合元素的拷貝 Java集合中保存的元素實(shí)質(zhì)是對(duì)象的引用(可以理解為C中的指針),而非對(duì)象本身。 迭代出的元素也就都是 引用的拷貝,結(jié)果還是引用。那么,如果集合中保存的元素是可變類(lèi)型的,我們就可以通過(guò)迭代出的元素修改原集合中的對(duì)象。 而對(duì)于不可變類(lèi)型,如String 基本元素的包裝類(lèi)型Integer 都是則不會(huì)反應(yīng)到原集合中。 
 為了便于理解,畫(huà)張圖: 
           
 
 
 驗(yàn)證代碼: 
 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; } } 
 
 
 
 小試牛刀,讓自己的類(lèi)支持迭代。 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)部類(lè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接口的約定,返回迭代器 } } 
 | 
|  | 
來(lái)自: Levy_X > 《JAVAWEB學(xué)習(xí)資料》