Da documentação do Java 1.6 Collection Framework :
Coleções que não oferecem suporte a nenhuma operação de modificação (como
add
,remove
eclear
) são chamadas de não modificáveis . [...] Coleções que garantem adicionalmente que nenhuma mudança no objeto Coleção será visível são chamadas de imutáveis .
O segundo critério me confunde um pouco. Dado que a primeira coleção não pode ser modificada, e supondo que a referência da coleção original tenha sido descartada, quais são as mudanças mencionadas na segunda linha? Está se referindo às mudanças nos elementos mantidos na coleção, ou seja, o estado dos elementos?
Segunda questão:
para que uma coleção seja imutável, como se faz para fornecer as garantias adicionais especificadas? Se o estado de um elemento na coleção for atualizado por um encadeamento, é suficiente para a imutabilidade que essas atualizações no estado não sejam visíveis no encadeamento que contém a coleção imutável?
Para que uma coleção seja imutável, como fornecer as garantias adicionais especificadas?
fonte
newCol = oldCol.add("element")
produzirá uma nova coleção que é uma cópia da antiga com mais 1 elemento, e todas as referências aoldCol
ainda apontarão para a mesma coleção antiga inalterada.Respostas:
Coleções não modificáveis são geralmente visualizações somente leitura (invólucros) de outras coleções. Você não pode adicionar, remover ou apagá-los, mas a coleção subjacente pode mudar.
Coleções imutáveis não podem ser alteradas de forma alguma - elas não envolvem outra coleção - elas têm seus próprios elementos.
Aqui está uma citação de goiaba
ImmutableList
Então, basicamente, para obter uma coleção imutável de uma mutável, você precisa copiar seus elementos para a nova coleção e proibir todas as operações.
fonte
unmodifiableList
, o código que recebe apenas uma referência a essa lista não será capaz de modificá-la, mas qualquer código que tivesse uma referência à lista original e pudesse modificá-la antes que o wrapper fosse criado ainda será ser capaz de fazer isso depois. Se o código que criou a lista original sabe o que aconteceu com cada referência que já existiu para ele e sabe que nenhuma delas cairá nas mãos de um código que possa modificar a lista, então ele pode saber que a lista nunca será modificado. Se a referência foi recebida de um código externo, no entanto ...unmodifiableList
, nem qualquer código que o use, saber se ou como a coleção agrupada pode ser alterada.A diferença é que você não pode ter uma referência a uma coleção imutável que permite mudanças. Coleções não modificáveis são inalteráveis por meio dessa referência , mas algum outro objeto pode apontar para os mesmos dados por meio dos quais pode ser alterado.
por exemplo
fonte
c1
é mutável (ou seja, nem não modificável nem imutável ).c2
é unmodifiable : ela não pode ser alterado em si, mas se mais tarde eu mudarc1
, em seguida, que a mudança será visível noc2
.Isso ocorre porque
c2
é simplesmente um invólucroc1
e não realmente uma cópia independente. Guava fornece aImmutableList
interface e algumas implementações. Eles funcionam criando uma cópia da entrada (a menos que a entrada seja uma coleção imutável por conta própria).Com relação à sua segunda pergunta:
A mutabilidade / imutabilidade de uma coleção não depende da mutabilidade / imutabilidade dos objetos nela contidos. Modificar um objeto contido em uma coleção não conta como uma "modificação da coleção" para esta descrição. Claro, se você precisa de uma coleção imutável, normalmente também quer que ela contenha objetos imutáveis.
fonte
c1
não escapa" não é uma consideração diferenciada em qualquer lugar da especificação. Na minha opinião, se você pode usar a coleção de uma forma que a torne não imutável, você deve sempre considerá-la não imutável.Collection.unmodifiableList()
não pode garantir isso, porque não pode garantir que seu argumento não escape. A goiabaImmutableList.of
sempre produz um imutávelList
, mesmo que você deixe escapar seus argumentos.Agora java 9 tem métodos de fábrica para Immutable List, Set, Map e Map.Entry.
No Java SE 8 e em versões anteriores, podemos usar os métodos utilitários da classe Collections, como unmodifiableXXX, para criar objetos Immutable Collection.
No entanto, esses métodos Collections.unmodifiableXXX são uma abordagem muito tediosa e detalhada. Para superar essas deficiências, o Oracle Corp adicionou alguns métodos utilitários às interfaces List, Set e Map.
Agora em java 9: - interfaces List e Set têm métodos “of ()” para criar uma Lista Imutável vazia ou não vazia ou objetos Set conforme mostrado abaixo:
Exemplo de lista vazia
Exemplo de lista não vazia
fonte
List.copyOf
eSet.copyOf
foram adicionados que permitem criar uma cópia não modificável de uma lista / conjunto, ou retornar a coleção dada se ela já estiver inalterada, veja JDK-8191517Acredito que o ponto aqui é que mesmo que uma coleção seja Imodificável, isso não garante que ela não possa ser alterada. Considere, por exemplo, uma coleção que despeja elementos se eles forem muito antigos. Imodificável significa apenas que o objeto que contém a referência não pode mudá-la, não que ele não pode mudar. Um verdadeiro exemplo disso é
Collections.unmodifiableList
método. Ele retorna uma visão não modificável de uma lista. A referência de Lista que foi passada para este método ainda é modificável e, portanto, a lista pode ser modificada por qualquer detentor da referência que foi passada. Isso pode resultar em ConcurrentModificationExceptions e outras coisas ruins.Imutável, significa que de forma alguma a coleção pode ser alterada.
Segunda questão: Uma coleção Imutável não significa que os objetos contidos na coleção não mudarão, apenas que a coleção não mudará no número e na composição dos objetos que contém. Em outras palavras, a lista de referências da coleção não mudará. Isso não significa que as partes internas do objeto referenciado não possam mudar.
fonte
unmodifiableList
modificada. Se você quiser fazer isso, useImmutableList
.Pure4J apóia o que você , de duas maneiras.
Primeiro, ele fornece uma
@ImmutableValue
anotação, para que você possa anotar uma classe para dizer que ela é imutável. Existe um plugin maven para permitir que você verifique se o seu código é realmente imutável (uso definal
etc.).Em segundo lugar, ele fornece as coleções persistentes do Clojure (com genéricos adicionados) e garante que os elementos adicionados às coleções sejam imutáveis. O desempenho deles é aparentemente muito bom. As coleções são imutáveis, mas implementam interfaces de coleções java (e genéricos) para inspeção. Mutation retorna novas coleções.
Isenção de responsabilidade: eu sou o desenvolvedor deste
fonte