3

方法一

ArrayList<String> list = new ArrayList<String>();

for (String s : list) {
    write.append(s);
    write.append('\n');
}

如何循环通过ArrayList这种方式?这种方法不是只适用于静态常用数组吗,例如:

String[] list2 = new String[]{"1","2","3","4"};

如果我想遍历ArrayList<String> list,为什么不这样做,例如:

方法 2

for (int i = 0; i < list.size(); i++) {
    write.append(list.get(i));
    write.append("\n");
}

我只是不明白如何使用Method 1。欢迎任何解释。

4

5 回答 5

3

这些称为 for-each 循环,可以应用于数组和集合。格式:

for ([type] [var-name] : [array or iterable value]) {
    ...
}

要使用 for-each 循环,您只需要满足以下两个条件之一:

  1. 迭代值是一个数组,或者
  2. 迭代值为Iterable.

我们这样做的最大原因是因为List它不是唯一Iterable可以在循环中使用的,而是唯一可以被索引。这使您可以进行通用迭代,而不是将自己锁定在固定的索引列表格式中。

例如,HashSet没有排序,但我仍然可以在 for-each 循环中对其进行迭代:

HashSet<String> strs = new HashSet<String>();
for (String str : strs) { ... }

我也可以有一个方法采取 anIterable而不是 a List

public static void printStrings(Iterable<String> strs) {
    for (String str : strs) {
        System.out.println(str);
    }
}

如果不先将其复制到其他东西(例如数组或List.

使用 for-each 循环的另一个重要原因是它编译为使用Iterator列表外(通过Iterable.iterator()),这允许快速失败迭代。这会导致类似ConcurrentModificationExceptions 的信息告诉我们,在我们对其进行迭代时,该集合已被修改。例如,这将总是抛出一个ConcurrentModificationException

List<String> strs = ... ;
for (String str : strs) {
    strs.remove(str);
}

但这不会:

List<String> strs = ... ;
for (int i = 0; i < strs.length(); i++) {
    strs.remove(str);
}

这对多线程应用程序很有用,因为您应该在访问列表之前锁定列表,因为大多数List实现都不是为线程安全而设计的,而且如果没有外部同步,无论是使用索引还是使用Iterator. 如果一个线程对其进行迭代,而另一个线程对其进行了更改,则可以(不能保证,但可以)抛出一个ConcurrentModificationException,它告诉您该列表未正确锁定。被索引的永远不会给你这种信息。相反,它只会表现出奇怪的行为,比如跳过元素。

于 2013-07-21T05:31:36.947 回答
3

ArrayList实现Iterable使其提供一个Iterator对象,然后由 for 循环用户使用。

任何实现的类Iterable都可以在 for 循环中使用,就像数组一样。

简化的 for 循环对于数组和集合看起来相同,但在底层,它使用数组的索引和集合的迭代器。

于 2013-07-21T05:24:40.580 回答
2

有一个称为Iterable允许快速迭代的接口。如果实现了某些东西Iterable,则允许快速迭代。该Iterable接口有一个方法,该方法返回一个Iterator可用于迭代元素的方法。

于 2013-07-21T05:24:14.140 回答
1

第一个称为增强型,或“for each”。它被认为是传统for语句模型的语法糖 - 允许您迭代集合中的每个元素 - 无论是数组还是 Java 集合框架中的任何内容。

这些类型的循环之间有两个明显的区别:

  • 增强的 for 语句为您索引值,将其作为声明的一部分存储在临时变量中。因此,您不必执行val[i]value.get(i)- 这会自动为您发生。
  • 您无法在增强的 for 语句中指定增量;您要么遍历集合中的所有元素,要么通过break语句提前终止。

可以使用标准数组对其进行迭代的原因在 JLS 中定义,特别是§14.14.2 - 因为数组没有实现Iterable,它将其转换为标准行为for语句。

  • ...否则,表达式必须具有数组类型 T[]。

    L1 ... Lm是紧接在增强的 for 语句之前的(可能为空的)标签序列。

增强的 for 语句等效于以下形式的基本 for 语句:

T[] #a = Expression; 
L1: L2: ... Lm:
for (int #i = 0; #i < #a.length; #i++) {
    VariableModifiers(opt) TargetType Identifier = #a[#i];
    Statement
}

#a 和 #i 是自动生成的标识符,与增强 for 语句发生时范围内的任何其他标识符(自动生成或以其他方式)不同。

于 2013-07-21T05:28:23.993 回答
1

这是 for-each 语法:http ://docs.oracle.com/javase/1.5.0/docs/guide/language/foreach.html

编译器会将方法 1 中的代码转换为:

for (Iterator<String> iterator = list.iterator(); iterator.hasNext(); ) {
  String s = iterator.next();
  write.append(s);
  write.append('\n');
}
于 2013-07-21T05:24:27.447 回答