Existe uma alternativa imutável para as matrizes primitivas em Java? Criar um array primitivo final
não impede que alguém faça algo como
final int[] array = new int[] {0, 1, 2, 3};
array[0] = 42;
Eu quero que os elementos da matriz sejam imutáveis.
int[]
enew int[]
é MUITO mais fácil digitar do queList<Integer>
enew ArrayList<Integer>
? XDRespostas:
Não com matrizes primitivas. Você precisará usar uma lista ou outra estrutura de dados:
fonte
Arrays.asList
é modificável. docs.oracle.com/javase/7/docs/api/java/util/… "Retorna uma lista de tamanho fixo apoiada pela matriz especificada. (Alterações na lista retornada" write through "to the array.)"Arrays.asList()
na verdade, parece não modificável no sentido de que você não podeadd
ouremove
itens da retornoujava.util.Arrays.ArrayList
( não deve ser confundida comjava.util.ArrayList
) - estas operações apenas não são implementadas. Talvez @mauhiz tente dizer isso? Mas é claro que você pode modificar elementos com existenteList<> aslist = Arrays.asList(...); aslist.set(index, element)
, entãojava.util.Arrays.ArrayList
certamente é não unmofiable , QED Adicionado o comentário apenas por uma questão de enfatizar a diferença entre o resultado deasList
e normalArrayList
Minha recomendação é não usar uma matriz ou uma,
unmodifiableList
mas usar o ImmutableList do Guava , que existe para esse fim.fonte
Collections.unmodifiableList
suficiente para tornar uma Lista imutável?Como outros observaram, você não pode ter matrizes imutáveis em Java.
Se você precisar absolutamente de um método que retorne uma matriz que não influencie a matriz original, será necessário cloná-la sempre:
Obviamente, isso é bastante caro (como você cria uma cópia completa toda vez que chama o getter), mas se você não pode alterar a interface (para usar um
List
por exemplo) e não pode arriscar que o cliente altere seus internos, pode ser necessário.Essa técnica é chamada de fazer uma cópia defensiva.
fonte
clone()
ouArrays.copy()
aqui?Há uma maneira de criar uma matriz imutável em Java:
Matrizes com 0 elementos (obviamente) não podem ser mutadas.
Isso pode ser útil se você estiver usando o
List.toArray
método para converter umList
em uma matriz. Como até mesmo uma matriz vazia ocupa um pouco de memória, você pode salvar essa alocação de memória criando uma matriz vazia constante e sempre passando-a para otoArray
método Esse método alocará uma nova matriz se a matriz que você passar não tiver espaço suficiente, mas se tiver (a lista está vazia), ela retornará a matriz que você passou, permitindo que você reutilize essa matriz sempre que você chamartoArray
um vazioList
.fonte
Outra resposta
fonte
A partir de Java 9 você pode usar
List.of(...)
, JavaDoc .Este método retorna um imutável
List
e é muito eficiente.fonte
Se você precisar (por motivos de desempenho ou economizar memória) nativo 'int' em vez de 'java.lang.Integer', provavelmente precisará escrever sua própria classe de wrapper. Existem várias implementações do IntArray na rede, mas nenhuma (eu achei) era imutável: Koders IntArray , Lucene IntArray . Provavelmente existem outros.
fonte
Desde o Guava 22, do pacote,
com.google.common.primitives
você pode usar três novas classes, com menor espaço de memória em comparação com oImmutableList
.Eles também têm um construtor. Exemplo:
ou, se o tamanho for conhecido em tempo de compilação:
Essa é outra maneira de obter uma visão imutável de uma matriz para primitivas Java.
fonte
Não, isso não é possível. No entanto, alguém poderia fazer algo assim:
Isso requer o uso de wrappers e é uma lista, não uma matriz, mas é o mais próximo que você vai chegar.
fonte
valueOf()
s, o autoboxing cuidará disso. TambémArrays.asList(0, 2, 3, 4)
seria muito mais conciso.valueOf()
é utilizar o cache interno de objetos Inteiros para reduzir o consumo / reciclagem de memória.int
em umInteger
porém; só tem que ter cuidado ao contrário.Em algumas situações, será mais leve usar esse método estático da biblioteca do Google Guava:
List<Integer> Ints.asList(int... backingArray)
Exemplos:
List<Integer> x1 = Ints.asList(0, 1, 2, 3)
List<Integer> x1 = Ints.asList(new int[] { 0, 1, 2, 3})
fonte
Se você deseja evitar a mutabilidade e o boxe, não há como sair da caixa. Mas você pode criar uma classe que contenha uma matriz primitiva dentro e forneça acesso somente leitura aos elementos via método (s).
fonte
O método of (E ... elements) em Java9 pode ser usado para criar uma lista imutável usando apenas uma linha:
O método acima retorna uma lista imutável que contém um número arbitrário de elementos. E adicionar qualquer número inteiro a esta lista resultaria em
java.lang.UnsupportedOperationException
exceção. Este método também aceita uma única matriz como argumento.fonte
Embora seja verdade que
Collections.unmodifiableList()
funciona, às vezes você pode ter uma biblioteca grande com métodos já definidos para retornar matrizes (por exemploString[]
). Para evitar quebrá-los, você pode realmente definir matrizes auxiliares que armazenarão os valores:Testar:
Não é perfeito, mas pelo menos você tem "matrizes pseudo-imutáveis" (da perspectiva da classe) e isso não quebra o código relacionado.
fonte
Bem ... matrizes são úteis para passar como constantes (se fossem) como parâmetros de variantes.
fonte
int[]
, o responsável pela chamada poderá assumir que pode fazer o que quiser com essa matriz sem afetar os internos da API.