casting LinkedList<Object> to LinkedList<Customer> - java

I have a method like this
public static LinkedList<Object> getListObjectWithConditionInXMLFile(String className){
LinkedList<Object> lstObj = new LinkedList<Object>();
if(className.equals("Customer")){
//read Data from XML File
Customer customer = ...;
lstObj.add(customer);
}
....
return lstObj;
}
after that i call this method and want to cast :
LinkedList<Customer> lstCustomer = (LinkedList<Customer>()) getListObjectWithConditionInXMLFile("Customer");
But it cannot cast.
How can i cast from LinkedList to LinkedList ?
Pls help me ! thanks so much !

You can refactor your method to something like this:
public static <E> LinkedList<E> getListObjectWithConditionInXMLFile(Class<E> type){
LinkedList<E> lstObj = new LinkedList<E>();
if (type.equals(Customer.class)) {
Customer customer = ...
lstObj.add((E)customer);
}
return lstObj;
}
By making the method generic and passing a Class parameter you can return a list of the right type.
You can call it this way
List<Customer> l = getListObjectWithConditionInXMLFile(Customer.class);

You will have to create new List and add casted object to the new linked list of Customer.
LinkedList<Customer> custList = new LinkedList<>();
for(Object obj: getListObjectWithConditionInXMLFile("Customer")) {
custList.add((Customer)obj));
}
Or, it is better to use generics if possible as mentioned by "Boris the Spider" in comment.
public static <T> LinkedList<T> getListObjectWithConditionInXMLFile(Class<T> requiredClass)
The definition can be as follows as given by "micha".
public static <T> LinkedList<T> getListObjectWithConditionInXMLFile(Class<T> requiredClass){
LinkedList<T> listObj = new LinkedList<>();
if (requiredClass.equals(Customer.class)) {
Customer customer = /*...*/
listObj.add((T)customer);
}
return listObj;
}
Then, You can call as
LinkedList<Customer> custList = getListObjectWithConditionInXMLFile(Customer.class);

Related

How to return different POJO using Java generics

I would like a method to return a different type of List.
I tried something like the following but not sure if this approach is correct or not. How can I do this?
public <T> List<T> getPageDetails(Long adId,String source);
Based on the source I will return a different List of objects in the implementation method.
Like in implementation if the source is 1, then will have to return List of objects type1, if the source is 2 then list of objects type2, etc.
private Object objT;
public <T> List<T> magicalListGetter(Class<T> cls) {
List<T> list = new ArrayList<>();
list.add(cls.cast(actuallyT));
try {
list.add(cls.getConstructor().newInstance()); // If default constructor
} ...
return list;
}
One can give a generic type parameter to a method too. You have correctly deduced that one needs the correct class instance, to create things (cls.getConstructor().newInstance()).
Without class :
public <T> List<T> magicalListGetter() {
return new ArrayList<T>();
}
You can use genrics to return multiple list
public <T> List<T> getPageDetails(Long adId,String source);
public static void main(String[] args) {
Solution sol = new Solution();
List<String> list = sol.getPageDetails(String.class, 0l, "source");
}
public <T> List<T> getPageDetails(Class<T> c, Long adId, String source) {
List<T> list = new ArrayList<>();
List<Object> objectList = getObjectList(adId, source);
for (Object o : objectList) {
T t = c.cast(o);
list.add(t);
}
return list;
}
private List<Object> getObjectList(Long adId, String source) {
// TODO Auto-generated method stub
return null;
}

Assigning a variable from nested generics in generic class in Java?

If I have the following code:
public class DummyClass<T> {
public List<T> getList() {
return new ArrayList<T>();
}
public Set<List<T>> getListSet() {
return new HashSet<List<T>>();
}
}
and I have a DummyClass<?> dummy,
I can do
List<?> list = dummy.getList();
without any errors.
However,
Set<List<?>> listSet = dummy.getListSet();
gives the compile error:
Type mismatch: cannot convert from Set<List<capture#1-of ?>> to Set<List<?>>
for the line assigning dummy.getListSet().
Why can't I assign dummy.getListSet() to a Set<List<?>>?
However you can do following:
Set<? extends List<?>> listSet = listSet = dummyClass.getListSet();
See the excellent article Generics gotchas.
First is important to know, that the compiler replace ? operator with Object class. So when you write this:
DummyClass<?> dummy
your class definition will look like this:
public class DummyClass<Object>
and methods like this:
public List<Object> getList() {
return new ArrayList<Object>();
}
public Set<List<Object>> getListSet() {
return new HashSet<List<Object>>();
}
You can write
List<?> list = new List<Object>();
but not
Set<List<?>> set = new HashSet<List<Object>>();

java how to create generic singleton class

