数组的 getter 和 setter

发布于 2024-11-19 18:39:19 字数 1610 浏览 8 评论 0原文

我有一些关于数组的 getter 和 setter 的问题。假设我们有一个这样的类,它在其构造函数中创建一个数组的私有副本:

import java.util.Arrays;

public class Foo
{
    private int[] array;

    public Foo(int[] array) {
        this.array = Arrays.copyOf(array, array.length);
    }
}

我们希望该数组只能通过 getter 和 setter 进行访问/修改。如果我们有一个如下所示的 getter:

public int[] getArray() {
    return array;
}

它违背了 getter 的目的,因为我们返回一个允许用户直接修改数组元素的引用。例如

Foo foo = new Foo(someArray);
...
int[] bar = foo.getArray();
bar[0] = 123; // Now foo.array[0] = 123 and we haven't used a setter!

,我们大概需要这样的东西:

public int getElement(int index) {
    return array[index];
}

对于设置者来说也是如此。但是,如果我们在每个元素的基础上进行操作,我们还需要提供一种获取长度的方法:

public int getArrayLength() {
    return array.length;
}

对于一维数组来说这已经有点混乱了,但是假设我们有一个多维数组相反:

import java.util.Arrays;

public class Foo
{
    private int[][][] array;

    public Foo(int[][][] array) {
        // Code for making a deep copy here
    }

    public int getElement(int i, int j, int k) {
        return array[i][j][k];
    }

    public void setElement(int i, int j, int k, int value) {
        array[i][j][k] = value;
    }

    public int getArrayLength() {
        return array.length;
    }

    public int getArrayLength(int i) {
        return array[i].length;
    }

    public int getArrayLength(int i, int j) {
        return array[i][j].length;
    }
}

对于这样一个琐碎的任务来说,这是很多代码,更重要的是,实际使用起来很混乱。我们真的必须以这样的方式结束吗?还是有更好的方法来做到这一点?我查遍了所有地方,似乎没有一个“标准做法”。

I have a few questions about getters and setters for arrays. Suppose we have a class like this, which makes a private copy of an array in its constructor:

import java.util.Arrays;

public class Foo
{
    private int[] array;

    public Foo(int[] array) {
        this.array = Arrays.copyOf(array, array.length);
    }
}

We want the array to only be accessed/mutated via the getters and setters. If we have a getter that looks like this:

public int[] getArray() {
    return array;
}

it defeats the purpose of the getter as we're returning a reference that allows the user to directly modify the elements of the array. e.g.

Foo foo = new Foo(someArray);
...
int[] bar = foo.getArray();
bar[0] = 123; // Now foo.array[0] = 123 and we haven't used a setter!

So presumably we need something like this:

public int getElement(int index) {
    return array[index];
}

Similarly for setters. But if we're doing things on a per-element basis, we're also going to need to provide a means of getting the length:

public int getArrayLength() {
    return array.length;
}

This is already a little messy for a 1-dimensional array, but say we have a multidimensional array instead:

import java.util.Arrays;

public class Foo
{
    private int[][][] array;

    public Foo(int[][][] array) {
        // Code for making a deep copy here
    }

    public int getElement(int i, int j, int k) {
        return array[i][j][k];
    }

    public void setElement(int i, int j, int k, int value) {
        array[i][j][k] = value;
    }

    public int getArrayLength() {
        return array.length;
    }

    public int getArrayLength(int i) {
        return array[i].length;
    }

    public int getArrayLength(int i, int j) {
        return array[i][j].length;
    }
}

This is a lot of code for such a trivial task, and more importantly it's a mess to actually use. Do we really have to end up with something like this, or is there a better way to do it? I've looked all over the place and there doesn't seem to be a "standard practice" for this.

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

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

发布评论

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

评论(4

网白 2024-11-26 18:39:19

多维数组也是一维数组:int[a][b][c] 实际上只是 int[a*b*c],所以问题归结为,如何安全地提供访问?就这么简单:

public class Foo {
    private int[] array;

    public Foo(int[] array) {
        this.array = Arrays.copyOf(array, array.length);
    }

    /** @return a copy of the array */
    public int[] getArray() {
        return Arrays.copyOf(array, array.length);
    }
}

就是这样。

调用者拥有数组的安全副本,并且可以以完全正常的数组使用方式使用它。不需要委托方法。

A multi-dimensional array is also a 1-dimensional array: int[a][b][c] is really just int[a*b*c], so the problem boils down to, how do you provide access safely? Simply like this:

public class Foo {
    private int[] array;

    public Foo(int[] array) {
        this.array = Arrays.copyOf(array, array.length);
    }

    /** @return a copy of the array */
    public int[] getArray() {
        return Arrays.copyOf(array, array.length);
    }
}

That's it.

Callers have a safe copy of the array and can use it in the full normal way arrays are used. No need for delegator methods.

笑红尘 2024-11-26 18:39:19

您认为 ArrayList 或之前的 Vector 会做什么?

我认为更好的问题是,为什么此时您要公开 Foo 完全由数组支持?如果您尝试封装它,则不需要到处都有访问器和设置器。如果您只是尝试围绕数组创建一个类包装器,那么我建议您有一个接口,将其称为 IntList 或其他名称,并使 Foo 成为具体实现这是有清单支持的。

What do you think ArrayList does, or Vector before it?

I think the better question is why, at this point, are you exposing that Foo is backed by an array at all? If you're trying to encapsulate it, you don't need to have accessors and setters all over the place. If you're just trying to create a class wrapper around the array, then I would suggest you have an interface, call it IntList or something, and make Foo a concrete implementation that's backed by the list.

情绪操控生活 2024-11-26 18:39:19

关于第一部分,你的 getter 看起来不像构造函数吗?

public int[] getArray() {
    return Arrays.copyOf(array, array.length);
}

In relation to the first part could your getter not look like the constructor?

public int[] getArray() {
    return Arrays.copyOf(array, array.length);
}
歌枕肩 2024-11-26 18:39:19

我为多维通用数组编写了一个小型 API。无论你的尺寸是多少,每个元素都有 getter 和 setter。

github 上的 MDDAJ

这是一个示例:创建一个 5 维字符串数组:

MDDAPseudo<String> c = new MDDAPseudo<String>(10,20,5,8,15);
c.set("xyz", 0,0,2,1,0); // setter indices: [0][0][2][1][0]
String s = c.get(0,0,0,0,0); // getter indices [0][0][0][0][0]

Bohemian 已经写过你只能使用一个方面。在这种情况下,类 PDAPSeudo 内部也具有一维。但 API 为您提供了像多维数组一样的访问

I wrote a small API for multidimensional generic arrays. There you have getters, setters for each element, whatever your dimensions are.

MDDAJ on github

Here is a example: creating a 5 dimensional string array:

MDDAPseudo<String> c = new MDDAPseudo<String>(10,20,5,8,15);
c.set("xyz", 0,0,2,1,0); // setter indices: [0][0][2][1][0]
String s = c.get(0,0,0,0,0); // getter indices [0][0][0][0][0]

Bohemian already wrote you can use only one dimension. In this case the class PDDAPSeudo internal have one dimension, too. But the API provides you access like a multi dimensional array

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