Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/189.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 哪种集合类型最适合于不断更新、固定大小的字符串数组?_Java_Android_Collections - Fatal编程技术网

Java 哪种集合类型最适合于不断更新、固定大小的字符串数组?

Java 哪种集合类型最适合于不断更新、固定大小的字符串数组?,java,android,collections,Java,Android,Collections,我遇到了一种情况,我需要Android中的集合类型,它可以容纳字符串对象,并满足以下标准: 它有一个固定的大小(比如说10) 只能从集合的一端添加对象 添加新对象时,所有其他对象将自动沿一个空间移动以容纳该对象 如果集合已满(所有10空间已占用),则当从一端添加一个对象时,从另一端删除该对象 可以随时在任一方向上迭代集合的内容,并在每个位置检索对象 根据我对收集类型的经验,我觉得像队列或链接列表这样的东西是合适的,尽管我从未亲自使用过这两种类型。然而,Android文档中的一些术语让我对它们

我遇到了一种情况,我需要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);
}