2012-03-05 21 views
16

Soy nuevo en Java, quiero almacenar una matriz de pares de dobles. Mi código se ve así:¿Cómo almacenar una matriz de pares en Java?

import java.util.ArrayList; 
import java.util.Map.Entry; 

List<Entry<Double, Double>> values = new ArrayList<>(); 
Entry<Double, Double> pair; 
// set pair values: 
// pair.setKey(0.5); // this method does not exists 
// pair.setValue(3.6); 
values.add(pair); 

¿Cómo puedo inicializar la variable de par? ¿Hay una estructura mejor para almacenar mi matriz de dobles?

+1

Si no puede molestarse, siempre puede intentar: http://www.javatuples.org/ – Nim

+0

Duplicate of http://stackoverflow.com/questions/521171/a-java-collection-of-value-pairs -tuples –

Respuesta

15

crear su propia clase para representar un par y añadir un constructor que toma dos argumentos:

public class MyPair 
{ 
    private final Double key; 
    private final Double value; 

    public MyPair(Double aKey, Double aValue) 
    { 
     key = aKey; 
     value = aValue; 
    } 

    public Double key() { return key; } 
    public Double value() { return value; } 
} 

Ver esta respuesta por razones por las que un Pair no existe en Java: What is the equivalent of the C++ Pair<L,R> in Java?

+2

Me sorprende que no haya algo que pueda usar en la biblioteca java estándar para una cosa tan simple –

+4

. Vea esta respuesta por las razones por las cuales no existe dicho 'Pair': http://stackoverflow.com/questions/156275/ what-is-the-equivalent-of-the-c-pairl-r-in-java – hmjd

+0

tenga en cuenta que esta solución aumenta enormemente la complejidad del proyecto ya que puede tener 100 clases diferentes que son efectivamente pares, pero cada uno tiene un tipo distinto; requiere una clasificación personalizada entre los tipos, que es tanto propensa a errores, se ve fea y costosa (como no se puede modificar de uno a otro, y hostilidad en caché). Está bien si todas las pairlikes implementan sus propios Marshallers, esto resuelve todos los problemas excepto el rendimiento y las diferentes versiones de pares que tienen una interfaz base con un nombre diferente, que se puede resolver al no tener una interfaz y utilizar la reflexión, pero ahora tiene otros problemas. – Dmitry

1

usted podría utilizar un mapa para resolver esto.

+1

true si cada "clave" es única. 'Map' no permite claves duplicadas – amit

+0

Dos pares pueden tener el mismo número de la izquierda, es decir: [(2, 6.3), (2, 8.4)] –

+0

Si tiene una' Doble' como clave, debe mirar este http://stackoverflow.com/q/1074781/1065197 –

1

¿Es Entry una clase que ha definido? Lo instancia con new.

Entry<Double, Double> pair = new Entry<Double, Double>(d1, d2); 

Nota Estoy suponiendo que haya definido un constructor que toma 2 dobles, y tiene referencias para d1 y d2.

Sugiero que NO utilice la clase Map.Entry. La semántica de esa clase es tal que los valores son una clave y un valor, que se ajustan a la forma en que funcionan los Mapas.

+0

mira las importaciones: "import java.util.Map.Entry;" – rompetroll

0

Si tiene acceso a la clase de Entrada, puede crear un constructor que tome la clave y el valor como parámetros.

Entry<Double, Double> pair = new Entry<Double, Double>(0.5, 3.6); 
values.add(pair); 
+0

Aparece el siguiente error: 'No se puede crear una instancia del tipo Map.Entry ' –

0

El tipo Map.Entry que está intentando utilizar es sólo una interfaz, y por lo tanto no puede ser instanciada. Si quisiera (mal) usar tipos internos de Map, entonces la implementación concreta Map.EntryHashEntry sería una opción.

Sin embargo, es una idea mucho mejor implementar su propio tipo de pareja. O para usar un mapa en lugar de una matriz, si es lo que necesita.

5

No desea utilizar la Entrada es una INTERFAZ, no una CLASE. Esa interfaz es utilizada por una implementación de Set cuando se llama a entrySet() en una clase que implementa Map. Básicamente, te permite manipular el mapa implementado como si fuera un conjunto.

