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

时间:2021-11-28 02:17:42

Is it possible to define a list with a fixed size that's 100? If not why isn't this available in Java?

是否可以定义一个固定大小为100的列表?如果没有,为什么这不适用于Java?

8 个解决方案

#1


15  

Yes,

Commons library provides a built-in FixedSizeList which does not support the add, remove and clear methods (but the set method is allowed because it does not modify the List's size). In other words, if you try to call one of these methods, your list still retain the same size.

Commons库提供了一个内置的FixedSizeList,它不支持add,remove和clear方法(但允许使用set方法,因为它不会修改List的大小)。换句话说,如果您尝试调用其中一种方法,则列表仍保持相同的大小。

To create your fixed size list, just call

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

List<YourType> fixed = FixedSizeList.decorate(Arrays.asList(new YourType[100]));

You can use unmodifiableList if you want an unmodifiable view of the specified list, or read-only access to internal lists.

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

List<YourType> unmodifiable = java.util.Collections.unmodifiableList(internalList);

#2


28  

This should do it if memory serves:

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

List<MyType> fixed = Arrays.asList(new MyType[100]);

#3


26  

Either your question is misstated, or you have an incorrect mental model of what a Java List is.

你的问题是错误的,或者你有一个不正确的心理模型,说明Java列表是什么。


A Java list is a collection of objects ... the elements of a list. The size of the list is the number of elements in that list. If you want that size to be fixed, that means that you cannot either add or remove elements, because adding or removing elements would violate your "fixed size" constraint.

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

The simplest way to implement a "fixed sized" list (if that is really what you want!) is to put the elements into an array and then Arrays.asList(array) to create the list wrapper. The wrapper will allow you to do operations like get and set, but the add and remove operations will throw exceptions.

实现“固定大小”列表的最简单方法(如果这真的是你想要的!)是将元素放入一个数组,然后是Arrays.asList(array)来创建列表包装器。包装器将允许您执行get和set等操作,但添加和删除操作将引发异常。

And if you want to create a fixed-sized wrapper for an existing list, then you could use the Apache commons FixedSizeList class. But note that this wrapper can't stop something else changing the size of the original list, and if that happens the wrapped list will presumably reflect those changes. (IMO, the javadoc for FixedSizeList is woeful. It makes no attempt to document how the class behaves when the wrapped list is changed. You will need to read the source code ... and hope that they don't change the behaviour when you are not paying attention.)

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


On the other hand, if you really want a list type with a fixed limit (or limits) on its size, then you'll need to create your own List class to implement this. For example, you could create a wrapper class that implements the relevant checks in the various add / addAll and remove / removeAll / retainAll operations. (And in the iterator remove methods if they are supported.)

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

So why doesn't the Java Collections framework implement these? Here's why I think so:

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

  1. Use-cases that need this are rare.
  2. 需要这种情况的用例很少见。

  3. The use-cases where this is needed, there are different requirements on what to do when an operation tries to break the limits; e.g. throw exception, ignore operation, discard some other element to make space.
  4. 在需要这种情况的用例中,当操作试图突破极限时,对于该怎么做有不同的要求;例如抛出异常,忽略操作,丢弃一些其他元素来腾出空间。

  5. A list implementation with limits could be problematic for helper methods; e.g. Collections.sort.
  6. 具有限制的列表实现可能对辅助方法有问题;例如Collections.sort。

#4


11  

Yes. You can pass a java array to Arrays.asList(Object[]).

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

List<String> fixedSizeList = Arrays.asList(new String[100]);

You cannot insert new Strings to the fixedSizeList (it already has 100 elements). You can only set its values like this:

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

fixedSizeList.set(7, "new value");

That way you have a fixed size list. The thing functions like an array and I can't think of a good reason to use it. I'd love to hear why you want your fixed size collection to be a list instead of just using an array.

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

#5


8  

Typically an alternative for fixed size Lists are Java arrays. Lists by default are allowed to grow/shrink in Java. However, that does not mean you cannot have a List of a fixed size. You'll need to do some work and create a custom implementation.

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