This is my current code:
import java.util.ArrayList;
public class SingletonAList<T> {
private final ArrayList<T> aL = new ArrayList<T>();
SingletonAList() {}
public ArrayList<T> getList(T t) {
return aL;
}
}
What I am looking to do is have it return a Singleton List of the type if it exists; if not to create a new one of type T;
so example three getList calls are made;
getList(Obj1);
getList(Obj2);
getList(Obj1);
On first getList a new ArrayList<Obj1> would be created;
on second getList a new ArrayList<Obj2> would be created;
and on third getList the same arrayList from the first call would be returned.
Any implementation suggestions? I have been messing around...it seems that the new call must be in the getList call; and possibly another list of Types that have already been instantiated?
One solution could be something like :
public class SingletonAList {
private static Map<Class, List> lists = new HashMap<Class, List>();
public static <T> List<T> getInstance(Class<T> klass) {
if (!lists.containsKey(klass)) {
lists.put(klass, new ArrayList<T>());
}
return lists.get(klass);
}
}
After, you can call it with SingletonAList.getInstance(String.class);

Generic method that takes List in non generic class

I want to do something like this
private <T extends List<?>> List<?> getFirstFiveElements(T list) {
//body
}
However when I tray to pass in the arguments it is not working
List<A> a = new LinkedList<A>;
List<B> b = new LinkedList<B>;
getFirstFiveElements(a);
getFirstFiveElements(b);
so any suggestion how I cam make this work.
The following should work just fine.
private static <A, T extends List<A>> List<A> getFirstFiveElements(T list) {
//
}
T serves no useful purpose here, and therefore can be eliminated.
private static <A> List<A> getFirstFiveElements(List<A> list) {
//
}
If you want the method to return the same type that it takes (i.e. ArrayList for ArrayList, LinkedList for LinkedList), then sorry to tell you, Java's type system is not capable of that.
Great 2 second later, I have found the magic combination. Anyway for all of the others who stumble upon this here is what worked for me
private <T> List<T> getStart(List<T> list)
This works for me:
import java.util.*;
public class Test {
private static <T extends List<?>> List<?> getFirstFiveElements(T list) {
List<Object> result = new LinkedList<Object>();
for (int i = 0; i < 5 && i < list.size(); i++) {
result.add(list.get(i));
}
return result;
}
public static void main(String[] args) {
List<Integer> a = new LinkedList<Integer>();
a.add(1);
a.add(2);
a.add(3);
a.add(4);
a.add(5);
a.add(6);
a.add(7);
System.out.println(getFirstFiveElements(a));
}
}
Why do you want to use template? Would not be enough to use this:
private List<?> getFirstFiveElements(List<?> list) {
//body
}

How to initialize List<E> in empty class constructor?

The following code obviously doesn't work because List<E> is abstract:
public class MyList {
private List<E> list;
public MyList() {
this.list = new List<E>();
}
}
How can I initialize MyList class with an empty constructor if I need the list variable to be a LinkedList or a ArrayList depending on my needs?
I'm not sure whether this is what you're asking...
public class MyList {
private List<E> list;
public MyList() {
if (myNeeds)
this.list = new LinkedList<E>();
else
this.list = new ArrayList<E>();
}
}
There are better alternatives for what you are trying to achieve:
Create a base class (abstract?) and override it twice, once for ArrayList and one for LinkedList
Inject the appropriate list to your class (dependency injection)
Why not use a protected (and possibly abstract method) like:
public abstract class MyList<T> {
protected final List<T> list;
public MyList() {
list = createList();
}
public MyList(boolean preferLinked) {
list = preferLinked? new LinkedList<T>() : new ArrayList<T>();
}
// Allows client code which subclasses from MyList to override the
// default behaviour
protected List<T> createList() {
return new ArrayList<T>();
}
}
boolean shouldThisBeAnArrayList=true; // Set to false to use LinkedList
if(shouldThisBeAnArrayList) {
this.list = new ArrayList<E>();
}
else {
this.list=new LinkedList<E>();
}
You need to determine what "your needs" are in the default case - LinkedList or ArrayList. If you can't - say, if the need changes depending on something that happens over the object's lifetime, then the list needs to change, too.
List is an interface and as such, cannot be constructed. Only implementations of said interface can be constructed (e.g. ArrayList). Also, you need to know the type (E) at construction.
This should work:
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
public class MyList<E> {
private List<E> list;
public MyList(boolean linked) {
if (linked) {
list = new LinkedList<E>();
} else {
list = new ArrayList<E>();
}
}
}
I would think you could do the following:
public class MyList<T> {
private List<T> list;
public MyList() {
this.list = new ArrayList<T>();
}
}
As I understand, you cannot use just a empty constructor, because you have a decision node in your model, when you need to choose between the type of the list, so, you will have to tell the program any way what kind of list will be.
This seems to be the best solution in my opinion:
public class MyList {
private List<E> list;
public MyList() {
this.list = new LinkedList<E>();
}
//an overload for another type,
public MyList(bool INeedArray) {
if (INeedArray)
this.list = new ArrayList<E>();
}
}
public class MyList<T> {
private List<T> list = new ArrayList<T>();
}
This is what I use in classes.. I have for a long initialized what I could when defining the private variable it self.

Categories

Resources