Por que o Java Collections não armazena diretamente os tipos Primitivos?

As collections Java armazenam apenas Objetos, não tipos primitivos; no entanto, podemos armazenar as classs wrapper.

Por que essa restrição?

Foi uma decisão de design em Java e uma que alguns consideram um erro. Containers querem Objetos e primitivos não derivam de Object.

Este é um lugar que os designers .NET aprenderam com a JVM e implementaram tipos de valor e genéricos de tal forma que o boxe é eliminado em muitos casos. No CLR, os contêineres genéricos podem armazenar tipos de valor como parte da estrutura do contêiner subjacente.

O Java optou por adicionar suporte genérico 100% no compilador sem suporte da JVM. A JVM sendo o que é, não suporta um object “não object”. Os genéricos Java permitem que você finja que não há wrapper, mas ainda paga o preço de desempenho do boxe. Isso é importante para certas classs de programas.

O boxe é um compromisso técnico, e eu sinto que é o detalhe da implementação vazando para o idioma. Autoboxing é bom açúcar sintático, mas ainda é uma penalidade de desempenho. Se qualquer coisa, eu gostaria que o compilador me avisasse quando isso acontecesse. (Por tudo que sei, pode agora, eu escrevi esta resposta em 2010).

Uma boa explicação sobre SO sobre boxe: Por que alguns idiomas precisam de Boxing e Unboxing?

E críticas aos genéricos Java: por que alguns afirmam que a implementação de genéricos do Java é ruim?

Em defesa de Java, é fácil olhar para trás e criticar. A JVM resistiu ao teste do tempo e é um bom design em muitos aspectos.

Facilita a implementação. Como as primitivas Java não são consideradas Objetos, você precisaria criar uma class de coleta separada para cada uma dessas primitivas (nenhum código de modelo para compartilhar).

Você pode fazer isso, é claro, apenas ver o GNU Trove , Primitivas Apache Commons ou HPPC .

A menos que você tenha collections realmente grandes, a sobrecarga para os wrappers não importa o suficiente para as pessoas se importarem (e quando você tiver collections primitivas realmente grandes, talvez queira gastar o esforço para usar / construir uma estrutura de dados especializada para elas ).

É uma combinação de dois fatos:

  • Tipos primitivos de Java não são tipos de referência (por exemplo, um int não é um Object )
  • Java faz genéricos usando o tipo de eliminação de tipos de referência (por exemplo, uma List< ?> É realmente uma List em tempo de execução)

Como ambos são verdadeiros, as collections Java genéricas não podem armazenar tipos primitivos diretamente. Por conveniência, o autoboxing é introduzido para permitir que tipos primitivos sejam automaticamente encheckboxdos como tipos de referência. Não se engane sobre isso, porém, as collections ainda estão armazenando referências de objects, independentemente.

Isso poderia ter sido evitado? Possivelmente.

  • Se um int é um Object , então não há necessidade de tipos de checkbox.
  • Se os genéricos não forem feitos usando o apagamento de tipos, os primitivos poderiam ter sido usados ​​para parâmetros de tipo.

Existe o conceito de auto-boxing e auto-unboxing. Se você tentar armazenar um int em um List o compilador Java irá convertê-lo automaticamente em um Integer .

Não é realmente uma restrição é?

Considere se você deseja criar uma coleção que armazene valores primitivos. Como você escreveria uma coleção que pudesse armazenar int, ou float ou char? Muito provavelmente você vai acabar com várias collections, então você vai precisar de uma intlist e uma lista de caridade, etc.

Aproveitando a natureza orientada a object do Java quando você escreve uma class de coleção, ele pode armazenar qualquer object, de modo que você precisa apenas de uma class de coleção. Essa ideia, polymorphism, é muito poderosa e simplifica bastante o design de bibliotecas.

Acho que podemos ver progresso neste espaço no JDK possivelmente no Java 10 baseado neste JEP – http://openjdk.java.net/jeps/218 .

Se você quiser evitar primitivos de boxe nas collections hoje, existem várias alternativas de terceiros. Além das opções de terceiros mencionadas anteriormente, há também Eclipse Collections , FastUtil e Koloboke .

Uma comparação de mapas primitivos também foi publicada um tempo atrás com o título: Visão geral de HashMap grande: JDK, FastUtil, Goldman Sachs, HPPC, Koloboke, Trove . A biblioteca GS Collections (Goldman Sachs) foi migrada para a Eclipse Foundation e agora é Eclipse Collections.

A principal razão é a estratégia de design java. ++ 1) collections requerem objects para manipulação e primitivos não são derivados de object, então esta pode ser a outra razão. 2) Os tipos de dados primitivos do Java não são do tipo de referência para ex. int não é um object.

Superar:-

temos conceito de auto-boxing e auto-unboxing. por isso, se você estiver tentando armazenar um compilador de tipos de dados primitivos, o converterá automaticamente em object dessa class de dados primitiva.