There is a list of
List<Person> persons = generatePersons();
An unmodifiableList is created with it.
List<Person> unmodifiableList = Collections.unmodifiableList(persons);
I understand that
unmodifiableList doesn't support add/remove/set operations. At the same time it is not immutable since it has a reference to an existing modifiable list
persons and whenever changes are made to the
persons list, the changes are reflected in
An immutable list is created this way.
List<Person> immutableList = Collections.unmodifiableList(new ArrayList<>(persons));
This creates an immutable list since a conversion constructor is being used. No add/remove/set ops can be performed on
immutableList nor any change in the original list
persons would reflect in
immutableList. Let's make an assumption that
Person objects are immutable too.
Now, I want to create these two lists using streams.
The first one, I have created using:
List<Person> unmodifiablePersons = persons.stream() .collect(Collectors.collectingAndThen(Collectors.toList(), Collections::unmodifiableList));
I am lost at creating equivalent of immutableList through streams.
How can I do that?
I added a new
Person object to the original list
persons and printed the size of
persons list and
unmodifiablePersons. Both give me the same size. So, changes are being reflected to
unmodifiablePersonsand hence it is not immutable yet. Am I missing something here?
Silly. Should have gone through the docs.
unmodifiablePersons is indeed an immutable list. Also, the new
Person object was added before the
unmodifiablePersons was created and hence the above observation. Super silly.
Well in your first case someone has access to
List<Person> unmodifiableList and can edit it, but when you
collect no one has access to that
List generated by
Collectors.toList - so you are good.
What you are probably missing is that
Collectors::toList will create a new List - which should really be obvious; and you wrap it into an unmodifiable one, thus the result of that is truly unmodifiable.
Also in java-10 there is special collector for that:
List<Integer> result = Arrays.asList(1, 2, 3, 4) .stream() .collect(Collectors.toUnmodifiableList());
This collector uses
List::of internally - immutable collections added in java-9, thus for example they don't support nulls.