Java 哪种集合类型最适合于不断更新、固定大小的字符串数组?
我遇到了一种情况,我需要Android中的Java 哪种集合类型最适合于不断更新、固定大小的字符串数组?,java,android,collections,Java,Android,Collections,我遇到了一种情况,我需要Android中的集合类型,它可以容纳字符串对象,并满足以下标准: 它有一个固定的大小(比如说10) 只能从集合的一端添加对象 添加新对象时,所有其他对象将自动沿一个空间移动以容纳该对象 如果集合已满(所有10空间已占用),则当从一端添加一个对象时,从另一端删除该对象 可以随时在任一方向上迭代集合的内容,并在每个位置检索对象 根据我对收集类型的经验,我觉得像队列或链接列表这样的东西是合适的,尽管我从未亲自使用过这两种类型。然而,Android文档中的一些术语让我对它们
集合
类型,它可以容纳字符串
对象,并满足以下标准:
- 它有一个固定的大小(比如说
)10
- 只能从
集合的一端添加对象
- 添加新对象时,所有其他对象将自动沿一个空间移动以容纳该对象
- 如果
已满(所有集合
空间已占用),则当从一端添加一个对象时,从另一端删除该对象10
- 可以随时在任一方向上迭代
,并在每个位置检索对象李>集合的内容
队列
或链接列表
这样的东西是合适的,尽管我从未亲自使用过这两种类型。然而,Android文档中的一些术语让我对它们是否符合我的要求感到困惑
例如,在的文档中,说明:
队列通常(但不一定)以FIFO(先进先出)方式对元素排序
这听起来很理想,但是当我考虑<代码> Ad())/<代码>和<代码>提供()/代码>方法时,它们都指定:
如果可以在不违反容量限制的情况下立即将指定元素插入此队列中 这听起来和我想要的正好相反 对于,说明包括以下行: 如果您需要类似队列的行为,则该类主要非常有用 这是完美的,但稍后它再次暗示了一个事实,即当需要灵活的大小时,LinkedList
非常有用
如果您希望列表包含零个或一个元素,但仍然需要能够扩展到稍微多一些的元素,那么它也可以用作列表
及
链表的主要优点是,您不需要为列表指定固定的大小。添加到链中的元素越多,链越大
有人能澄清一下这些类型中的一种是否适合我的情况吗
LinkedList
肯定会有用。“添加”逻辑只是:
list.add(newItem);
if (list.size() > MAX_SIZE) {
list.remove(0);
}
如果您需要超高效,可以使用字符串[MAX_SIZE]
,并使用当前
索引说明您在其中的位置(例如,环形缓冲区)。“添加”逻辑即:
buffer[current] = newItem;
current = (current + 1) % MAX_SIZE;
最后一行移动到下一个位置,必要时再次环绕到0
假设您预先填充它(例如,它从不为空或部分为空),则按添加顺序循环逻辑为:
for (int index = (current + 1) % MAX_SIZE; index != current; index = (index + 1) % MAX_SIZE) {
// ...
}
如果它可能是空的或部分空的,并且假设
null
不是有效的非空值,您可以做同样的事情,但是跳过null
s。不要偷懒,自己做吧
public class Collection<T> implements Iterable<T>, RandomAccess{
private final Object[] data;
private int size = 0;
public enum Direction{
LEFT,
RIGHT
}
private Direction direction = Direction.LEFT;
public Collection(int capacity){
data = new Object[capacity];
}
public void setDirection(Direction direction){
this.direction = direction;
}
public void add(T item){
if(size < data.length){
switch (direction){
case LEFT:
data[data.length - size] = item;
break;
case RIGHT:
data[size] = item;
break;
}
size++;
}
else {
switch (direction) {
case LEFT:
System.arraycopy(data, 1, data, 0, data.length - 1);
data[0] = item;
break;
case RIGHT:
System.arraycopy(data, 1, data, 0, data.length - 1);
data[data.length - 1] = item;
break;
}
}
}
public void remove(){
if(size == 0){
return;
}
switch (direction){
case LEFT:
remove(data.length - size);
break;
case RIGHT:
remove(size);
break;
}
}
public int size(){
return size;
}
private void remove(int index) {
System.arraycopy(data, index + 1, data, index, data.length - 1 - index);
data[data.length - 1] = null;
}
@Override
public Iterator<T> iterator() {
return new Iterator<T>() {
private int current = direction == Direction.RIGHT ? 0 : data.length - 1;
@Override
public boolean hasNext() {
switch (direction){
case LEFT:
return current > 0;
case RIGHT:
default:
return current < data.length;
}
}
@Override
public T next() {
current += direction == Direction.RIGHT ? 1 : -1;
Object result = data[current];
//noinspection unchecked
return (T) result;
}
@Override
public void remove() {
Collection.this.remove(current + (direction == Direction.RIGHT ? -1 : 1));
}
};
}
}
public类集合实现了Iterable、random访问{
私有最终对象[]数据;
私有整数大小=0;
公共枚举方向{
左边
正确的
}
专用方向=Direction.LEFT;
公共收集(国际容量){
数据=新对象[容量];
}
公共空间设置方向(方向){
这个方向=方向;
}
公共作废新增(T项){
if(尺寸<数据长度){
开关(方向){
案例左:
数据[data.length-大小]=项目;
打破
案例权利:
数据[大小]=项目;
打破
}
大小++;
}
否则{
开关(方向){
案例左:
System.arraycopy(数据,1,数据,0,数据长度-1);
数据[0]=项目;
打破
案例权利:
System.arraycopy(数据,1,数据,0,数据长度-1);
数据[data.length-1]=项目;
打破
}
}
}
公共空间删除(){
如果(大小==0){
返回;
}
开关(方向){
案例左:
删除(数据长度-大小);
打破
案例权利:
移除(尺寸);
打破
}
}
公共整数大小(){
返回大小;
}
私有void删除(int索引){
System.arraycopy(数据,索引+1,数据,索引,数据长度-1-索引);
data[data.length-1]=null;
}
@凌驾
公共迭代器迭代器(){
返回新的迭代器(){
private int current=direction==direction.RIGHT?0:data.length-1;
@凌驾
公共布尔hasNext(){
开关(方向){
案例左:
返回电流>0;
案例权利:
违约:
返回电流<数据长度;
}
}
@凌驾
公共交通工具{
电流+=方向==方向。右侧?1:-1;
对象结果=数据[当前];
//未检查
返回(T)结果;
}
@凌驾
公共空间删除(){
Collection.this.remove(current+(direction==direction.RIGHT?-1:1));
}
};
}
}
有一个系列
可以满足您几乎所有的需求-它是最适合您的
不幸的是,它在一个方面有不足之处:
阵列设备没有容量限制;它们根据需要增长以支持使用
从正面来看:
这个类可能比Stack whe更快
private final int maxSize;
public MyArrayDeque(int maxSize) {
super(maxSize);
this.maxSize= maxSize;
}
@Override
public void addFirst(E e) {
if (maxSize == size())
removeLast();
super.addFirst(e);
}
@Override
public void addLast(E e) {
if (maxSize == size())
removeFirst();
super.addLast(e);
}