Eu gosto de como o Java tem um mapa onde você pode definir os tipos de cada entrada no mapa, por exemplo <String, Integer>
.
O que estou procurando é um tipo de coleção em que cada elemento da coleção é um par de valores. Cada valor no par pode ter seu próprio tipo (como o exemplo String e Inteiro acima), que é definido no momento da declaração.
A coleção manterá sua ordem determinada e não tratará um dos valores como uma chave exclusiva (como em um mapa).
Essencialmente, eu quero poder definir uma ARRAY do tipo <String,Integer>
ou quaisquer outros 2 tipos.
Percebo que posso fazer uma aula com nada além das 2 variáveis, mas isso parece excessivamente detalhado.
Também percebo que eu poderia usar uma matriz 2D, mas, devido aos diferentes tipos que preciso usar, precisaria transformá-los em matrizes de OBJECT e, em seguida, precisaria converter o tempo todo.
Eu só preciso armazenar pares na coleção, então só preciso de dois valores por entrada. Existe algo assim sem seguir a rota da classe? Obrigado!
Pair
, e o pessoal do Google chegou ao ponto de criar uma alternativa muito melhor - Auto / Valor . Permite criar facilmente classes de tipo de valor bem tipadas , com semântica igual a / hashCode. Você nunca precisará de umPair
tipo novamente!Respostas:
A classe Pair é um daqueles exemplos genéricos "gimme" que são fáceis de escrever por conta própria. Por exemplo, em cima da minha cabeça:
E sim, isso existe em vários locais da Internet, com diferentes graus de completude e recursos. (Meu exemplo acima pretende ser imutável.)
fonte
long l = left.hashCode() * 2654435761L;
return (int)l + (int)(l >>> 32) + right.hashCode();
AbstractMap.SimpleEntry
Fácil você está procurando isso:
Como você pode preenchê-lo?
Isso simplifica para:
E, com a ajuda de um
createEntry
método, pode reduzir ainda mais a verbosidade para:Como
ArrayList
não é final, pode ser subclassificado para expor umof
método (e ocreateEntry
método mencionado acima ), resultando na síntese sintática:fonte
SimpleEntry
tem uma classe de irmãos que omite osetValue
método como imutável. Assim o nomeSimpleImmutableEntry
.Entry
deve ser um par de valor-chave, e é bom para isso. Mas tem pontos fracos como uma tupla verdadeira. Por exemplo, ahashcode
implementaçãoSimpleEntry
apenas comporta os códigos dos elementos, portanto faz o<a,b>
hash com o mesmo valor que<b,a>
. As implementações de tuplas geralmente são classificadas lexicograficamente, masSimpleEntry
não são implementadasComparable
. Portanto, tenha cuidado lá fora ...Java 9 ou superior
No Java 9, você pode simplesmente escrever:
Map.entry(key, value)
para criar um par imutável.Nota: este método não permite que chaves ou valores sejam nulos. Se você quiser permitir valores nulos, por exemplo, que você gostaria de mudar isso para:
Map.entry(key, Optional.ofNullable(value))
.Java 8+
No Java 8, você pode usar o propósito mais geral
javafx.util.Pair
para criar um par serializável e imutável. Esta classe não permitir chaves nulos e valores nulos. (No Java 9, essa classe está incluída nojavafx.base
módulo). EDIT: A partir do Java 11, o JavaFX foi dissociado do JDK, portanto, você precisa do artefato maven adicional org.openjfx: javafx-base.Java 6+
No Java 6 e superior, você pode usar o mais detalhado
AbstractMap.SimpleImmutableEntry
para um par imutável ouAbstractMap.SimpleEntry
para um par cujo valor pode ser alterado. Essas classes também permitem chaves e valores nulos e são serializáveis.Android
Se você está escrevendo para Android, use
Pair.create(key, value)
para criar um par imutável.Apache Commons
Apache Commons Lang
fornece o útilPair.of(key, value)
para criar um par imutável, comparável e serializável.Coleções Eclipse
Se você estiver usando pares que contêm primitivas, o Eclipse Collections fornecerá algumas classes de pares primitivos muito eficientes que evitarão todo o ineficiente auto-boxe e auto-unboxing.
Por exemplo, você pode usar
PrimitiveTuples.pair(int, int)
para criar umIntIntPair
ouPrimitiveTuples.pair(float, long)
para criar umFloatLongPair
.Projeto Lombok
Usando o Projeto Lombok , você pode criar uma classe de pares imutável simplesmente escrevendo:
Lombok vai encher No construtor, getters,
equals()
,hashCode()
, etoString()
métodos para você automaticamente no bytecode gerado. Se você quer um método de fábrica estático em vez de um construtor, por exemplo, umPair.of(k, v)
, basta alterar a anotação para:@Value(staticConstructor = "of")
.De outra forma
Se nenhuma das soluções acima flutuar no seu barco, você pode simplesmente copiar e colar o código a seguir (que, diferentemente da classe listada na resposta aceita, protege contra NullPointerExceptions):
fonte
Pair
interface para objetos, que pode ser instanciada chamandoTuples.pair(object1, object2)
. eclipse.org/collections/javadoc/9.2.0/org/eclipse/collections/…List<Pair<Integer, String> listOfTuple
. Como eu usolistOfTuple.add()
? Se eu fizer -listOfTuple.add(Pair<someInteger, someString>);
, isso não vai funcionar. Desde já, obrigado.Map.Entry
Essas classes internas também são uma opção. Ambos implementam a
Map.Entry
interface.AbstractMap.SimpleEntry
AbstractMap.SimpleImmutableEntry
fonte
O Apache common lang3 possui a classe Pair e poucas outras bibliotecas mencionadas neste segmento Qual é o equivalente do par C ++ <L, R> em Java?
Exemplo que corresponde ao requisito da sua pergunta original:
fonte
Para quem estiver desenvolvendo para Android, você pode usar android.util.Pair . :)
fonte
E a
Pair
classe "Apache Commons Lang 3" e as subclasses relativas?ImmutablePair
é uma subclasse específica que não permite que os valores do par sejam modificados, mas existem outras implementações com semântica diferente. Essas são as coordenadas do Maven, se você precisar delas.fonte
Você pode escrever uma classe Pair <A, B> genérica e usá-la em uma matriz ou lista. Sim, você precisa escrever uma turma, mas pode reutilizar a mesma turma para todos os tipos, portanto, apenas uma vez.
fonte
Expandindo as outras respostas, um par imutável genérico deve ter um método estático para evitar sobrecarregar seu código com a chamada ao construtor:
se você nomear o método estático "de" ou "pairOf", o código se tornará fluente, pois você pode escrever:
é uma pena que as principais bibliotecas java sejam tão escassas em coisas que você precisa usar o commons-lang ou outros terceiros para fazer essas coisas básicas. mais um motivo para atualizar para o scala ...
fonte
Eu ia perguntar se você não gostaria de usar apenas um
List<Pair<T, U>>
? mas é claro que o JDK não tem uma classe Pair <>. Mas um rápido Google encontrou um na Wikipedia e no forums.sun.com . Felicidadesfonte
A solução preferida, como você descreveu, é uma lista de pares (ou seja, lista).
Para fazer isso, você criaria uma classe Pair para uso em sua coleção. Esta é uma classe de utilitário útil para adicionar à sua base de código.
A classe mais próxima no Sun JDK que fornece funcionalidade semelhante a uma classe Pair típica é AbstractMap.SimpleEntry. Você poderia usar essa classe em vez de criar sua própria classe Pair, embora tenha que conviver com algumas restrições embaraçosas e acho que a maioria das pessoas se desaprova como não é o papel pretendido do SimpleEntry. Por exemplo, o SimpleEntry não possui o método "setKey ()" e nenhum construtor padrão; portanto, você pode achar isso muito limitador.
Lembre-se de que as coleções são projetadas para conter elementos de um único tipo. As interfaces de utilidade relacionadas, como o Mapa, não são realmente Coleções (ou seja, o Mapa não implementa a interface Coleção). Um par também não implementaria a interface Collection, mas é obviamente uma classe útil na construção de estruturas de dados maiores.
fonte
Isso é baseado no código do JavaHelp4u.
Menos detalhado e mostra como fazer em uma linha e como fazer um loop sobre as coisas.
fonte
O Apache Crunch também possui uma
Pair
classe: http://crunch.apache.org/apidocs/0.5.0/org/apache/crunch/Pair.htmlfonte
basta criar uma classe como
então crie a Lista desses objetos de tuplas
para que você também possa implementar outras novas estruturas de dados da mesma maneira.
fonte
Quero dizer, mesmo que não haja
Pair
classe em Java, há algo bastante semelhante:Map.Entry
Documentação de Map.Entry
Isto é (simplificando bastante) o que
HashMap
, ou realmente qualquerMap
loja.Você pode criar uma instância de
Map
armazenar seus valores nela e obter o conjunto de entradas. Você vai acabar com umSet<Map.Entry<K,V>>
que efetivamente é o que você deseja.Assim:
fonte
Spring tem um
Pair<S,T>
tipo no pacote Data Utilsorg.springframework.data.util
fonte
E o com.sun.tools.javac.util.Pair?
fonte
A primeira coisa que penso em pares de chave / valor é a Classe de Propriedades, na qual é possível salvar e carregar itens em um fluxo / arquivo.
fonte
No projeto Reator (io.projectreactor: reator-core), há suporte avançado para n-Tuplas:
Lá você pode obter
t.getT1(), t.getT2(), ...
Especialmente com Stream ou Flux, você pode até mapear os elementos da tupla:fonte