国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 學院 > 開發設計 > 正文

Java暗箱操作之for-each

2019-11-15 01:19:18
字體:
來源:轉載
供稿:網友
java暗箱操作之for-each

  對于我們常用的ArrayList等容器類,經常需要一個一個遍歷里面的元素,從而對各個元素執行對應的操作。

  像我代碼寫多了,通常的做法是用傳統的,類似于數組遍歷的方法,即在for循環中設置一個int變量作為索引,然后用List的get方法,想怎么做就怎么做,不會遇到任何不能做的事。

  當然,偶爾我會寫得簡單一點,用 for (元素類型變量名 :集合) 的方法,即不用索引,直接指定實際的元素類型,取下一個元素,這樣可以少寫一行代碼。

  但不管用哪一種,我都沒有考慮過用迭代器iterator,雖然教程上面經常提到這東西,我也知道這是用來遍歷,順便執行刪除等操作的。因為用類似數組遍歷的方法取元素從未遇到過瓶頸,就從來沒研究過iterator,也一直都覺得這是個沒有卵用的東西。

  最近在研究ArrayList和LinkedList源碼的時候,源碼里面也有很大一段是關于Iterator的,這讓我更加不解了:既然是一個可有可無可替代的東西,為什么官方還要費這么大的勁來描述它呢?

  直到最近閱讀《Effective Java》,看了一節關于for-each和傳統for循環的比較,里面有一句話讓我重新審視Iterator:

    Not only does the for-each loop let you iterate over collections and arrays,

    it lets you iterate over any object that implements the Iterable interface.

    這就不得不讓我懷疑:難道我以前所知道的集合類,就是因為實現了Iterable接口,才可以用for加冒號的方式?

  

  google了一下,果然,for-each這樣一種簡潔的書寫方式,內部居然就是用迭代器實現的!

  下面的代碼摘自StackOverFlow  

  

List<String> someList = new ArrayList<String>();

  正常的用for-each遍歷方法:

for (String item : someList) {    System.out.PRintln(item);}

  重點來了,上面這簡單的一句話,在編譯過程中,被編譯器自動翻譯成了下面這段,真正執行的時候也正是下面這段:

for(Iterator<String> i = someList.iterator(); i.hasNext(); ) {    String item = i.next();    System.out.println(item);}

  

  所以,在實際開發中,雖然明面上很少用到標標準準的Iterator,但是常用的for-each的暗箱操作卻都是Iterator!

  Java創造出來for-each的操作,好處之一當然是簡化了代碼的書寫,減少了變量個數。

  另外還有很重要的一點是大大降低了遍歷過程當中的誤操作。想想看,如果在for-each過程中,你得到了當前位置的元素值,有什么辦法可以添加、刪除或修改元素值呢?答案是沒有。然而利用Iterator或者索引來寫循環,你可以進行幾乎所有的增刪改操作。所以利用for-each來操作更安全。

  當然,for-each還有一種用法,即用在普通數組的遍歷當中,當中也進行了暗箱操作,即轉換為索引的遍歷。

int[] test = new int[] {1,4,5,7};for (int intValue : test) {    // do some work here on intValue}

  

  編譯時轉換為:

int[] test = new int[] {1,4,5,7};for (int i = 0; i < test.length; i++) {    int intValue = test[i];    // do some work here on intValue}

一定要注意,for-each只能用于:①Iterable ②數組

也即,除了數組以外,一般的類只要實現了Iterable接口就能用for-each

我們可以隨便寫個類玩玩。

import java.util.Iterator;public class MyClass<E> implements Iterable<E>{        private class MyIterator implements Iterator<E> {                private int max = 10;        private int cur = 0;        @Override        public boolean hasNext() {            if (cur < max)                return true;            else                return false;        }        @SuppressWarnings("unchecked")        @Override        public E next() {            Object res = ++cur;            return (E) res;        }        @Override        public void remove() {            System.out.println("索引:"+cur+" 被刪除");        }            };    @Override    public Iterator<E> iterator() {        return new MyIterator();    }    }

測試下

import java.util.Iterator;public class JavaMain {    public static void main(String[] args) {        MyClass<Integer> m = new MyClass<>();        for (Integer i : m) {            System.out.println(i);        }        System.out.println("-------------------------------------------");        for (Iterator<Integer> it = m.iterator();it.hasNext();) {            Integer val = it.next();            if (val % 3 == 0)                it.remove();        }    }    }

輸出結果:

12345678910-------------------------------------------索引:3 被刪除索引:6 被刪除索引:9 被刪除

我們這里的MyClass類沒有任何實際的意義,居然試驗成功了,真是一件不可思議的事情。。。

參考資料:

http://stackoverflow.com/questions/85190/how-does-the-java-for-each-loop-work

http://docs.Oracle.com/javase/specs/jls/se8/html/jls-14.html#jls-14.14.2


發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 基隆市| 边坝县| 石棉县| 佳木斯市| 得荣县| 西充县| 哈尔滨市| 丹阳市| 全南县| 饶平县| 六盘水市| 灯塔市| 禹城市| 沂源县| 汪清县| 图片| 布拖县| 珲春市| 铁岭县| 海阳市| 阳江市| 金秀| 肇州县| 屏南县| 弥勒县| 班戈县| 城口县| 淳化县| 集安市| 青冈县| 湘西| 灵川县| 亳州市| 临江市| 简阳市| 和静县| 江西省| 和顺县| 信宜市| 安多县| 内黄县|