我试图迭代一个Object数组。使用next()方法是有效的,所以我猜测我的迭代器类和构造函数正在工作。
由于某些原因,当hasNext()方法运行时,我没有得到任何输出。
Iterator it = hej.iterator();
Object j = it.next();
System.out.println(j);
while(it.hasNext()){
Object i = it.next();
System.out.println(i + " ");
}
" hej"是我的Object数组。
我的下一个()代码;和hasNext()方法如下:
public class StackIterator implements Iterator<Object>{
// fields
private int element = 0;
private final Object[] elements;
private final int max;
// constructor
public StackIterator(Object[] values, int maxIndex) {
elements = values;
max = maxIndex;
}
// methods
public boolean hasNext() {
return element < max;
}
public Object next() {
return elements[element++];
}
}
构造Object Array和Object Array的文件取决于接口:
public interface Stack {
int size();
boolean isEmpty();
void push(Object element);
Object pop();
Object peek();
Iterator<Object> iterator();
}
然后在另一个文件中解释这些方法:
public class StackExample implements Stack {
// fields
int length = 0;
Object[] arr;
// constructor
public StackExample() {arr = new Object[length];}
// method returns size of object array
public int size() {
return arr.length;
}
// method checks if object is empty
public boolean isEmpty() {
boolean result = false;
if (arr.length == 0){
result = true;
}
return result;
}
// method for push
public void push(Object element) {
newBiggerObj();
arr[0] = element;
}
// returns the first object of the stack
public Object pop() {
Object[] temp = new Object[arr.length-1];
Object first = arr[0];
for (int i = 0; i<arr.length-1; i++){
temp[i] = arr[i+1];
}arr = temp;
return first;
}
// returns the object on top of stack
public Object peek() {
if (isEmpty()){
try{
throw new Exception("Stack empty, can't peek!");
}
catch(Exception e){
return e.getMessage();
}
}
else {
Object first = arr[0];
return first;
}
}
// method for push method
private void newBiggerObj(){
Object[] temp = new Object[arr.length+1];
for (int i = 0; i<arr.length; i++){
temp[i+1] = arr[i];
}
arr = temp;
}
public String toString(){
String str = "";
for (int i = 0; i < arr.length; i++){
str = str + arr[i] + " , ";
}return str;
}
public Iterator<Object> iterator() {
return new StackIterator(arr, length);
}
}
困扰我的是Iterator方法本身返回了Stack Iterator类的实例。我在上面发布的。所以我真正的问题似乎是我的字段没有被赋予任何价值,因为我不是自己在构造函数中给出任何值。
我测试所有这些的主要方法如下:
public class Teststack {
public static void main(String[] args){
// new instane of class StackExample
StackExample hej = new StackExample();
// test for the different methods
System.out.println(hej.isEmpty());
System.out.println(hej.size());
hej.push(4);
hej.push("hej");
hej.push(6);
hej.push(5);
System.out.println(hej.size());
System.out.println(hej.peek());
System.out.println(hej.pop());
System.out.println(hej.toString());
System.out.println(hej.isEmpty());
System.out.println("Testing Iterator: ");
// test for iterator
Iterator it = hej.iterator();
Object j = it.next();
System.out.println(j);
while(it.hasNext()){
Object i = it.next();
System.out.println(i + " ");
}
}
}
答案 0 :(得分:1)
在StackExample
课程中,我不会看到在推送或弹出元素时更新的length
变量。因此,length
将始终为0,并且对it.hasNext()
的调用将始终返回false。
您不需要将长度作为单独的参数传递。您可以在StackIterator
构造函数中找到数组的长度并使用它。
另请注意,由于您在每次推送和弹出时都创建了一个新数组,StackExample#iterator()
返回的迭代器在每次推送/弹出后都会变得陈旧,因为它可以在旧的副本/状态下工作堆栈。
答案 1 :(得分:0)
几个问题:
Object j = it.next();
,然后检查hasNext。您正在递增元素索引。因此,如果您只有一个元素,则不会进入while循环。此外,如果您的自定义数据结构为空,即数组没有元素,那么您很容易出现ArrayIndexOutOfBoundException。答案 2 :(得分:0)
尽量不要打电话 对象j = it.next()语句,但只是循环。看起来你有一个只有1个元素的数组。
答案 3 :(得分:0)
问题在于:
public Iterator<Object> iterator() {
return new StackIterator(arr, length);
}
length
字段永远不会更改,因此其值始终为0
。您可以将代码更改为:
public Iterator<Object> iterator() {
return new StackIterator(arr, arr.length);
}
此外,在从迭代器中检索元素之前,应始终调用it.hasNext
。你这样做的事实:
Iterator it = hej.iterator();
Object j = it.next();
工作只是纯粹的运气。
除此之外,我可以感觉到你的堆栈实现设计不好。以下是一些改进代码的提示:
java.util.ArrayList
实施中所述)。push
)或从堆栈中删除(pop
)元素时,应避免创建新数组。除此之外,您应该使用length
字段来控制stack
中的元素数量。array.length + 1
。例如,尝试使用int newSize = array.length / 2 * 3;
。push
时,仅在您需要增加数组大小时才执行此操作。在调用pop
时,如果数组的当前长度(array.length
)远远超过您班级length
字段的值,请执行此操作。length
和push
方法上更新pop
的值。答案 4 :(得分:0)
此代码存在许多问题:
StackIterator
构造函数中,maxIndex
没有边界检查。呼叫者可以传入大于values.length
,小于0等的数字next
方法中,无法直接或通过调用hasNext()
来检查结束条件。来电者可以继续致电next()
并查看max
以外的元素,甚至可以获得ArrayIndexOutOfBoundsException
,这时他们应该获得NoSuchElementException
。Stack
类永远不会递增或递减其length
字段。Stack
类与数组分开跟踪length
,即使它总是在每次推送或弹出时调整数组大小,但Java数组已经知道它们的大小。 (但请参阅下一个项目。)Stack
类在每次推送或弹出时调整数组大小,效率非常低。通常,这样的类只在必要时调整数组大小,允许“松弛”空间,以提供分摊的常量时间性能(请参阅ArrayList)。但是,如果执行此操作,则必须null
弹出项目以避免无意识的对象保留。Stack
在数组的开头添加和删除元素。这是非常低效的,因为这意味着必须在每次推送或弹出时进行O(n)重新洗牌。peek()
方法考虑了Stack
可能为空的可能性,但pop()
方法没有。空pop()
上的Stack
会抛出ArrayIndexOutOfBoundsException
。Stack
不是通用类。它持有Object
。 Stack
的用户必须转换peek()
或pop()
的返回值,并且它不是类型安全的。在您的示例中,您显示的堆栈是String
和Integer
的异构混合。这是一种非常Java的方式,虽然它不一定是错的,但您应该考虑参数化Stack
。