我一直在开发一个名为Deque的程序。该程序有四种方法:给定一个任意数组,我可以将一个元素添加到数组的前面(addFirst)、后面(addLast)、移除第一个元素(removeFirst)和移除最后一个元素(removeLast)。
(StdIn、StdOut是API,其工作方式与C相同)
是的,程序会编译,我可以添加和删除列表中的项目。在我停止添加元素并尝试打印出列表上的元素之前,一切都很顺利(我指定StdIn.isEmpty=True并中断循环;请参阅主方法。)。例如,输入1和2会给我以下错误:
java Deque1.java
+
Type your input String addFirst: 1
++
Type your input String addLast: 2
deque[]: Exception in thread "main" java.lang.ClassCastException: [Ljava.lang.Object; cannot be cast to [Ljava.lang.String;
at Deque1.main(Deque1.java:123)
第123行为:StdOut.print(dequeinstance.deque[(dequeinstance.first + i) % dequeinstance.deque.length] + " ");
我已经处理这个小错误好几个小时了,但返回的只是一个重复的运行时错误。我相信我已经将Item声明为String类型,但我不明白为什么代码不起作用。请帮帮我。这是我写的代码,它不断地给我classcastexception错误:
import java.util.Iterator;
import java.util.NoSuchElementException;
public class Deque1<Item> implements Iterable<Item> {
private Item[] deque;
private int N = 0;
private int last = 0;
private int first = 0;
public Deque1() // construct an empty deque
{
deque = (Item[]) new Object[2];
}
public boolean isEmpty() // is the deque empty?
{
return N == 0;
}
public int size() // return the number of items on the deque
{
return N;
}
public void addFirst(Item item) // add the item to the front
{
if(item == null) throw new java.lang.NullPointerException();
if(N == deque.length) resize(2 * deque.length);
deque[first--] = item;
if (first == -1) first = deque.length - 1;
N++;
}
public void addLast(Item item) // add the item to the end
{
if(item == null) throw new java.lang.NullPointerException();
if(N == deque.length) resize(2*deque.length);
if(last == deque.length - 1) last = -1;
deque[++last] = item;
N++;
}
public Item removeFirst() // remove and return the item from the front
{
if (isEmpty()) throw new NoSuchElementException("Queue underflow");
if(N > 0 && N == deque.length/4) resize(deque.length/2);
if(first == deque.length - 1) first = -1;
Item item = deque[++first];
deque[first] = null;
return item;
}
public Item removeLast() // remove and return the item from the end
{
if (isEmpty()) throw new NoSuchElementException("Queue underflow");
if(N > 0 && N == deque.length/4) resize(deque.length/2);
Item item = deque[last];
deque[last--] = null;
if(last == -1) last = deque.length -1;
N--;
return item;
}
private void resize(int capacity)
{
Item[] temp = (Item[]) new Object[capacity];
for(int i = 0; i < N; i++)
{
temp[i] = deque[(first + i)%deque.length];
}
deque = temp;
first = 0;
last = N - 1;
}
public Iterator<Item> iterator() {return new ArrayIterator();}
// an iterator, doesn't implement remove() since it's optional
private class ArrayIterator implements Iterator<Item> {
private int i = 1;
public boolean hasNext() {return i <= N;}
public void remove() {throw new java.lang.UnsupportedOperationException();}
public Item next()
{
if (!hasNext()) throw new java.util.NoSuchElementException();
Item item = deque[(i + first) % deque.length];
i++;
return item;
}
}
public static void main(String[] args)
{
Deque1<String> dequeinstance = new Deque1();
//String[] dq = dequeinstance.deque;
//Iterator<String> itr = dq.iterator();
while (!StdIn.isEmpty())
{
String item = StdIn.readString();
if (item.equals("--")) dequeinstance.removeLast();
else if (item.equals("-")) dequeinstance.removeFirst();
else if (item.equals("++"))
{
StdOut.print("Type your input String addLast: ");
String item2 = StdIn.readString();
dequeinstance.addLast(item2);
}
else if (item.equals("+"))
{
StdOut.print("Type your input String addFirst: ");
String item2 = StdIn.readString();
dequeinstance.addFirst(item2);
}
}
//for(String str : itr)
StdOut.print("deque[]: ");
for(int i = 1; i <= dequeinstance.size(); i++)
{
StdOut.print(dequeinstance.deque[(dequeinstance.first + i) % dequeinstance.deque.length] + " ");
}
System.out.println();
}
}
ps。另一点需要注意的是,我如何创建一个迭代列表deque(String[]deque)中所有元素的迭代器?
当我尝试创建迭代器时
Iterator<String> itr = dq.iterator();
我得到一个编译错误:
Deque1.java:99: error: cannot find symbol
Iterator<String> itr = dq.iterator();
^
symbol: method iterator()
location: variable dq of type String[]
我试图使用一种替代方法,删除dq并直接引用类deque 中的deque
Iterator<String> itr = dequeinstance.deque.iterator();
这一次,我得到了一个类似但不同的错误:
Iterator<String> itr = dequeinstance.deque.iterator();
^
symbol: method iterator()
location: variable deque of type Item[]
where Item is a type-variable:
Item extends Object declared in class Deque1
我已经将Java泛型添加到代码中,以便正确地从迭代器类继承。
我相信代码现在可以正常工作了。
ClassCastException不再发生,发生这种情况有两个原因,您使用的是"dequeinstance.deque.length"而不是"dequeinstance.size()",这不是一个大问题。但最大的问题是缺乏Java泛型的使用,这导致Java不理解以下行:
dequeinstance.deque[(dequeinstance.first + i) % dequeinstance.deque.length] + " "
实际上是一根绳子。
这就是为什么需要泛型。
请参阅下面的代码。
package test;
import java.util.Iterator;
import java.util.NoSuchElementException;
public class Deque1<E> implements Iterable<E> {
private Object[] deque;
private int N = 0;
private int last = 0;
private int first = 0;
public Deque1() // construct an empty deque
{
deque = (Object[]) new Object[2];
}
public boolean isEmpty() // is the deque empty?
{
return N == 0;
}
public int size() // return the number of items on the deque
{
return N;
}
public void addFirst(Object item) // add the item to the front
{
if(item == null) throw new java.lang.NullPointerException();
if(N == deque.length) resize(2 * deque.length);
deque[first--] = item;
if (first == -1) first = deque.length - 1;
N++;
}
public void addLast(Object item) // add the item to the end
{
if(item == null) throw new java.lang.NullPointerException();
if(N == deque.length) resize(2*deque.length);
if(last == deque.length - 1) last = -1;
deque[++last] = item;
N++;
}
public Object removeFirst() // remove and return the item from the front
{
if (isEmpty()) throw new NoSuchElementException("Queue underflow");
if(N > 0 && N == deque.length/4) resize(deque.length/2);
if(first == deque.length - 1) first = -1;
Object item = deque[++first];
deque[first] = null;
return item;
}
public Object removeLast() // remove and return the item from the end
{
if (isEmpty()) throw new NoSuchElementException("Queue underflow");
if(N > 0 && N == deque.length/4) resize(deque.length/2);
Object item = deque[last];
deque[last--] = null;
if(last == -1) last = deque.length -1;
N--;
return item;
}
private void resize(int capacity)
{
Object[] temp = (Object[]) new Object[capacity];
for(int i = 0; i < N; i++)
{
temp[i] = deque[(first + i)%deque.length];
}
deque = temp;
first = 0;
last = N - 1;
}
public Iterator<E> iterator() {return (Iterator<E>) new ArrayIterator();}
// an iterator, doesn't implement remove() since it's optional
private class ArrayIterator implements Iterator<Object> {
private int i = 1;
public boolean hasNext() {return i <= N;}
public void remove() {throw new java.lang.UnsupportedOperationException();}
public Object next()
{
if (!hasNext()) throw new java.util.NoSuchElementException();
Object item = deque[(i + first) % deque.length];
i++;
return item;
}
}
public static void main(String[] args)
{
Deque1<String> dequeinstance = new Deque1<String>();
//String[] dq = dequeinstance.deque;
//Iterator<String> itr = dq.iterator();
while (!StdIn.isEmpty())
{
String item = StdIn.readString();
if (item.equals("--")) dequeinstance.removeLast();
else if (item.equals("-")) dequeinstance.removeFirst();
else if (item.equals("++"))
{
StdOut.print("Type your input String addLast: ");
String item2 = StdIn.readString();
dequeinstance.addLast(item2);
}
else if (item.equals("+"))
{
StdOut.print("Type your input String addFirst: ");
String item2 = StdIn.readString();
dequeinstance.addFirst(item2);
}
}
//for(String str : itr)
StdOut.print("deque[]: ");
for(int i = 1; i <= dequeinstance.size(); i++)
{
StdOut.print(dequeinstance.deque[(dequeinstance.first + i) % dequeinstance.deque.length] + " ");
}
System.out.println();
}
}
在回答第二个问题时,您的类已经是一个迭代器了。你不能把迭代器变成迭代器。迭代器类提供了.next()等函数,您已经拥有了这些函数,因此无法再次获得这些函数。
当我尝试创建迭代器时
Iterator<String> itr = dq.iterator();
我收到编译时错误
Deque1.java:99: error: cannot find symbol
Iterator<String> itr = dq.iterator();
^
symbol: method iterator()
location: variable dq of type String[]
这个编译时错误是不言自明的,因为你的dq类型是String[]
,它不是集合接口的实现类,迭代器方法是Collection Interface
,而不是String[]
正如文件所说
Iterator<E> iterator()
返回此集合中元素的迭代器。没有关于元素返回顺序的保证(除非此集合是某个类的实例,该类提供担保)。
现在来到
另一点需要注意的是,我如何创建一个迭代列表中的所有元素deque(String[]deque)?
First List和Array不相同,
private Item[] deque; // can not Iterate with Iterator
private List<Item> deque;//Iterate this with an Iterator since it is a List
如果你想在迭代器的帮助下对数组进行迭代,那么就使用这个
Arrays.asList(deque).iterator();