¿Una colección Java de pares de valores? (tuplas?)

Me gusta cómo Java tiene un Mapa donde puede definir los tipos de cada entrada en el mapa, por ejemplo .

Lo que estoy buscando es un tipo de colección donde cada elemento de la colección es un par de valores. Cada valor en el par puede tener su propio tipo (como el ejemplo de Cadena y Entero anterior), que se define en el momento de la statement.

La colección mantendrá su orden dado y no tratará uno de los valores como una clave única (como en un mapa).

Básicamente, quiero poder definir un ARRAY de tipo o cualquier otro 2 tipos.

Me doy cuenta de que puedo hacer una clase con nada más que las 2 variables, pero parece excesivamente detallado.

También me doy cuenta de que podría usar una matriz 2D, pero debido a los diferentes tipos que necesito usar, tendría que hacer arreglos de OBJETOS, y luego tendría que lanzar todo el tiempo.

Solo necesito almacenar pares en la colección, por lo que solo necesito dos valores por entrada. ¿Existe algo como esto sin seguir la ruta de la clase? ¡Gracias!

La clase Pair es uno de esos ejemplos generics “gimme” que es bastante fácil de escribir por su cuenta. Por ejemplo, fuera de mi cabeza:

 public class Pair { private final L left; private final R right; public Pair(L left, R right) { this.left = left; this.right = right; } public L getLeft() { return left; } public R getRight() { return right; } @Override public int hashCode() { return left.hashCode() ^ right.hashCode(); } @Override public boolean equals(Object o) { if (!(o instanceof Pair)) return false; Pair pairo = (Pair) o; return this.left.equals(pairo.getLeft()) && this.right.equals(pairo.getRight()); } } 

Y sí, esto existe en varios lugares de la red, con diversos grados de integridad y características. (Mi ejemplo anterior está destinado a ser inmutable).

AbstractMap.SimpleEntry

Fácil, estás buscando esto:

 java.util.List> pairList= new java.util.ArrayList<>(); 

¿Cómo puedes llenarlo?

 java.util.Map.Entry pair1=new java.util.AbstractMap.SimpleEntry<>("Not Unique key1",1); java.util.Map.Entry pair2=new java.util.AbstractMap.SimpleEntry<>("Not Unique key2",2); pairList.add(pair1); pairList.add(pair2); 

Esto simplifica a:

 Entry pair1=new SimpleEntry<>("Not Unique key1",1); Entry pair2=new SimpleEntry<>("Not Unique key2",2); pairList.add(pair1); pairList.add(pair2); 

Y, con la ayuda de un método createEntry , puede reducir aún más la verbosidad a:

 pairList.add(createEntry("Not Unique key1", 1)); pairList.add(createEntry("Not Unique key2", 2)); 

Como ArrayList no es final, se puede subclasificar para exponer un método (y el método createEntry mencionado createEntry ), lo que resulta sintácticamente concisa:

 TupleList> pair = new TupleList<>(); pair.of("Not Unique key1", 1); pair.of("Not Unique key2", 2); 

Java 9+

En Java 9, puede simplemente escribir: Map.entry(key, value) para crear un par inmutable.

Nota: este método no permite que las claves o valores sean nulos. Si quiere permitir valores nulos, por ejemplo, querría cambiar esto a: Map.entry(key, Optional.ofNullable(value)) .


Java 8+

En Java 8, puede usar el javafx.util.Pair uso más general para crear un par inmóvil y serializable. Esta clase permite claves nulas y valores nulos. (En Java 9, esta clase está incluida en el módulo javafx.base ).


Java 6+

En Java 6 en adelante, puede usar la más detallada AbstractMap.SimpleImmutableEntry para un par inmutable, o AbstractMap.SimpleEntry para un par cuyo valor se puede cambiar. Estas clases también permiten claves nulas y valores nulos, y son serializables.


Androide

Si está escribiendo para Android, solo use Pair.create(key, value) para crear un par inmutable.


Apache Commons

Apache Commons Lang proporciona el Pair.of(key, value) útil de Pair.of(key, value) para crear un par inmutable, comparable y serializable.


Colecciones Eclipse

Si está utilizando pares que contienen primitivos, Eclipse Collections ofrece algunas clases primitivas de pares muy eficientes que evitarán todo el auto-boxing ineficaz y el auto-unboxing.

Por ejemplo, puede usar PrimitiveTuples.pair(int, int) para crear un IntIntPair , o PrimitiveTuples.pair(float, long) para crear un FloatLongPair .


De otra manera

Si ninguna de las soluciones anteriores flota en su bote, simplemente copie y pegue el siguiente código (que, a diferencia de la clase enumerada en la respuesta aceptada, protege contra NullPointerExceptions):

 import java.util.Objects; public class Pair { public final K key; public final V value; public Pair(K key, V value) { this.key = key; this.value = value; } public boolean equals(Object o) { return o instanceof Pair && Objects.equals(key, ((Pair< ?,?>)o).key) && Objects.equals(value, ((Pair< ?,?>)o).value); } public int hashCode() { return 31 * Objects.hashCode(key) + Objects.hashCode(value); } public String toString() { return key + "=" + value; } } 

Estas clases integradas también son una opción:

  • AbstractMap.SimpleEntry
  • AbstractMap.SimpleImmutableEntry

Apache common lang3 tiene clase Pair y algunas otras librerías mencionadas en este hilo ¿Cuál es el equivalente del par C ++ en Java?

