2013-08-25 58 views
4

以下代码不起作用。这段代码有什么问题?编译器在for循环中抱怨NumberList不是Iterable类。for-each循环只能遍历数组或java.lang.Iterable的实例

什么样的类可以用于for-each循环?如何使NumberList可迭代?我试着制作NumberList implement Iterable,但它似乎不工作,因为我不知道如何正确定义Iterator。

如果有人能演示如何使这段代码工作,或者将我链接到一个很棒的教程。

public class Test{ 
    public class NumberList{ 
     private int numItems; 
     private Number[] numbers; 

     public NumberList(int size){ 
      this.numbers = new Number[size]; 
      this.numItems=0; 
     } 

     public void add(Number n){ 
      this.numbers[this.numItems++]=n; 
     } 
    } 

    public void printPairs() { 
     ArrayList<Integer> num=new ArrayList<Integer>(); 

     NumberList numbers = new NumberList(50); 
     numbers.add(4); 
     numbers.add(5); 
     numbers.add(6); 

     for(Number n1: numbers){ 
      System.out.println(n1); 
     } 
    } 
} 
+3

为什么你定义自己的列表,而不是使用一个ArrayList? –

+0

首先,肯定使用JDK附带的列表。正如前面的评论者所说,没有用来定义你自己的。但是如果你想修复你的代码,编译器给了你答案。只需实现Iterable并填写所需的方法。 –

+0

还有其他关于如何实现Iterable的问题,包括[实现Iterable接口](http://stackoverflow.com/questions/6050379/implementing-the-iterable-interface)。 –

回答

4

NumberList不实现Iterable。就编译器而言,它只关心其他任何类。

你需要做这样的事情

public class NumberList implements Iterable<Number> { 

    private int numItems; 
    private Number[] numbers; 

    public NumberList(int size) { 
     this.numbers = new Number[size]; 
     this.numItems = 0; 
    } 

    public void add(Number n) { 
     this.numbers[this.numItems++] = n; 
    } 

    @Override 
    public Iterator<Number> iterator() { 
     return Arrays.asList(numbers).subList(0, numItems).iterator(); 
    } 
} 
+0

答案很好,但是说明了这个练习的无用性:你拥有的只是一个很薄的代表层,没有增加任何值。 – Bohemian

+0

答案并不好,因为迭代器遍历数组的所有元素,而不仅仅是遍历第一个numItems元素。 –

+1

@JB你当然是对的,更新的答案。有了这些愚蠢的玩具的例子,它很容易被误解成一种错误的意识,你不能误解它。 – monkjack

0

您需要implementIterable interface。在这种情况下,这意味着您需要将方法Iterator<T> iterator()添加到您的NumberList类中。由于您的列表只包含这种情况下的数字,所以通用类型参数T只是Number

3

NumberList类需要实现Iterable接口:

import java.util.ArrayList; 
import java.util.Arrays; 
import java.util.Iterator; 

public class Test { 
    public class NumberList implements Iterable<Number> { 
     private int numItems; 
     private Number[] numbers; 

     public NumberList(int size) { 
      this.numbers = new Number[size]; 
      this.numItems = 0; 
     } 

     public void add(Number n) { 
      this.numbers[this.numItems++] = n; 
     } 

     @Override 
     public Iterator<Number> iterator() { 
      return Arrays.asList(numbers).iterator(); 
     } 

    } 

    public void printPairs() { 

     ArrayList<Integer> num = new ArrayList<Integer>(); 

     NumberList numbers = new NumberList(50); 
     numbers.add(4); 
     numbers.add(5); 
     numbers.add(6); 

     for (Number n1 : numbers) { 
      System.out.println(n1); 
     } 
    } 
}  
+0

我有个问题,为什么“implements Iterable ”需要泛型?为什么我不能把它作为Iterable?在我的编译器中,似乎我可以将迭代器方法保留为原始类型,但需要在“实现”中将作为泛型类型。 – turtlesoup

+4

@Jimster如果你实现原始的'Iterable'而不是'Iterable',那么你只能说'for(Object o:numbers)',编译器会拒绝'for(Number n:numbers)' –

+0

In一般来说,即使编译器会允许你,如果有其他选择,将任何东西都保留为原始类型永远不是一个好主意。 –

相关问题