这是一个基于数组的队列,用于int
:
/**
* Array based
* @author X220
*
*/
public class MyQueue {
private int[] _data;
private int MAX_SIZE;
private int front = -1;
private int back = 0;
private int elementsCount = 0;
public void printQueue()
{
int j = this.front + 1;
int i = 0;
while (i < this._data.length && i < elementsCount)
{
System.out.println("At location " + j % MAX_SIZE + " element :" + this._data[j % MAX_SIZE]);
j++;
i++;
}
}
public MyQueue(int _size)
{
MAX_SIZE = _size > 0 ? _size : 10;
this._data = new int[MAX_SIZE];
}
public boolean IsEmpty()
{
return this.elementsCount == 0;
}
public boolean IsFull()
{
return this.elementsCount == MAX_SIZE;
}
public void Push(int pushMe) throws QueueIsFullException
{
if (IsFull())
{
throw new QueueIsFullException("Queue is full");
}
this.elementsCount++;
_data[back++ % MAX_SIZE] = pushMe;
}
public int Pop() throws QueueIsEmptyException
{
if (IsEmpty())
{
throw new QueueIsEmptyException("Queue is full");
}
elementsCount--;
return _data[++front % MAX_SIZE];
}
public static void main(String args[])
{
try
{
MyQueue q1 = new MyQueue(15);
q1.Push(1);
q1.Push(2);
q1.Push(3);
q1.Push(4);
q1.Push(5);
q1.Pop();
q1.Pop();
q1.Pop();
q1.Pop();
q1.Pop();
q1.Push(6);
q1.Pop();
q1.Push(7);
q1.Push(8);
q1.Push(9);
q1.Push(10);
q1.Push(11);
q1.Push(12);
// q1.Push(1);
// q1.Push(2);
// q1.Push(3);
// q1.Push(4);
// q1.Push(5);
// q1.Push(7);
// q1.Push(8);
// q1.Push(9);
// q1.Push(10);
// q1.Push(11);
// q1.Push(12);
// q1.Push(40);
// q1.Push(50);
q1.printQueue();
}
catch (Exception e)
{
System.out.println(e);
}
}
@SuppressWarnings("serial")
class QueueIsFullException extends Exception
{
public QueueIsFullException(String message){
super(message);
}
}
@SuppressWarnings("serial")
class QueueIsEmptyException extends Exception
{
public QueueIsEmptyException(String message){
super(message);
}
}
}
我想使用泛型,所以我将int
更改为T
但我得到了这个:
public class MyQueue <T>{
private T[] _data;
private int MAX_SIZE;
private int front = -1;
private int back = 0;
private int elementsCount = 0;
public void printQueue()
{
int j = this.front + 1;
int i = 0;
while (i < this._data.length && i < elementsCount)
{
System.out.println("At location " + j % MAX_SIZE + " element :" + this._data[j % MAX_SIZE]);
j++;
i++;
}
}
public MyQueue(int _size)
{
MAX_SIZE = _size > 0 ? _size : 10;
this._data = new T[MAX_SIZE];
}
....
}
那:
- 无法创建T
的通用数组
从this post的答案中我发现我不能将泛型用于数组。
这是否意味着基于数组的泛型队列没有解决方法?我必须切换到其他一些数据结构吗?
答案 0 :(得分:3)
问题的根本原因不在于你的MyQueue类,我认为你误解了Java处理泛型的方式。通用类型仅在编译时存在,之后它们只是从字节代码中删除,并且在运行时只有真正的Java类型存在于幕后。
这就是为什么你不能实例化泛型类型的原因,因为在运行时这个参数化类型根本就不存在。
你可以做的是在MyQueue类中提供一个真实的类(扩展T)作为参数来实例化这个类类型,因为这是一个一流的Java类型。
这是一个非常相似的StackOverflow问题和解决方案: Instantiating a generic class in Java
还建议阅读关于泛型的Java参考,就像你原来问题的答案在这里: https://docs.oracle.com/javase/tutorial/java/generics/restrictions.html#createObjects
答案 1 :(得分:2)
没有解决这个丑陋的演员,将你的数组通用创建改为:
this._data = (T[])new Object[MAX_SIZE];
由于Java泛型的实现,您不能拥有这样的代码:
this._data = new T[MAX_SIZE];
答案 2 :(得分:2)
我喜欢的方法是使用
@SuppressWarnings("unchecked")
T[] arr = (T[]) Array.newInstance(clazz,length);
其中clazz
是与通用类型对应的Class<T>
对象。请注意,转换操作未选中,但Array.newInstance
可确保您无法在阵列中插入无效类型。
对我而言,这是最佳解决方案,因为:
Array
实例来处理Class<T>
类的类型一致性,该实例将用于转换插入数组中的所有对象。因此,这是类型安全的,无需您执行任何操作。Object[]
,就会出现这种情况。