views:

694

answers:

6

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.

+13  A: 
    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.

Bozho
+7  A: 

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.

Mr. Shiny and New
A: 

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 :)

Andreas_D
A: 

While you were all right, Mr. Shiny and New nailed it completely; I was using Collestions.emptyList() to create an empty list, while not realizing it's an unmodifiable list too.

If I may build up on my original question, and ask another one:

Why was this not working:

tasksList = workflowService.getPooledTasks(currentUserName); //unmodifiable list
List<WorkflowTask> tasksListModifiable = Collections.emptyList(); //unmodifiable list

tasksListModifiable.addAll(tasksList);
Lista
Naming the variable "Modifiable" isn't enough to make it modifiable. :) Is this really the code you meant to post?
Kevin Bourrillion
You're missing my point; why wasn't I able to add elements to the tasksListModifiable list? Even though that's an unmodifiable list, I should still be able to add elements to it.
Lista
@Lista - an unmodifiable list is, well, unmodifiable... that means that you cannot add any items to it, since that would be mofifying it.
Paul Wagland
@Lista - just to clarify, the <a href="http://java.sun.com/j2se/1.5.0/docs/api/java/util/Collections.html#emptyList()">javadoc</a> explicitly states that the returned list is immutable. immutable == unmodifiable.
Paul Wagland
@Lista, does it make sense now?
Kevin Bourrillion
+6  A: 

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

List<Foo> sorted = Ordering.natural().sortedCopy(unmodifiableList);
Kevin Bourrillion
Looks like advertising...I like it.
Willi
+1  A: 

Since I'm new here and cannot leave a comment on the answer above...I will write a regular answer to 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.

Kevin Brock
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.
True Soft
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.
Kevin Brock
@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.
Mr. Shiny and New