2011-07-12 54 views
10

Tengo algunas preguntas sobre getters y setters para matrices. Supongamos que tenemos una clase como esta, lo que hace una copia privada de una matriz en su constructor:Getters y setters para matrices

import java.util.Arrays; 

public class Foo 
{ 
    private int[] array; 

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

Queremos que la matriz sólo se puede acceder a/mutado a través de los captadores y definidores. Si tenemos un captador que tiene este aspecto:

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

en contra del propósito del captador ya que estamos devolviendo una referencia que permite al usuario modificar directamente los elementos de la matriz. p.ej.

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

Así que, presumiblemente, necesitamos algo como esto:

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

Del mismo modo para los emisores. Pero si estamos haciendo las cosas en función de cada elemento, también vamos a tener que proporcionar un medio para conseguir la longitud:

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

Esto ya es un poco desordenado para una matriz de dimensión 1, pero decir que tenemos una matriz multidimensional en su lugar:

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; 
    } 
} 

se trata de una gran cantidad de código para una tarea tan trivial, y lo más importante es un desastre a utilizar realmente. ¿Realmente tenemos que terminar con algo como esto, o hay una mejor manera de hacerlo? He buscado por todos lados y no parece haber una "práctica estándar" para esto.

+0

¿ha mirado las listas? – Jacob

+1

Las matrices son tan de 1900. – Marcelo

Respuesta

7

una matriz multi-dimensional es también una matriz de dimensión 1: int[a][b][c] es realmente sólo int[a*b*c], por lo que el problema se reduce a que, ¿cómo se proporciona acceso de forma segura? Simplemente así:

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

Eso es todo.

Las personas que llaman tienen una copia segura de la matriz y pueden usarla de la manera normal en que se utilizan las matrices. No hay necesidad de métodos delegadores.

1

¿Qué crees que ArrayList hace, o Vector antes que?

Creo que la mejor pregunta es por qué, en este punto, ¿está exponiendo que Foo está respaldado por una matriz? Si está tratando de encapsularlo, no necesita tener accesodores ni instaladores por todos lados. Si solo intenta crear un contenedor de clases alrededor de la matriz, entonces le sugiero que tenga una interfaz, llámelo IntList o algo similar, y haga de Foo una implementación concreta respaldada por la lista.

1

En relación con la primera parte ¿podría su getter no parecerse al constructor?

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

Escribí una pequeña API para matrices genéricas multidimensionales. Ahí tienes getters, setters para cada elemento, sean cuales sean tus dimensiones.

MDDAJ on github

Aquí está un ejemplo: la creación de una matriz de 5 cuerdas dimensiones:

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] 

Bohemia ya escribió puede utilizar una sola dimensión. En este caso, la clase PDDAPSeudo interna también tiene una dimensión. Pero la API le proporciona acceso como una matriz multidimensional

Cuestiones relacionadas