Геттеры и сеттеры для массивов
у меня есть несколько вопросов о геттерах и сеттерах для массивов. Предположим, у нас есть такой класс, который делает частную копию массива в его конструкторе:
import java.util.Arrays;
public class Foo
{
private int[] array;
public Foo(int[] array) {
this.array = Arrays.copyOf(array, array.length);
}
}
мы хотим, чтобы массив был доступен/мутирован только через геттеры и сеттеры. Если у нас есть геттер, который выглядит так:
public int[] getArray() {
return array;
}
теряется смысл геттер как мы возвращаем ссылку, которая позволяет пользователю напрямую изменять элементы массива. например,
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;
}
это уже немного беспорядочно для 1-мерного массива, но, скажем, у нас есть многомерный массив:
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;
}
}
это много кода для такой тривиальной задачи, и, что более важно, это беспорядок на самом деле использовать. Мы действительно должны закончить с чем-то подобным, или есть лучший способ сделать это? Я искал повсюду, и, похоже, для этого не существует "стандартной практики".
4 ответов
многомерный массив также является 1-мерным массивом: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);
}
}
вот именно.
вызывающие абоненты имеют безопасную копию массива и могут использовать его в полном обычном режиме. Нет необходимости в методах делегирования.
что думаете?ArrayList
или Vector
перед ним?
Я думаю, что лучший вопрос заключается в том, почему на данный момент вы подвергаете этоFoo
поддерживается массивом вообще? Если вы пытаетесь оформить его, вам не нужно иметь доступ, и сеттеры повсюду. Если вы просто пытаетесь создать оболочку класса вокруг массива, я бы предложил вам иметь интерфейс, назовите его IntList
или что-то, и сделать Foo
конкретная реализация, которая поддерживается по списку.
по отношению к первой части может ли ваш геттер не выглядеть как конструктор?
public int[] getArray() {
return Arrays.copyOf(array, array.length);
}
Я написал небольшой API для многомерных универсальных массивов. Там у вас есть геттеры, сеттеры для каждого элемента, каковы бы ни были ваши размеры.
вот пример: создание 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 уже написал, что вы можете использовать только одно измерение. В этом случае класс PDDAPSeudo internal также имеет одно измерение. Но API предоставляет вам доступ как многомерный массив