在Java中定义固定大小的列表

fas*_*ava 41 java collections list

是否可以定义一个固定大小为100的列表?如果没有,为什么不能在Java中使用它?

McD*_*ell 35

如果内存服务,这应该这样做:

List<MyType> fixed = Arrays.asList(new MyType[100]);
Run Code Online (Sandbox Code Playgroud)

  • @fastcodejava - 你不能使用带有固定长度列表的`add`方法 - 它已经有100个空条目.使用`set`来设置值. (8认同)
  • 它会引发异常 (3认同)
  • 如果 `MyType` 是参数化类型,这将不起作用。例如,`List&lt;List&lt;String&gt;&gt; fixed = Arrays.asList(new List&lt;String&gt;[100]);` 将产生编译器错误。(在早期的 Java 版本中,它会生成警告。)请参阅 Java 教程中的 [Restrictions on Generics](https://docs.oracle.com/javase/tutorial/java/generics/restrictions.html)。 (2认同)

Ste*_*n C 27

你的问题是错误的,或者你的思维模型不正确List.


Java列表是对象的集合......列表的元素.列表的大小是该列表中元素的数量.如果您希望修复该大小,则意味着您无法添加或删除元素,因为添加或删除元素会违反"固定大小"约束.

实现"固定大小"列表的最简单方法(如果这真的是你想要的!)是将元素放入数组中,然后Arrays.asList(array)创建列表包装器.包装器将允许你这样做操作,如getset,但addremove操作将抛出异常.

如果要为现有列表创建固定大小的包装器,则可以使用Apache commons FixedSizeList类.但请注意,此包装器无法阻止其他更改原始列表大小的内容,如果发生这种情况,则包装列表可能会反映这些更改.(IMO,javadoc for FixedSizeList是可悲的.它不会尝试记录更改包装列表时类的行为.您需要阅读源代码...并希望它们不会改变您的行为不重视.)


另一方面,如果你真的想要一个对其大小有固定限制(或限制)的列表类型,那么你需要创建自己的List类来实现它.例如,您可以创建一个包装类,在各种add/ addAllremove/ removeAll/ retainAll操作中实现相关检查.(remove如果支持它们,则在迭代器方法中.)

那么为什么Java Collections框架没有实现这些呢?这就是为什么我这么认为:

  1. 需要这种情况的用例很少见.
  2. 在需要这种情况的用例中,当操作试图打破限制时,对于该怎么做有不同的要求; 例如抛出异常,忽略操作,丢弃一些其他元素来腾出空间.
  3. 具有限制的列表实现可能对辅助方法有问题; 例如Collections.sort.


Art*_*ald 18

是的,

共享库提供了一个内置的FixedSizeList,其不支持add,removeclear方法(但是被允许的组的方法,因为它不修改List的大小).换句话说,如果您尝试调用其中一种方法,则列表仍保持相同的大小.

要创建固定大小列表,只需致电

List<YourType> fixed = FixedSizeList.decorate(Arrays.asList(new YourType[100]));
Run Code Online (Sandbox Code Playgroud)

unmodifiableList如果需要指定列表的不可修改视图或对内部列表的只读访问权限,则可以使用.

List<YourType> unmodifiable = java.util.Collections.unmodifiableList(internalList);
Run Code Online (Sandbox Code Playgroud)

  • 如果它已经是固定大小的列表,为什么要装饰Arrays.asList结果? (12认同)
  • 是的......`FixedSizeList.decorate(...)`用于包装尚未固定大小的列表.在这里使用它是多余的. (4认同)

sna*_*ile 13

是.您可以将java数组传递给Arrays.asList(Object []).

List<String> fixedSizeList = Arrays.asList(new String[100]);
Run Code Online (Sandbox Code Playgroud)

您不能将新的字符串插入fixedSizeList(它已经有100个元素).您只能像这样设置其值:

fixedSizeList.set(7, "new value");
Run Code Online (Sandbox Code Playgroud)

这样你就有了一个固定大小的列表.这个东西就像一个数组,我想不出一个使用它的好理由.我很想知道为什么你希望固定大小的集合成为一个列表,而不是只使用一个数组.


sha*_*ams 8

通常,固定大小列表的替代方案是Java阵列.默认情况下,列表允许在Java中增长/缩小.但是,这并不意味着您不能拥有固定大小的列表.您需要做一些工作并创建自定义实现.

您可以使用clear,add和remove方法的自定义实现扩展ArrayList.

例如

import java.util.ArrayList;

public class FixedSizeList<T> extends ArrayList<T> {

    public FixedSizeList(int capacity) {
        super(capacity);
        for (int i = 0; i < capacity; i++) {
            super.add(null);
        }
    }

    public FixedSizeList(T[] initialElements) {
        super(initialElements.length);
        for (T loopElement : initialElements) {
            super.add(loopElement);
        }
    }

    @Override
    public void clear() {
        throw new UnsupportedOperationException("Elements may not be cleared from a fixed size List.");
    }

    @Override
    public boolean add(T o) {
        throw new UnsupportedOperationException("Elements may not be added to a fixed size List, use set() instead.");
    }

    @Override
    public void add(int index, T element) {
        throw new UnsupportedOperationException("Elements may not be added to a fixed size List, use set() instead.");
    }

    @Override
    public T remove(int index) {
        throw new UnsupportedOperationException("Elements may not be removed from a fixed size List.");
    }

    @Override
    public boolean remove(Object o) {
        throw new UnsupportedOperationException("Elements may not be removed from a fixed size List.");
    }

    @Override
    protected void removeRange(int fromIndex, int toIndex) {
        throw new UnsupportedOperationException("Elements may not be removed from a fixed size List.");
    }
}
Run Code Online (Sandbox Code Playgroud)


dev*_*ity 5

创建一个大小为 100 的数组。如果需要 List 接口,则在其上调用Arrays.asList。它将返回一个由数组支持的固定大小的列表。