在我正在从事的项目中,我有一个代表一些数据的 2D ArrayList:
private ArrayList>; data = null;
现在我需要将此 ArrayList 返回给某个对象,以便让该对象检查它,但不能修改它。
我在下面的文章中发现 2D ArrayList 需要由不可修改的包装器单独包装,但它没有提到如何做到这一点:
java 集合的不可修改包装器是否使它们线程安全?
所以我的问题是:如何返回来自现有 2D ArrayList 的不可变 2D ArrayList?此外,由于实际数据可能很大,最快的方法是什么?
感谢您的所有投入!
In the project I am working on, I have a 2D ArrayList which represents some data:
private ArrayList<ArrayList<T>> data = null;
Now I need to return this ArrayList to some object, in order to let the object inspect it, but not modify it.
I found in the following post that a 2D ArrayList needs to be wrapped separately by the unmodifiable wrapper, but it does not mention how to do it:
Does the unmodifiable wrapper for java collections make them thread safe?
So my problem is: how to return an immutable 2D ArrayList from an existing 2D ArrayList? And in addition, what is the fastest way, since the data could be large in practice?
Thanks for all the inputs!
发布评论
评论(5)
使用
Collections.unmodifyingList
方法:在
source
集合上调用Collections.unmodifyingList
,不会使每个嵌套列表不可修改。如果您希望所有嵌套列表不可修改,则需要在列表上递归地执行此操作。所以:Use the
Collections.unmodifiableList
method:Calling
Collections.unmodifiableList
on thesource
collection, does not make each nested list unmodifiable. You'll need to do this recursively on the list, if you want all nested lists to be unmodifiable. So:我建议创建一个处理可变性问题的包装类,而不是在整个代码库中使用
List
。您可以使此类实现 List 接口,以便客户端实际上可以将其用作列表,但底层数据不一定是列表的列表(甚至可以是一个或多个数组)。>
在内部使用数组可以让您免去逐步浏览列表列表的麻烦,甚至可能最终提高性能。您还可以尝试查看其中一个数字 Java 库,看看它们是否提供不可变的高性能矩阵,除非此类只是您应用程序的一小部分,并且您不再需要任何其他内容。
I'd recommend creating a wrapper class which handles the mutability issues rather than having
List<List<T>>
all over the code-base. You can make this class implement the List interface so the clients can actually use it as a list but the underlying data need not necessarily be a list of lists (it can even be an array or arrays).Using an array internally will save you through the trouble of stepping through a list of lists which might even end up increasing performance. You can also try looking at one of the numeric Java libraries out there and see if they offer a immutable high performance matrix, unless this class is just a small part of your application and you won't be needing anything more.
您可以编写自己的不可变矩阵包装器。
正如我在代码中所写,也许您想交换
x
和y
。或者将它们重命名为
level0
和level1
。这样,您就不必复制任何内容。这就足够了:
You can write your own immutable matrix wrapper.
As I wrote in the code, maybe you want to swap
x
andy
.Or rename them as
level0
andlevel1
.This way, you don't have to copy anything. This is sufficient:
假设列表列表是表示数据的最佳方式:
对于大小为 n × m 的数组,运行时间为 O(n)
列表列表是对不规则填充的矩阵执行临时数据收集的好方法,但是如果您实际上正在处理固定大小的常规二维数组,那么围绕支持
String[][]
创建一个包装对象,并移动创建和操作该数据的业务逻辑是有意义的进入那个物体。这包括返回矩阵的只读视图,如果您有一个函数需要只读List
,您可以返回一个实现该视图的视图对象来自支持阵列的接口。>
Assuming a list of lists is the best way to represent your data:
Running time is O(n) for an array of size n by m
A list of lists is a decent way to perform ad-hoc data collection on irregularly populated matrixes, but if you're actually dealing with regular, 2D arrays of fixed size, it makes sense to create a wrapper object around a backing
String[][]
, and move your business logic that creates and manipulates that data into that object. This includes returning a read-only view of your matrix, and if you have a function that is expecting a read-onlyList<List<String>>
, you can return an view object that implements that interface from the backing arrays.您可以使用
Collections.unmodabilibleList( ... )
来完成您想要的操作。但是,这仅适用于一个列表,因此您也必须对内部列表执行此操作。另一种选择可能是二维数组。除此之外,您可以使用已经建议的包装类。
You might use
Collections.unmodifiableList( ... )
which does what you want. However, that works for one list only, so you'd have to do that for the inner lists as well.Another option might be a 2D array. Besides that, you might to use a wrapper class as has already been suggested.