classcastexception来自一位入门程序员:从对象到字符串的转换



我一直在开发一个名为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();

相关内容

最新更新