ATUALIZAÇÃO: Esta resposta é uma resposta à pergunta original, o Java SE 8 possui pares ou tuplas? (E implicitamente, se não, por que não?) O OP atualizou a pergunta com um exemplo mais completo, mas parece que pode ser resolvido sem o uso de qualquer tipo de estrutura de pares. [Nota do OP: aqui está a outra resposta correta .]
A resposta curta é não. Você precisa rolar por conta própria ou trazer uma das várias bibliotecas que a implementa.
Ter uma Pair
aula no Java SE foi proposto e rejeitado pelo menos uma vez. Veja este tópico de discussão em uma das listas de discussão do OpenJDK. As compensações não são óbvias. Por um lado, existem muitas implementações de pares em outras bibliotecas e no código do aplicativo. Isso demonstra uma necessidade e a inclusão dessa classe no Java SE aumentará a reutilização e o compartilhamento. Por outro lado, ter uma classe Pair aumenta a tentação de criar estruturas de dados complicadas a partir de pares e coleções sem criar os tipos e abstrações necessários. (Essa é uma paráfrase da mensagem de Kevin Bourillion desse tópico.)
Eu recomendo que todos leiam todo esse tópico de email. É notavelmente perspicaz e não tem flamage. É bastante convincente. Quando começou, pensei: "Sim, deveria haver uma classe Pair no Java SE", mas quando o segmento chegou ao fim, eu havia mudado de idéia.
Observe, no entanto, que o JavaFX possui a classe javafx.util.Pair . As APIs do JavaFX evoluíram separadamente das APIs do Java SE.
Como se pode ver na questão vinculada Qual é o equivalente do par C ++ em Java? existe um espaço de design bastante grande em torno do que aparentemente é uma API tão simples. Os objetos devem ser imutáveis? Eles devem ser serializáveis? Eles deveriam ser comparáveis? A aula deve ser final ou não? Os dois elementos devem ser ordenados? Deve ser uma interface ou uma classe? Por que parar em pares? Por que não triplas, quads ou N-tuplas?
E, claro, há a inevitável nomeação de bikeshed para os elementos:
- (a, b)
- (primeiro segundo)
- (esquerda direita)
- (carro, cdr)
- (foo, bar)
- etc.
Um grande problema que quase não foi mencionado é o relacionamento dos pares com os primitivos. Se você possui um (int x, int y)
dado que representa um ponto no espaço 2D, representá-lo como Pair<Integer, Integer>
consome três objetos em vez de duas palavras de 32 bits. Além disso, esses objetos devem residir no heap e incorrem em sobrecarga do GC.
Parece claro que, como Streams, seria essencial haver especializações primitivas para Pares. Queremos ver:
Pair
ObjIntPair
ObjLongPair
ObjDoublePair
IntObjPair
IntIntPair
IntLongPair
IntDoublePair
LongObjPair
LongIntPair
LongLongPair
LongDoublePair
DoubleObjPair
DoubleIntPair
DoubleLongPair
DoubleDoublePair
Mesmo um IntIntPair
ainda exigiria um objeto na pilha.
Naturalmente, elas lembram a proliferação de interfaces funcionais no java.util.function
pacote no Java SE 8. Se você não quer uma API inchada, quais você deixaria de fora? Você também pode argumentar que isso não é suficiente e que especializações para, por exemplo, Boolean
devem ser adicionadas também.
Meu sentimento é que se o Java tivesse adicionado uma classe Pair há muito tempo, seria simples, ou até simplista, e não teria satisfeito muitos dos casos de uso que estamos imaginando agora. Considere que se o Pair tivesse sido adicionado no período de tempo do JDK 1.0, provavelmente teria sido mutável! (Veja java.util.Date.) As pessoas ficariam felizes com isso? Meu palpite é que, se houvesse uma classe Pair em Java, seria meio que não muito útil e todo mundo continuaria se adaptando para satisfazer suas necessidades, haveria várias implementações Pair e Tuple em bibliotecas externas, e as pessoas ainda estariam discutindo / discutindo sobre como corrigir a classe Pair do Java. Em outras palavras, meio que no mesmo lugar em que estamos hoje.
Enquanto isso, algum trabalho está em andamento para resolver a questão fundamental, que é o melhor suporte na JVM (e eventualmente na linguagem Java) para tipos de valor . Consulte este documento Estado dos valores . Este é um trabalho preliminar e especulativo, e cobre apenas questões da perspectiva da JVM, mas já tem uma boa quantidade de pensamento por trás. Obviamente, não há garantias de que isso chegue ao Java 9, ou que entre em qualquer lugar, mas mostra a direção atual de se pensar neste tópico.
AbstractMap.SimpleImmutableEntry<K,V>
há anos ... Mas de qualquer maneira, em vez de mapeamentoi
para(i, value[i])
apenas para filtrar porvalue[i]
e mapeamento de volta parai
: porque não basta filtrovalue[i]
em primeiro lugar, sem o mapeamento?