tuplas - java value pair list
Usando pares o 2 tuplas en Java (14)
Esta pregunta ya tiene una respuesta aquí:
- ¿Una colección de Java de pares de valores? (tuplas?) 17 respuestas
My Hashtable en Java se beneficiaría de un valor que tenga una estructura de tupla. ¿Qué estructura de datos puedo usar en Java para hacer eso?
Hashtable<Long, Tuple<Set<Long>,Set<Long>>> table = ...
Aunque el artículo es bastante antiguo ahora, y entiendo que no soy muy útil, creo que el trabajo realizado aquí: http://www.pds.ewi.tudelft.nl/pubs/papers/cpe2005.pdf , hubiera sido agradable en la corriente principal de Java.
Puedes hacer cosas como:
int a;
char b;
float c;
[a,b,c] = [3,''a'',2.33];
o
[int,int,char] x = [1,2,''a''];
o
public [int,boolean] Find(int i)
{
int idx = FindInArray(A,i);
return [idx,idx>=0];
}
[idx, found] = Find(7);
Aquí las tuplas son:
- Definido como tipos primitivos - sin plantillas / genéricos
- Asignado a la pila si se declara localmente
- Asignado utilizando el patrón de coincidencia
Este enfoque aumenta
- Actuación
- Legibilidad
- Expresividad
Comenzaré desde un punto de vista general sobre las tuplas en Java y terminaré con una implicación para su problema concreto.
1) La forma en que se utilizan las tuplas en lenguajes no genéricos se evita en Java porque no son de tipo seguro (por ejemplo, en Python: tuple = (4, 7.9, ''python'')
). Si aún desea usar algo como una tupla de propósito general (que no se recomienda ), debe usar Object[]
o List<Object>
y lanzar los elementos después de una verificación con instanceof
para garantizar la seguridad de tipo.
Por lo general, las tuplas en una configuración determinada siempre se usan de la misma manera que con la misma estructura. En Java, debe definir esta estructura explícitamente en una class
para proporcionar valores y métodos bien definidos y seguros. Esto parece molesto e innecesario al principio, pero evita errores ya en tiempo de compilación .
2) Si necesita una tupla que contenga las mismas (super) clases de Foo
, use Foo[]
, List<Foo>
, o List<? extends Foo>
List<? extends Foo>
(o las contrapartes inmutables de las listas). Como una tupla no tiene una longitud definida, esta solución es equivalente.
3) En su caso, parece que necesita un Pair
(es decir, una tupla de longitud bien definida 2). Esto hace que la respuesta de maerics o una de las respuestas complementarias sea la más eficiente, ya que puede reutilizar el código en el futuro.
Como una extensión de la buena respuesta de @maerics, he agregado algunos métodos útiles:
public class Tuple<X, Y> {
public final X x;
public final Y y;
public Tuple(X x, Y y) {
this.x = x;
this.y = y;
}
@Override
public String toString() {
return "(" + x + "," + y + ")";
}
@Override
public boolean equals(Object other) {
if (other == this) {
return true;
}
if (!(other instanceof Tuple)){
return false;
}
Tuple<X,Y> other_ = (Tuple<X,Y>) other;
// this may cause NPE if nulls are valid values for x or y. The logic may be improved to handle nulls properly, if needed.
return other_.x.equals(this.x) && other_.y.equals(this.y);
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((x == null) ? 0 : x.hashCode());
result = prime * result + ((y == null) ? 0 : y.hashCode());
return result;
}
}
Con lombok es fácil declarar una clase Pair
:
@Data(staticConstructor = "of")
public class Pair<A, B> {
private final A left;
private final B right;
}
Esto generará captadores, constructor estático denominado "of", equals()
, hashcode()
y toString()
.
Crea una clase que describa el concepto que realmente estás modelando y usa eso. Solo puede almacenar dos Set<Long>
y proporcionar accesores para ellos, pero debe nombrarse para indicar qué es exactamente cada uno de esos conjuntos y por qué están agrupados.
Esta es exactamente la misma pregunta en otra parte, que incluye un equals
más robusto, hash
que alude maerics:
Esa discusión continúa para reflejar los enfoques de maerics vs ColinD de "debería reutilizar una clase Tuple con un nombre no específico, o crear una nueva clase con nombres específicos cada vez que me encuentre con esta situación". Hace años estuve en este último campamento; He evolucionado para apoyar al primero.
No creo que haya una clase de tupla de propósito general en Java, pero una personalizada podría ser tan fácil como la siguiente:
public class Tuple<X, Y> {
public final X x;
public final Y y;
public Tuple(X x, Y y) {
this.x = x;
this.y = y;
}
}
Por supuesto, hay algunas implicaciones importantes de cómo diseñar esta clase aún más con respecto a la igualdad, la inmutabilidad, etc., especialmente si planea usar instancias como claves para el hashing.
Otros 2 centavos: A partir de Java 7, ahora hay una clase para esto en Lib estándar: javafx.util.Pair.
Y sí, es Java estándar, ahora que JavaFx está incluido en el JDK :)
Para complementar la respuesta de @maerics, aquí está la tupla Comparable
:
import java.util.*;
/**
* A tuple of two classes that implement Comparable
*/
public class ComparableTuple<X extends Comparable<? super X>, Y extends Comparable<? super Y>>
extends Tuple<X, Y>
implements Comparable<ComparableTuple<X, Y>>
{
public ComparableTuple(X x, Y y) {
super(x, y);
}
/**
* Implements lexicographic order
*/
public int compareTo(ComparableTuple<X, Y> other) {
int d = this.x.compareTo(other.x);
if (d == 0)
return this.y.compareTo(other.y);
return d;
}
}
Puedes usar Google Guava Table
Si está buscando una tupla de dos elementos Java incorporada, intente AbstractMap.SimpleEntry
.
Apache Commons proporcionó algunas utilidades comunes de Java, incluyendo un Pair . Implementa Map.Entry
, Comparable
y Serializable
.
Este objeto proporciona una implementación sensible de equals (), devolviendo verdadero si equals () es verdadero en cada uno de los objetos contenidos.
javatuples es un proyecto dedicado para tuplas en Java.
Unit<A> (1 element)
Pair<A,B> (2 elements)
Triplet<A,B,C> (3 elements)