33

How would one do this?

I have tried creating a new, empty list, then copying unmodifiable list's elements to it, but I'm getting unsupported operation error.

Any help is appreciated.

1
  • 3
    Can you show the code you're using to copy the list? Commented Nov 25, 2009 at 15:09

6 Answers 6

51
    List unmodifiableList = Collections.unmodifiableList(list);

    List newList = new ArrayList(unmodifiableList);

    Collections.sort(newList);

The constructor of ArrayList takes an existing list, reads its elements (without modifying them!), and adds them to the new List.

Sign up to request clarification or add additional context in comments.

Comments

45

FWIW, with google-collections it's a one-liner:

List<Foo> sorted = Ordering.natural().sortedCopy(unmodifiableList);

Comments

31

In Java 8, you can use the streams API. For instance:

List<?> sortedList = unsortedList.stream().sorted().collect(Collectors.toList());

Since Java 16, a Stream.toList() function was added, so the above can be shortened to:

List<?> sortedList = unsortedList.stream().sorted().toList();

3 Comments

The other great thing about this approach is that you can pass a Comparator to the sorted method to implement a custom sort order.
This does not work in case of unmodifiable list as the question is.
@ShaileshVikramSingh it should work for unmodifiable lists, what makes you think it does not?
24

Are you creating an empty list using Collections.emptyList()? If so, that is an unmodifiable list too and that may be the source of your problem.

Create a new list using the constructor for your List implementation, such as new ArrayList(). You can pass the original list into the constructor or else use the addAll() method.

Comments

0

It should work as described. Elements in an unmodifiable List are not unmodifiable themselves. Of course you can't sort an unmodifiable List, because it has to be rewritten with add and delete operations, and those are not allowed.

Guess the error is somewhere else, best would be to show your code :)

Comments

0

I will answer your second question:

You cannot add to your 'taskListModifiable' list because that is an 'unmodifiable' list, which in Java means that it is immutable. An unmodifiable/immutable list or collection of any kind cannot be directly changed in any way - you cannot add elements to it, remove elements from it, or change references to existing elements.

Note that existing elements in the list/collection may be changed if they are themselves mutable, but references to them from the list cannot be changed. That is, until the list goes completely out of scope and is garbage collected, the unmodifiable list will always contain those same references.

Now, in your case, Collections.emptyList() returns an unmodifiable EMPTY list. This is actually always the same instance since it is immutable and always empty. You cannot add to it because of the rule that an immutable list cannot be expanded (added to). Since it is empty there is also nothing in it that can be changed.

I should add to make it even more clear that Collection.emptyList() does not create an empty list. It just returns a reference to a singleton list instance.

3 Comments

unmodifiable IS NOT immutable in Java!! If you create an unmodifiable list after list1, and then you add/remove objects to list1, then the unmodifiable list will reflect the changes.
That is true for any language where the unmodifiable collection just wraps the other collection (e.g. does not make a safe copy), not just Java. You are talking about retaining a reference to the wrapped object and changing that. However, I was making a comment (which I couldn't do) to another answer where they were asking why they couldn't change the specific taskListModifiable where it was created with this: <code>taskListModifiable = Collections.emptyList()</code>. In fact, in all cases, this is immutable because the emptyList() returns an immutable, Singleton, empty list.
@True Soft: yes, you are right, the backing list inside some "unmodifiable" lists is actually modifiable. It's true that it's not strictly immutable and that you cannot necessarily treat it as such. However, in practice you often can, if you create the list, then make it unmodifiable, then throw away the initial pointer to the list.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.