20

Well, I have a class Customer (no base class).

I need to cast from LinkedList to List. Is there any clean way to do this?

Just so you know, I need to cast it to List. No other type will do. (I'm developing a test fixture using Slim and FitNesse).


EDIT: Okay, I think I need to give code examples here.

import java.util.*; public class CustomerCollection { protected LinkedList<Customer> theList; public CustomerCollection() { theList = new LinkedList<Customer>(); } public void addCustomer(Customer c){ theList.add(c); } public List<Object> getList() { return (List<? extends Object>) theList; } } 

So in accordance with Yuval A's remarks, I've finally written the code this way. But I get this error:

CustomerCollection.java:31: incompatible types found : java.util.List<capture#824 of ? extends java.lang.Object> required: java.util.List<java.lang.Object> return (List<? extends Object>)theList; ^ 1 error 

So, what's the correct way to do this cast?

1
  • you should have given code examples from the start, I'll update my answer in a second... Commented May 25, 2009 at 9:18

10 Answers 10

33

You do not need to cast. LinkedList implements List so you have no casting to do here.

Even when you want to down-cast to a List of Objects you can do it with generics like in the following code:

LinkedList<E> ll = someList; List<? extends Object> l = ll; // perfectly fine, no casting needed 

Now, after your edit I understand what you are trying to do, and it is something that is not possible, without creating a new List like so:

LinkedList<E> ll = someList; List<Object> l = new LinkedList<Object>(); for (E e : ll) { l.add((Object) e); // need to cast each object specifically } 

and I'll explain why this is not possible otherwise. Consider this:

LinkedList<String> ll = new LinkedList<String>(); List<Object> l = ll; // ERROR, but suppose this was possible l.add((Object) new Integer(5)); // now what? How is an int a String??? 

For more info, see the Sun Java generics tutorial. Hope this clarifies.

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

4 Comments

You missed my point. Consider: [code] LinkedList<E> ll = someList; List<Object> l =ll [/code]. Is this okay? I mean this.
Did what you said, but problem persists. Edited the question to add code example and the error encountered.
Is it possible for your getList() method to return List<?>?
@Andrew No. Thats the main problem.
21

Here's my horrible solution for doing casting. I know, I know, I shouldn't be releasing something like this into the wild, but it has come in handy for casting any object to any type:

public class UnsafeCastUtil { private UnsafeCastUtil(){ /* not instatiable */} /** * Warning! Using this method is a sin against the gods of programming! */ @SuppressWarnings("unchecked") public static <T> T cast(Object o){ return (T)o; } } 

Usage:

Cat c = new Cat(); Dog d = UnsafeCastUtil.cast(c); 

Now I'm going to pray to the gods of programming for my sins...

1 Comment

I am absolutely ok with this. I do it regularly. I usually do this "internally" in libraries (never exposed in the wild for arbitrary casts). Then I structure my code to make a wrong cast impossible. So when I know that I can safely cast List<E> to List<B> because the structure of my code obligates E to be a subclass of B (and I don't need to reverse the cast), then I'm good to go. Sometimes a "hack" is the right and clean thing to do.
3

I did this function for that, ugly but it works

public static <T> Collection<T> cast(Collection<? super T> collection, Class<T> clazz){ return (Collection<T>)collection; } 

2 Comments

and clazz is for what ? is not used
clazz is purely used to determine what T is, so collection can be casted to a collection of T
1
> public List<Object> getList() 

Why are you returning List<Object>? You might as well return List (without generics) since that is equivalent but would make the following code work:

LinkedList<Customer> theList = new LinkedList<Customer>(); public List getList() { return theList; } 

Casting between Lists with different generic types is tricky and seems unnecessary here.

Of course you should be returning type List<Customer> ...

Comments

1

You should return a List<?> from your method. Intuitively, getList() returns a list so that the caller can retrieve the items inside. List<?> (which is equivalent to List<? extends Object>) allows that functionality. However, you won't be able to put anything into it via the returned list, because that would not be type safe; but I don't think that is what you need anyway.

public List<?> getList() { return theList; } 

Comments

0

LinkedList implements List, so you can implement

List< String > list1 = new LinkedList< String >(); 

Or do you want to cast from LinkedList< String > to List< int >? in this case you have to pick every single element and convert it to an integer.

1 Comment

I want to convert from LinkedList<String> to List<Object>. That (i used to think) should be automatic, coz LinkedList IS_A List, and String IS_A Object. But I found out today that it is not. :(
0

just put

public static List<Object> getList() { List l = test; return l; } 

Comments

0

If your list is of a generic type for eg

ArrayList<String> strList = new ArrayList<String>(); strList.add("String1"); Object o = strList;

then Following method should work

public <T> List<T> getListObjectInBodyOfType(Class<T> classz, Object body) { if(body instanceof List<?>){ List<?> tempList = (List<?>)body; if(tempList.size() > 0 && tempList.get(0).getClass().equals(classz)){ return (List<T>) body; } } return new ArrayList<T>(); } 

How to use it?

List<String> strList1 = getListObjectInBodyOfType(String.class, o); 

as I mentioned before it works if the Object contains generic list, this won't work if you pass a non-generic list with mixed type of elements

Comments

0

Based on julman99 answer:

@SuppressWarnings("unchecked") public <T> List<T> cast(List<? super T> list){ return (List<T>) list; } 

Comments

-1

List is an interface, LinkedList is a concrete implementation of that interface. Much of the time an implicit cast will work, assign a LinkedList to a List, or pass it to a function expecting a List and it should just `work'.

An explicit cast can also be done if necessary.

//This is valid List<Customer> myList = new LinkedList<Customer>(); //Also Valid List<Customer> myList = (List<Customer>) new LinkedList<Customer>(); 

1 Comment

an explicit cast is never necessary.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.