Java中的for-each
Java这门现代语言为程序员提供了很多便利的开发手段。具体就循环而言,除开从C和C++继承而来的传统for写法,也提供了在很多时候(包括在解答AP计算机科学主观题)更为方便的for-each语句。
比如对于一个String
的数组,传统上遍历每一个元素需要这么写:
String[] fruits = new String[] { "Orange", "Apple", "Pear", "Strawberry" }; for (int i = 0; i < fruits.length; i++) { String fruit = fruits[i]; // fruit is an element of the `fruits` array. }
但这个可以等价于更加简洁的for-each语句:
String[] fruits = new String[] { "Orange", "Apple", "Pear", "Strawberry" }; for (String fruit : fruits) { // fruit is an element of the `fruits` array. }
for-each对于AP计算机科学所考察的List
也同样适用。所以
List someList = new ArrayList(); // add "monkey", "donkey", "skeleton key" to someList for (String item : someList) { System.out.println(item); }
事实上等价于
List someList = new ArrayList(); // add "monkey", "donkey", "skeleton key" to someList for (Iterator i = someList.iterator(); i.hasNext();) { String item = i.next(); System.out.println(item); }
注意for-each的括号中只有两个部分:前面的是一个自定义的变量,其作用域仅限于for之后的花括号中,用于遍历数组或集合中的每个元素;后面则是数组或集合的名字,注意数组或集合所包含的数据类型需要和前面的变量一致,否则会出错。两者之间通过一个冒号分隔。
for-each的好处在于写法更加简洁优雅,避免了对于索引或者Iterator
的直接操作,也确保了数组或集合中的每个元素都会被读取。
但是for-each同时也带来了以下这些问题:
- for-each循环无法修改数组的内容,也无法改变集合的结构。
以下的示例代码对数组本身不会有任何影响,num
只是一个一次性的局部变量。
for (int num : marks) { // only changes num, not the array element num = num*2; }
在for-each中调用所循环List
的add()
或remove()
method可能会抛出java.util.ConcurrentModificationException
异常。
- for-each循环无法读取索引或
Iterator
。
如果希望寻找某些满足特定条件的元素并返回索引或Iterator
,for-each不是一个理想的选择。
for (int num : numbers) { if (num == target) { return ???; // do not know the index of num } }
同理,for-each在同一层循环里一般只能处理一个数组或集合。
// cannot be easily converted to a for-each loop for (int i=0; i<numbers.length; i++) { if (numbers[i] == arr[i]) { ... } }
- for-each循环的顺序无法被调整,也必定访问所有元素。
对于逆序、部分、非标准间隔或者特殊的循环条件,for-each无法处理。
// cannot be converted to a for-each loop for (int i=numbers.length-1; i>0; i--) { System.out.println(numbers[i]); }
在什么情况下使用for-each?简单遍历、仅读取元素是一条可用的判据。
0 条评论