Me gusta cómo Java tiene un mapa donde puede definir los tipos de cada entrada en el mapa, por ejemplo <String, Integer>
.
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 String e Integer anterior), que se define en el momento de la declaración.
La colección mantendrá su orden dado y no tratará uno de los valores como una clave única (como en un mapa).
Esencialmente quiero poder definir un ARRAY de tipo <String,Integer>
o cualquier otro tipo de 2.
Me doy cuenta de que puedo hacer una clase con nada más que las 2 variables, pero eso parece demasiado 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 hacerlos matrices de OBJETO, 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 ir a la ruta de clase? ¡Gracias!
Pair
, y la gente de Google ha ido tan lejos como para crear una alternativa mucho mejor: Auto / Value . Le permite crear fácilmente clases de tipo de valor bien tipadas , con una semántica igual / hashCode adecuada. ¡Nunca más necesitarás unPair
tipo!Respuestas:
La clase Pair es uno de esos ejemplos genéricos "dame" que es bastante fácil de escribir por su cuenta. Por ejemplo, fuera de mi cabeza:
Y sí, esto existe en múltiples lugares en la red, con diversos grados de integridad y funcionalidad. (Mi ejemplo anterior está destinado a ser inmutable).
fuente
long l = left.hashCode() * 2654435761L;
return (int)l + (int)(l >>> 32) + right.hashCode();
AbstractMap.SimpleEntry
Fácil estás buscando esto:
¿Cómo puedes llenarlo?
Esto se simplifica a:
Y, con la ayuda de un
createEntry
método, puede reducir aún más la verbosidad a:Como
ArrayList
no es definitivo, se puede subclasificar para exponer unof
método (y elcreateEntry
método mencionado anteriormente ), lo que resulta en el sintácticamente conciso:fuente
SimpleEntry
tiene unsetValue
método de omisión de clase de hermano para ser inmutable. De ahí el nombreSimpleImmutableEntry
.Entry
está destinado a ser un par clave-valor, y está bien para eso. Pero tiene debilidades como una verdadera tupla. Por ejemplo, lahashcode
implementación enSimpleEntry
solo xors los códigos de los elementos, por lo tanto,<a,b>
tiene el mismo valor<b,a>
. Las implementaciones de tuplas a menudo se clasifican lexicográficamente, peroSimpleEntry
no se implementanComparable
. Así que ten cuidado allá afuera ...Java 9+
En Java 9, simplemente puede escribir:
Map.entry(key, value)
para crear un par inmutable.Nota: este método no permite que las claves o valores sean nulos. Si desea permitir valores nulos, por ejemplo, que te gustaría cambiar esto a:
Map.entry(key, Optional.ofNullable(value))
.Java 8+
En Java 8, puede usar el propósito más general
javafx.util.Pair
para crear un par inmutable y serializable. Esta clase no permite llaves nulos y valores nulos. (En Java 9, esta clase está incluida en eljavafx.base
módulo).EDITAR: a partir de Java 11, JavaFX se ha desacoplado del JDK, por lo que necesitará el artefacto maven adicional org.openjfx: javafx-base.Java 6+
En Java 6 y versiones posteriores, puede usar el más detallado
AbstractMap.SimpleImmutableEntry
para un par inmutable oAbstractMap.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 la ayudaPair.of(key, value)
para crear un par inmutable, comparable y serializable.Colecciones Eclipse
Si usa pares que contienen primitivas, Eclipse Collections proporciona algunas clases de pares primitivos muy eficientes que evitarán todo el ineficiente auto-boxing y auto-unboxing.
Por ejemplo, podría usar
PrimitiveTuples.pair(int, int)
para crear unIntIntPair
, oPrimitiveTuples.pair(float, long)
para crear unFloatLongPair
.Proyecto lombok
Con Project Lombok , puede crear una clase de par inmutable simplemente escribiendo:
Lombok llenará en el constructor, captadores,
equals()
,hashCode()
, ytoString()
métodos de forma automática en el código de bytes generada. Si quieres un método de fábrica estática en lugar de un constructor, por ejemplo, unaPair.of(k, v)
, basta con cambiar la anotación a:@Value(staticConstructor = "of")
.De otra manera
Si ninguna de las soluciones anteriores flota en su bote, simplemente puede copiar y pegar el siguiente código (que, a diferencia de la clase que figura en la respuesta aceptada, protege contra NullPointerExceptions):
fuente
Pair
interfaz para objetos, que se puede instanciar llamandoTuples.pair(object1, object2)
. eclipse.org/collections/javadoc/9.2.0/org/eclipse/collections/…List<Pair<Integer, String> listOfTuple
. ¿Cómo lo usolistOfTuple.add()
? Si lo hagolistOfTuple.add(Pair<someInteger, someString>);
, esto no funcionará. Gracias por adelantado.Map.Entry
Estas clases incorporadas también son una opción. Ambos implementan la
Map.Entry
interfaz.AbstractMap.SimpleEntry
AbstractMap.SimpleImmutableEntry
fuente
Apache common lang3 tiene la clase Pair y algunas otras bibliotecas mencionadas en este hilo ¿Cuál es el equivalente del par C ++ <L, R> en Java?
Ejemplo que coincide con el requisito de su pregunta original:
fuente
Para cualquiera que desarrolle para Android, puede usar android.util.Pair . :)
fuente
¿Qué pasa con la
Pair
clase "Apache Commons Lang 3" y las subclases relativas?ImmutablePair
es una subclase específica que no permite modificar los valores en el par, pero hay otras implementaciones con diferentes semánticas. Estas son las coordenadas Maven, si las necesita.fuente
Podría escribir una clase genérica Par <A, B> y utilizarla en una matriz o lista. Sí, debe escribir una clase, pero puede reutilizar la misma clase para todos los tipos, por lo que solo tiene que hacerlo una vez.
fuente
Al expandir las otras respuestas, un par inmutable genérico debe tener un método estático para evitar saturar su código con la llamada al constructor:
si nombra el método estático "of" o "pairOf", el código se vuelve fluido ya que puede escribir:
Es una verdadera lástima que las bibliotecas centrales de Java sean tan escasas en tales cosas que tienes que usar commons-lang u otros terceros para hacer cosas tan básicas. otra razón más para actualizar a scala ...
fuente
Iba a preguntar si no querrías simplemente usar un
List<Pair<T, U>>
? pero luego, por supuesto, el JDK no tiene una clase Pair <>. Pero un rápido Google encontró uno en Wikipedia y en foros.sun.com . Saludfuente
La solución preferida 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 de par 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 la gente desaprobaría esto porque no es realmente el papel previsto de SimpleEntry. Por ejemplo, SimpleEntry no tiene el método "setKey ()" y no tiene un constructor predeterminado, por lo que puede ser demasiado limitante.
Tenga en cuenta que las Colecciones están diseñadas para contener elementos de un solo tipo. Las interfaces de utilidad relacionadas, como Map, en realidad no son Colecciones (es decir, Map no implementa la interfaz de Colección) Un Par tampoco implementaría la interfaz de Colección, pero obviamente es una clase útil en la construcción de estructuras de datos más grandes.
fuente
Esto se basa en el código de JavaHelp4u.
Menos detallado y muestra cómo hacerlo en una línea y cómo recorrer las cosas.
fuente
Apache Crunch también tiene una
Pair
clase: http://crunch.apache.org/apidocs/0.5.0/org/apache/crunch/Pair.htmlfuente
solo crea una clase como
luego crea una lista de estos objetos de tuplas
para que también pueda implementar otras nuevas estructuras de datos de la misma manera.
fuente
Quiero decir, aunque no hay
Pair
clase en Java, hay algo bastante similar:Map.Entry
Map.Entry Documentation
Esto es (simplificando bastante) qué
HashMap
, o en realidad cualquierMap
tienda.Puede crear una instancia de
Map
almacenar sus valores en ella y obtener el conjunto de entradas. Terminarás con unSet<Map.Entry<K,V>>
que efectivamente es lo que quieres.Entonces:
fuente
Spring tiene un
Pair<S,T>
tipo en el paquete Data Utilsorg.springframework.data.util
fuente
¿Qué pasa con com.sun.tools.javac.util.Pair?
fuente
Lo primero que tengo en mente cuando hablo de pares clave / valor es la clase de propiedades donde puede guardar y cargar elementos en una secuencia / archivo.
fuente
En el proyecto Reactor (io.projectreactor: reactor-core) hay soporte avanzado para n-Tuples:
Allí puede obtener
t.getT1(), t.getT2(), ...
especialmente con Stream o Flux, incluso puede asignar los elementos de tupla:fuente