Lo que harías (pero no puedes) es esto. Si intenta hacer esto, verá un error de compilación en la línea de "No se puede crear una instancia del tipo Map.Entry". Eso es porque Map.Entry es una interfaz, no una clase. Una interfaz no contiene ningún código real, por lo que no hay ningún constructor real para ejecutar aquí.

Entry<Double, Double> pair = new Entry<Double, Double>(); 

Si nos fijamos en los documentos siguientes se puede ver claramente en la parte superior que es un "Map.Entry Interface", que significa que es una interfaz. http://docs.oracle.com/javase/1.4.2/docs/api/java/util/Map.Entry.html

Lo que debe hacer en lugar de intentar crear una interfaz, lo cual es imposible, es crear su propia clase llamada Pair. Algo como esto. Recuerde cambiar el paquete si usa el siguiente código.

package org.mike.test; 

public class Pair { 
    private double x = 0.0; 
    private double y = 0.0; 

    public Pair(double x, double y) 
    { 
     this.x = x; 
     this.y = y; 
    } 

    public Pair() 
    { 

    } 

    public double getX() { 
     return x; 
    } 

    public void setX(double x) { 
     this.x = x; 
    } 

    public double getY() { 
     return y; 
    } 

    public void setY(double y) { 
     this.y = y; 
    } 


} 

Después de escribir su clase Pair, su código se verá así.

package org.mike.test; 

import java.util.ArrayList; 
import org.mike.test.Pair; //You don't need this if the Pair class is in the same package as the class using it 

public class tester { 

    /** 
    * @param args 
    */ 
    public static void main(String[] args) { 
     ArrayList<Pair> values = new ArrayList<Pair>(); 
     Pair pair = new Pair(); 
     // set pair values: 
     pair.setY(3.6); 
     pair.setX(3.6); 
     values.add(pair); 
    } 

} 
+0

Nice, y supongamos que nos dio un constructor Pair (doble, doble), simplificaría y eliminaría el setX/Y () llama y usa Pair pair = new Pair (3.6, 3.6); – Leif

0

Otro enfoque, y probablemente la forma más eficiente para almacenar y matriz de pares dobles es utilizar una única matriz de dobles, y el uso (2 * i) y (2 * i + 1) como su indexación esquema. Además, obtienes la ventaja de que la matriz se inicializará a todos los 0 cuando la crees, no se requieren pasos adicionales. Lamentablemente, hay un poco de sobrecarga de codificación adicional para implementar add() y eliminar(), pero sorprendentemente, es probablemente menos que crear su propia clase de contenedor para el par.

class MyClass { 
    double[] values; 
    int count; 

    MyClass(int initialCapacity) { 
     values = new double[initialCapacity*2]; 
    } 

    // adding a pair 
    void addPair(double x, double y) { 
     if (count*2 >= values.length) { 
      values = Arrays.copyOf(values, values.length*2); 
     } 
     values[count*2] = x; 
     values[count*2 + 1] = y; 
     count++; 
    } 

    void remove(int index) { 
     if (index >= count) throw new IndexOutOfBoundsException(); 

     if (index < --count) { 
      System.arraycopy(values, (index+1)*2, values, index*2, (count - index) * 2); 
     } 
    } 

    int size() { return count; } 

    // both these should check that index < count. 
    double getX(int index) { return values[index*2]; } 
    double getY(int index) { return values[index*2 + 1]; } 

    void exampleIteration() { 
     // getX/Y accessors are examples of how to get 
     // the values, but it will be more efficient 
     // in most cases to just access the array 
     // array directly as so... 
     for (int i=0 ; i<count ; ++i) { 
      System.out.printf("%d: (%f,%f)%n", i, values[i*2], values[i*2+1]); 
     } 
    } 
} 
2

no Podrías utilizar

public class MyClass<A,B> extends ArrayList{ 
private A first; 
private B second; 
public MyClass(A first, B second){ 
super(); 
this.first = first; 
this.second = second;} 
} 

y luego añadir algún tipo de método add, junto con un primer y segundo método mutador de acceso &? Soy un poco nuevo en la programación, pero de esta manera parece que podría funcionar, y ser accesible a otras cosas además del DOBLE, (en caso de que quiera usar otros tipos, como Integer, o incluso String) .

Cuestiones relacionadas