Ejemplo que coincide con el requisito de su pregunta original:

 List> myPairs = new ArrayList>(); myPairs.add(Pair.of("val1", 11)); myPairs.add(Pair.of("val2", 17)); //... for(Pair pair : myPairs) { //following two lines are equivalent... whichever is easier for you... System.out.println(pair.getLeft() + ": " + pair.getRight()); System.out.println(pair.getKey() + ": " + pair.getValue()); } 

Para cualquier persona que desarrolle para Android, puede usar android.util.Pair . 🙂

¿Qué pasa con la clase de Pair “Apache Commons Lang 3” y las subclases relativas?

  import org.apache.commons.lang3.tuple.ImmutablePair; import org.apache.commons.lang3.tuple.Pair; ... @SuppressWarnings("unchecked") Pair[] arr = new ImmutablePair[]{ ImmutablePair.of("A", 1), ImmutablePair.of("B", 2)}; // both access the 'left' part String key = arr[0].getKey(); String left = arr[0].getLeft(); // both access the 'right' part Integer value = arr[0].getValue(); Integer right = arr[0].getRight(); 

ImmutablePair es una subclase específica que no permite modificar los valores del par, pero existen otras implementaciones con diferente semántica. Estas son las coordenadas de Maven, si las necesita.

   org.apache.commons commons-lang3 3.4  

Iba a preguntar si no querrías simplemente usar una List> ? pero luego, por supuesto, el JDK no tiene una clase Pair <>. Pero Google rápidamente encontró uno tanto en Wikipedia como en forums.sun.com . Aclamaciones

La solución preferida tal como la ha descrito es una Lista de pares (es decir, Lista).

Para lograr esto, crearía una clase Pair para usar en su colección. Esta es una clase de utilidad útil para agregar a su base de código.

La clase más cercana en Sun JDK que proporciona una funcionalidad similar a una clase Pair típica es AbstractMap.SimpleEntry. Podrías usar esta clase en lugar de crear tu propia clase Pair, aunque tendrías que vivir con algunas restricciones incómodas y creo que la mayoría de las personas fruncirían el ceño al ver que esto no es realmente el rol previsto de SimpleEntry. Por ejemplo, SimpleEntry no tiene el método “setKey ()” y no tiene un constructor predeterminado, por lo que puede resultarle demasiado restrictivo.

Tenga en cuenta que las Colecciones están diseñadas para contener elementos de un solo tipo. Las interfaces de utilidad relacionadas, como Map, no son en realidad Collections (es decir, Map no implementa la interfaz de Collection). Un par no implementaría la interfaz de colección, pero obviamente es una clase útil para construir estructuras de datos más grandes.

Expandir el otro responde que un par inmutable genérico debe tener un método estático para evitar saturar el código con la llamada al constructor:

 class Pair { final L left; final R right; public Pair(L left, R right) { this.left = left; this.right = right; } static  Pair of(L left, R right){ return new Pair(left, right); } } 

si nombra el método estático “de” o “pairOf”, el código se convierte en fluido ya que puede escribir:

  list.add(Pair.of(x,y)); // my preference list.add(pairOf(x,y)); // use with import static xyPair.pairOf 

Es una verdadera lástima que las bibliotecas centrales de Java sean tan dispersas en cosas tales que usted tenga que usar commons-lang u otras terceras partes para hacer tales cosas básicas. otra razón más para actualizar a scala …

Esto se basa en el código de JavaHelp4u.

Menos detallado y muestra cómo hacer en una línea y cómo recorrer las cosas.

 //======> Imports import java.util.AbstractMap.SimpleEntry; import java.util.ArrayList; import java.util.List; import java.util.Map.Entry; //======> Single Entry SimpleEntry myEntry = new SimpleEntry("ID", "Text"); System.out.println("key: " + myEntry.getKey() + " value:" + myEntry.getValue()); System.out.println(); //======> List of Entries List> pairList = new ArrayList<>(); //-- Specify manually Entry firstButton = new SimpleEntry("Red ", "Way out"); pairList.add(firstButton); //-- one liner: pairList.add(new SimpleEntry("Gray", "Alternate route")); //Ananomous add. //-- Iterate over Entry array: for (Entry entr : pairList) { System.out.println("Button: " + entr.getKey() + " Label: " + entr.getValue()); } 

Apache Crunch también tiene una clase Pair : http://crunch.apache.org/apidocs/0.5.0/org/apache/crunch/Pair.html

solo crea una clase como

 class tuples { int x; int y; } 

luego crea una lista de estos objetos de tuplas

 List list = new ArrayList(); 

por lo que también puede implementar otras estructuras de datos nuevas de la misma manera.

Quiero decir, aunque no hay una clase Pair en Java, hay algo bastante similar: Map.Entry

Map.Entry Documentation

Esto es (simplificando un poco) lo que HashMap , o en realidad cualquier Map almacena.

Puede crear una instancia de Map almacenar sus valores en ella y obtener la entrada establecida. Usted terminará con un Set

>

que efectivamente es lo que quiere.

Asi que:

 public static void main(String []args) { HashMap values = new HashMap(); values.put("A", 235);//your custom data, the types may be different //more data insertions.... Set> list = values.entrySet();//your list //do as you may with it } 

¿Qué pasa con com.sun.tools.javac.util.Pair?

Lo primero que tengo en mente cuando hablo de pares clave / valor es la clase de propiedades donde puede guardar y cargar elementos a una secuencia / archivo.