【问题标题】:For-Each Loop Alternative - ClarificationFor-Each 循环替代方案 - 澄清
【发布时间】:2015-08-28 23:22:14
【问题描述】:

我正在学习 Java 课程,但无法完全理解下一课的内容。

目的:本课的目的是通过创建一个模拟 for-each 循环如何工作的替代方案来解释 for-each 循环的工作原理。

上一课对for-each循环的解释很简单:

import java.util.ArrayList //Imports ArrayList CLASS

public class ForEachLoops

{

    public static void main(String[] args)
    {

        ArrayList<Integer> numbers = new ArrayList<Integer>(); 
        // ^ Creates ArrayList object & calls constructor
        for(int i = 1; i < 11; ++i)
            numbers.add(i); //Just adding numbers 1-10 to the ArrayList.


        for(int n : numbers) //For-Each Loop
            System.out.println(n); //Returns value from each ArrayList element


    }

}

在下一课中,讲师展示了如何创建 for-each 循环的替代/模拟器。它的工作原理如下:

import java.util.ArrayList; //Importing ArrayList class from package
import java.util.Iterator; // Question 1 (See Below)

public class Chap16Part9
{

    public static void main(String[] args)
    {

        ArrayList<Integer> numbers = new ArrayList<Integer>();
        // ^ Creating object of ArrayList & calling constructor

        for(int i = 1; i < 11; ++i)
            numbers.add(i); //Just adding numbers 1-10 to ArrayList object

        for(Iterator<Integer> n = numbers.iterator(); n.hasNext();) {
   //       ^ Question 2 (See Below)
            int num = n.next(); //Points to the next element to assign value.
            System.out.println(num); //Prints current value of "num."
        }

    }

}

问题1:阅读Java文档后,“Iterator”被列为接口。这仍然与导入类相同吗?例如,在 Java 文档中,“java.util.Scanner”被认为是一个类,而不是一个接口。

问题 2:在问问题之前,循环不需要实现“++i”类型的控件,因为 Iterator 的 hasNext() 方法会检查是否有另一个元素去检查。如果没有,则停止。这是一个布尔值。然而,循环的开始,循环控制变量(LCV)是“Iterator&lt;Integer&gt; n = numbers.iterator();”,我不太明白这是什么意思。在我眼里,我看到了一个Iterator类的对象?设置为等于 ArrayList iterator() 方法。可能是因为给定“java.util.Interator;”被认为是一个接口(基本上是一个声明了如果由一个类实现则必须实现的方法的合约),ArrayList 类完成了 ArrayList 类中声明的 iterator() 方法的语句集,因此,需要以这种方式调用,而不是像调用传统类那样由构造函数调用(例如,ArrayList)?我对此有点困惑,我希望有人能阐明这一点。谢谢!

【问题讨论】:

  • 对于“Iterator n = numbers.iterator()”,我的意思是输入“Iterator n = numbers.iterator()”
  • 为了避免 &lt;whatever&gt; 被视为 HTML 标签而不是被显示的问题,总是使用 ` 包装代码片段。
  • The tutorial on for-each 解释得很好。
  • 访问迭代器documentation 解决所有问题。
  • ArrayList is (implements) List which is (extends) @​​987654330@ which is (extends) @​​987654331@ (注意它不是Iterator,而是Iterable目的是确保类可以通过调用iterator() 方法返回Iterator)。

标签: java loops foreach iterator


【解决方案1】:

Java 引用类型包括类、接口和枚举(以及数组,但它们有点不同)。它们都是定义行为的代码片段,因此需要导入您的程序以了解其中可用的方法等。

所以像Iterator 这样的接口有代码说明其中定义了哪些方法和常量,方法接受哪些参数,返回什么类型等等。编译器必须知道所有这些,才能检查程序的正确性并在它创建的字节码中生成对这些方法的正确调用。

List 中的方法 iterator() 返回一个迭代器,该迭代器遍历该列表中的项目。也就是说,来自实现Iterator 的类的对象。您不知道将是哪个类以及它是如何实现的——这些信息被封装在特定列表的代码中——但你知道它实现了Iterator,因此拥有Iterator 中声明的所有方法并根据它们实现它们到Iterator 合约。

因此,您可以将实现接口X的任何对象的引用分配给类型为X的变量,即使它只是一种接口类型。该变量指向某个类的实际对象,但程序只对它实现了 X 的事实感兴趣。

Iterator<Integer> n = numbers.iterator();

正是这样做的。它说“将n 声明为接口类型Iterator&lt;Integer&gt; 的变量。向numbers 列表询问它的迭代器,并将其分配给n。所以你的“循环变量”实际上是Iterator 对象。因为你知道它是 Iterator 类型 - 实现了 Iterator 合约 - 你知道你可以在上面使用 hasNext()next()。这就是你在循环条件检查和以下行中所做的。

【讨论】:

    【解决方案2】:

    接口类似于类,但不是构造一个新类,而是使用关键字 implements 实现接口。迭代器接口在许多 Java 标准类中实现。

    假设你有一个球工厂。 它可以抽出网球和篮球,这是您的课程。但是当网球和篮球都被制作时,它们具有相似的属性,例如 isRound() 和bounce() 等等。接口就像将这些属性组合在一个名称下。所以网球和篮球都实现了接口 Ball。

    因此,在实现可迭代的 List 中,您可以使用称为迭代器的可迭代方法,该方法可以遍历列表的元素。 Arraylist 也可以通过继承 List 来进行迭代。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-09-20
      • 1970-01-01
      • 2011-05-21
      • 1970-01-01
      • 1970-01-01
      • 2015-07-30
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多