You can extend an ArrayList with custom implementations of the clear, add and remove methods.

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

e.g.

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.");
    }
}

#6


3  

Create an array of size 100. If you need the List interface, then call Arrays.asList on it. It'll return a fixed-size list backed by the array.

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

#7


2  

If you want some flexibility, create a class that watches the size of the list.

如果您需要一些灵活性,请创建一个监视列表大小的类。

Here's a simple example. You would need to override all the methods that change the state of the list.

这是一个简单的例子。您需要覆盖更改列表状态的所有方法。

public class LimitedArrayList<T> extends ArrayList<T>{
    private int limit;

    public LimitedArrayList(int limit){
        this.limit = limit;
    }

    @Override
    public void add(T item){
        if (this.size() > limit)
            throw new ListTooLargeException();
        super.add(item);
    }

    // ... similarly for other methods that may add new elements ...

#8


0  

If you want to use ArrayList or LinkedList, it seems that the answer is no. Although there are some classes in java that you can set them fixed size, like PriorityQueue, ArrayList and LinkedList can't, because there is no constructor for these two to specify capacity.

如果你想使用ArrayList或LinkedList,似乎答案是否定的。尽管java中有一些类可以设置它们固定大小,例如PriorityQueue,ArrayList和LinkedList不能,因为这两个类没有构造函数来指定容量。

If you want to stick to ArrayList/LinkedList, one easy solution is to check the size manually each time.

如果您想坚持使用ArrayList / LinkedList,一个简单的解决方案是每次手动检查大小。

public void fixedAdd(List<Integer> list, int val, int size) {
    list.add(val);
    if(list.size() > size) list.remove(0);
}

LinkedList is better than ArrayList in this situation. Suppose there are many values to be added but the list size is quite samll, there will be many remove operations. The reason is that the cost of removing from ArrayList is O(N), but only O(1) for LinkedList.

在这种情况下,LinkedList优于ArrayList。假设要添加许多值但列表大小非常小,则会有许多删除操作。原因是从ArrayList中删除的成本是O(N),但是对于LinkedList只有O(1)。

#1


15  

Yes,

Commons library provides a built-in FixedSizeList which does not support the add, remove and clear methods (but the set method is allowed because it does not modify the List's size). In other words, if you try to call one of these methods, your list still retain the same size.

Commons库提供了一个内置的FixedSizeList,它不支持add,remove和clear方法(但允许使用set方法,因为它不会修改List的大小)。换句话说,如果您尝试调用其中一种方法,则列表仍保持相同的大小。

To create your fixed size list, just call

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

List<YourType> fixed = FixedSizeList.decorate(Arrays.asList(new YourType[100]));

You can use unmodifiableList if you want an unmodifiable view of the specified list, or read-only access to internal lists.

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

List<YourType> unmodifiable = java.util.Collections.unmodifiableList(internalList);

#2


28  

This should do it if memory serves:

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

List<MyType> fixed = Arrays.asList(new MyType[100]);

#3


26  

Either your question is misstated, or you have an incorrect mental model of what a Java List is.

你的问题是错误的,或者你有一个不正确的心理模型,说明Java列表是什么。


A Java list is a collection of objects ... the elements of a list. The size of the list is the number of elements in that list. If you want that size to be fixed, that means that you cannot either add or remove elements, because adding or removing elements would violate your "fixed size" constraint.

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

The simplest way to implement a "fixed sized" list (if that is really what you want!) is to put the elements into an array and then Arrays.asList(array) to create the list wrapper. The wrapper will allow you to do operations like get and set, but the add and remove operations will throw exceptions.

实现“固定大小”列表的最简单方法(如果这真的是你想要的!)是将元素放入一个数组,然后是Arrays.asList(array)来创建列表包装器。包装器将允许您执行get和set等操作,但添加和删除操作将引发异常。

And if you want to create a fixed-sized wrapper for an existing list, then you could use the Apache commons FixedSizeList class. But note that this wrapper can't stop something else changing the size of the original list, and if that happens the wrapped list will presumably reflect those changes. (IMO, the javadoc for FixedSizeList is woeful. It makes no attempt to document how the class behaves when the wrapped list is changed. You will need to read the source code ... and hope that they don't change the behaviour when you are not paying attention.)

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


On the other hand, if you really want a list type with a fixed limit (or limits) on its size, then you'll need to create your own List class to implement this. For example, you could create a wrapper class that implements the relevant checks in the various add / addAll and remove / removeAll / retainAll operations. (And in the iterator remove methods if they are supported.)

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

So why doesn't the Java Collections framework implement these? Here's why I think so:

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

