如何使 2D ArrayList 不可变?

发布于 2024-11-16 19:13:01 字数 503 浏览 3 评论 0 原文

在我正在从事的项目中,我有一个代表一些数据的 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!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

缱绻入梦 2024-11-23 19:13:01

使用 Collections.unmodifyingList方法:

ArrayList<ArrayList<String>> source = new ArrayList<ArrayList<String>>();
List<ArrayList<String>> out = Collections.unmodifiableList(source);

source集合上调用Collections.unmodifyingList,不会使每个嵌套列表不可修改。如果您希望所有嵌套列表不可修改,则需要在列表上递归地执行此操作。所以:

ArrayList<ArrayList<String>> source = new ArrayList<ArrayList<String>>();
List<List<String>> temp = new ArrayList<List<String>>();
for (ArrayList<String> list : source) {
    temp.add(Collections.unmodifiableList(list));
}
List<List<String>> out = Collections.unmodifiableList(temp);    

Use the Collections.unmodifiableList method:

ArrayList<ArrayList<String>> source = new ArrayList<ArrayList<String>>();
List<ArrayList<String>> out = Collections.unmodifiableList(source);

Calling Collections.unmodifiableList on the source 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:

ArrayList<ArrayList<String>> source = new ArrayList<ArrayList<String>>();
List<List<String>> temp = new ArrayList<List<String>>();
for (ArrayList<String> list : source) {
    temp.add(Collections.unmodifiableList(list));
}
List<List<String>> out = Collections.unmodifiableList(temp);    
圈圈圆圆圈圈 2024-11-23 19:13:01

我建议创建一个处理可变性问题的包装类,而不是在整个代码库中使用 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.

世俗缘 2024-11-23 19:13:01

您可以编写自己的不可变矩阵包装器。

public class ImmutableMatrix<T>
{
    private ArrayList<ArrayList<T>> matrix;

    public ImmutableMatrix(ArrayList<ArrayList<T>> matrix)
    {
        this.matrix = matrix;
    }

    public T get(int x, int y)
    {
        return matrix.get(y).get(x); // Maybe you want to swap x and y
    }

    public int height()
    {
        return matrix.size();
    }

    public int width(int y)
    {
        return matrix.get(y).size();
    }

}

正如我在代码中所写,也许您想交换 xy
或者将它们重命名为 level0level1

这样,您就不必复制任何内容。这就足够了:

public Matrix<T> returnInspectData()
{
     return new Matrix(data); 
}

You can write your own immutable matrix wrapper.

public class ImmutableMatrix<T>
{
    private ArrayList<ArrayList<T>> matrix;

    public ImmutableMatrix(ArrayList<ArrayList<T>> matrix)
    {
        this.matrix = matrix;
    }

    public T get(int x, int y)
    {
        return matrix.get(y).get(x); // Maybe you want to swap x and y
    }

    public int height()
    {
        return matrix.size();
    }

    public int width(int y)
    {
        return matrix.get(y).size();
    }

}

As I wrote in the code, maybe you want to swap x and y.
Or rename them as level0 and level1.

This way, you don't have to copy anything. This is sufficient:

public Matrix<T> returnInspectData()
{
     return new Matrix(data); 
}
埋情葬爱 2024-11-23 19:13:01

假设列表列表是表示数据的最佳方式:

private ArrayList<ArrayList<T>> data = (put your data here);


ArrayList<ArrayList<String>> temp = new ArrayList<ArrayList<String>>();
for (ArrayList<String> l : data) {
    temp.add(Collections.unmodifiableList(l));
}
return Collections.unmodifiableList(temp);

对于大小为 n × m 的数组,运行时间为 O(n)


列表列表是对不规则填充的矩阵执行临时数据收集的好方法,但是如果您实际上正在处理固定大小的常规二维数组,那么围绕支持 String[][] 创建一个包装对象,并移动创建和操作该数据的业务逻辑是有意义的进入那个物体。这包括返回矩阵的只读视图,如果您有一个函数需要只读 List>,您可以返回一个实现该视图的视图对象来自支持阵列的接口。

Assuming a list of lists is the best way to represent your data:

private ArrayList<ArrayList<T>> data = (put your data here);


ArrayList<ArrayList<String>> temp = new ArrayList<ArrayList<String>>();
for (ArrayList<String> l : data) {
    temp.add(Collections.unmodifiableList(l));
}
return Collections.unmodifiableList(temp);

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-only List<List<String>>, you can return an view object that implements that interface from the backing arrays.

世态炎凉 2024-11-23 19:13:01

您可以使用 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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文