如果我想创建一个固定大小的整数缓冲区,我会使用new int[size]
。现在,假设我想在泛型类型上创建一个缓冲区。
一个可能的解决方案是:
List<T> buffer = new ArrayList<T>(size);
for (int i = 0; i < size; ++i)
buffer.add(null);
// now simply access the buffer via buffer.get() and buffer.set()
我应该使用哪些更好的东西?一个示例用例将是implement a queue。请注意,这不是真实的用例,而是面试问题。
答案 0 :(得分:3)
你可以做这样的事情
private final T[] items;
public RingBuffer(Class<T> clazz, int capacity) {
this.items = (T[]) Array.newInstance(clazz, capacity);
}
你必须转发T[]
,但它确实是T[]
而不是Object[]
答案 1 :(得分:1)
由于Java中的泛型系统已断开,您无法使用参数化数组定义,但由于类型擦除,您可以选择将一个对象数组分配给参数数组声明,然后它可以绕过VM的类型系统在运行时。 在此之后,使用此数组的任何操作都必须满足类型T,编译器将确保在编译时发生。你只需要解决这个定义。
class ArrayList<V> {
private V[] backingArray;
public ArrayList() {
backingArray = (V[]) new Object[DEFAULT_SIZE];
}
}
答案 2 :(得分:0)
将一个通用集合包装在一个自定义类中,您可以在其中控制固定大小的集合。例如:
class Queue<T> {
private ArrayList<T> q;
private int size;
public Queue(int size) {
this.size = size;
this.q = new ArrayList<T>(size);
}
public int size() {
return size;
}
// ...
public T get(int index) {
if (index > q.size()) {
return null;
}
// ... or whatever
return q.get(index);
}
}
** 编辑 **
或者更具体地说,创建自己的Collection兼容泛型类。例如:
public class FixedQueue<E> extends AbstractList<E> {
private Object[] queue;
public FixedQueue(int size) {
queue = new Object[size];
}
@Override
public E set(int index, E element) {
Object old = queue[index];
queue[index] = element;
modCount++;
return (E) old;
}
@Override
public E get(int index) {
return (E) queue[index];
}
@Override
public int size() {
return queue.length;
}
@Override
public E remove(int index) {
Object old = queue[index];
System.arraycopy(queue, index+1, queue, index, queue.length - index - 1);
modCount++;
return (E) old;
}
}
此未经测试的类将允许get
和set
以及remove
操作,但不允许add
等。但如果您愿意,可以根据自己的规范实施。如果您需要添加一个功能(例如ensureCapacity
)来实现它而不涉及任何其他来源,那么实现类而不是使用固定大小的数组将允许您。
** 更新 **
我刚刚看到你的编辑,基本上,你正在开始。只需使用一个Object
数组,当你得到一个元素时,你将其转换为你的泛型类型。例如,请参阅Java的ArrayList
实现。
答案 3 :(得分:0)
java.util.ArrayDeque
(或java.util.concurrent.ArrayBlockingQueue)。但是,我建议你实现自己的循环缓冲区/队列。这是一个非常好的练习。
至于缓存int []我建议你不要这样做。 重要提示:如果要使用某些缓存机制,请不要像tomcat那样使用ConcurrentLinkedQueue。 缓存应该使用堆栈而不是队列,ArrayDeque和ArrayBlockingQueue都适合堆栈。