  1. Use-cases that need this are rare.
  2. 需要这种情况的用例很少见。

  3. The use-cases where this is needed, there are different requirements on what to do when an operation tries to break the limits; e.g. throw exception, ignore operation, discard some other element to make space.
  4. 在需要这种情况的用例中,当操作试图突破极限时,对于该怎么做有不同的要求;例如抛出异常,忽略操作,丢弃一些其他元素来腾出空间。

  5. A list implementation with limits could be problematic for helper methods; e.g. Collections.sort.
  6. 具有限制的列表实现可能对辅助方法有问题;例如Collections.sort。

#4


11  

Yes. You can pass a java array to Arrays.asList(Object[]).

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

List<String> fixedSizeList = Arrays.asList(new String[100]);

You cannot insert new Strings to the fixedSizeList (it already has 100 elements). You can only set its values like this:

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

fixedSizeList.set(7, "new value");

That way you have a fixed size list. The thing functions like an array and I can't think of a good reason to use it. I'd love to hear why you want your fixed size collection to be a list instead of just using an array.

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

#5


8  

Typically an alternative for fixed size Lists are Java arrays. Lists by default are allowed to grow/shrink in Java. However, that does not mean you cannot have a List of a fixed size. You'll need to do some work and create a custom implementation.

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

You can extend an ArrayList with custom implementations of the clear, add and remove methods.

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

e.g.

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.");
    }
}

#6


3  

Create an array of size 100. If you need the List interface, then call Arrays.asList on it. It'll return a fixed-size list backed by the array.

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

#7


2  

If you want some flexibility, create a class that watches the size of the list.

如果您需要一些灵活性,请创建一个监视列表大小的类。

Here's a simple example. You would need to override all the methods that change the state of the list.

这是一个简单的例子。您需要覆盖更改列表状态的所有方法。

public class LimitedArrayList<T> extends ArrayList<T>{
    private int limit;

    public LimitedArrayList(int limit){
        this.limit = limit;
    }

    @Override
    public void add(T item){
        if (this.size() > limit)
            throw new ListTooLargeException();
        super.add(item);
    }

    // ... similarly for other methods that may add new elements ...

#8


0  

If you want to use ArrayList or LinkedList, it seems that the answer is no. Although there are some classes in java that you can set them fixed size, like PriorityQueue, ArrayList and LinkedList can't, because there is no constructor for these two to specify capacity.

如果你想使用ArrayList或LinkedList,似乎答案是否定的。尽管java中有一些类可以设置它们固定大小,例如PriorityQueue,ArrayList和LinkedList不能,因为这两个类没有构造函数来指定容量。

If you want to stick to ArrayList/LinkedList, one easy solution is to check the size manually each time.

如果您想坚持使用ArrayList / LinkedList,一个简单的解决方案是每次手动检查大小。

public void fixedAdd(List<Integer> list, int val, int size) {
    list.add(val);
    if(list.size() > size) list.remove(0);
}

LinkedList is better than ArrayList in this situation. Suppose there are many values to be added but the list size is quite samll, there will be many remove operations. The reason is that the cost of removing from ArrayList is O(N), but only O(1) for LinkedList.

在这种情况下,LinkedList优于ArrayList。假设要添加许多值但列表大小非常小,则会有许多删除操作。原因是从ArrayList中删除的成本是O(N),但是对于LinkedList只有O(1)。