1

I have a wrapper layer which returns me a Collection of objects of certain Type. Now I call this wrapper in my application which has a different type, so I try to cast the whole collection that is been returned into my application type.

Collection<wrapperType> wrapperCollection = wrapper.method();
MyApp<appType> appCollection = (Collection<appType>)wrapperCollection;

Above casts wrapperCollection to appCollection. Now when i try to do this-:

for( appType item : appCollection) // Exception-: can't convert wrapperType to appType.
{
.......
}

I am trying to figure out-:

  • How can I cast wrapperCollection to appCollection so that each item inside the appCollection becomes appType and then I can iterate over it? Is there any other better way via which I can easily cast ans Iterate over collection.
  • I am also thinking is casting a good idea at all performance wise.

I researched following links-:

Cast a Collection to another

Community
  • 1
  • 1
Mr. Wonderful
  • 189
  • 4
  • 13
  • 1
    Please show us the signature for `MyApp`, `wrapperType`, and `appType` – Tim Biegeleisen Apr 13 '15 at 16:39
  • wrapperType and appType contains mostly same fields like personId, name etc. appType has few more fields that can be populated further via MyApp. – Mr. Wonderful Apr 13 '15 at 16:44
  • Clearly `wrapperCollection` contains something that's not an `appType`. (Perhaps you need to learn more about inheritance and casting in general here...?) https://docs.oracle.com/javase/tutorial/java/IandI/subclasses.html – Radiodef Apr 13 '15 at 17:11
  • please remember to mark your question as answered if a solution suits your problem. – Turing85 Apr 13 '15 at 21:06
  • sure, I am still working on it. More likely to follow generics approach. – Mr. Wonderful Apr 13 '15 at 22:19

4 Answers4

0

You cannot cast a Collection<WrapperType> into a Collection<appType> or vice-versa. One reason this is not possible is discussed here. If you want to achieve your goal, you need to do this manually, i.e. iterate over the Collection<WrapperType>, cast each entry into an object of type appType and add them to a new Collection<appType>

EDIT: look at @Jean-François Savard's answer for a workaround. This is also known as PECS

Community
  • 1
  • 1
Turing85
  • 18,217
  • 7
  • 33
  • 58
0

You want to use either a generic collection, or define a parent class (mostly an interface or abstract class) which both class extends/implements. Then store your object as list of this parent class instead.

Note that if you choose to use generics, both type must be compatible. Example :

List<? extends Integer> intList = new ArrayList<Integer>();

for(Number i : intList)
Jean-François Savard
  • 20,626
  • 7
  • 49
  • 76
  • Thanks for suggestions guys. I ended up using generics as Jean-Francois / Turing85 suggested. I also gave an attempt to create a base class which both wrapperType and appType can extend. Issue with that is wrapper is a layer which eventually going to be consumed by various applications, so I am not sure where base class would reside? PS: don't have enough points to vote up answers, though I marked which was helpful to me. – Mr. Wonderful Apr 14 '15 at 03:16
0

I believe you can refactor your code to something like below.

package com.test;

import java.util.ArrayList;
import java.util.List;

public class GenericWrap {

public static void main(String[] args) {
    List<? super String> myList = new ArrayList<String>();
    myList.add("hello");
    myList.add("world");
    for(String s : (List<String>)myList){
        System.out.println(s);
    }
}

}
Pavan Kumar
  • 4,182
  • 1
  • 30
  • 45
0

If you want to do it without using any framework / library, then you must do it "by hand" (read: manually). If you can get the help of "something" already built for this purposes, try Dozer; it's (almost) the perfect tool for doing that kind of stuff.

x80486
  • 6,627
  • 5
  • 52
  • 111