Reputation: 834
Imagine having 2 Generic ArrayLists each storing different types. My program will be using only one of these ArrayLists at a time. Is it possible to create a general ArrayList (currentArrayList) which can store both ArrayLists, and use the two ArrayLists without casting.
ArrayList<Integer> arrInt = new ArrayList<>();
arrInt.add(10);
ArrayList<String> arrString = new ArrayList<>();
arrString.add("ten");
ArrayList<XXX> currentArrayList = arrInt;
Integer i = currentArrayList.get(0);
currentArrayList = arrString;
String str = currentArrayList.get(0);
Thanks.
Upvotes: 0
Views: 103
Reputation: 116674
The problem is the part where you want to:
use the two ArrayLists without casting.
Definitely not going to happen. The whole point of a static type system is to stop you from being able to treat a general type as a specific type without explicitly asking to do so.
So for example, you could say:
ArrayList<?> currentArrayList = arrInt;
Object i = currentArrayList.get(0);
But notice that i
is just an Object
, so the compiler is happy - we don't know anything about the things in the array except that they must be Object
-based because this is a Java program. But you want to say:
ArrayList<?> currentArrayList = arrInt;
Integer i = currentArrayList.get(0);
It's that second line that isn't ever going to happen without a cast.
UPDATE Question from comments:
Can't the compiler easily infer the type of the ArrayList by looking at the generic type of arrInt ?
Suppose it did that for us. What should it then do with the type of currentArrayList
when it sees the line:
currentArrayList = arrString;
Your code as it stands assumes that the compiler is not going to do that kind of inference. Suppose you comment-out that second assignment. Now the compiler could make the inference you suggest, and allow your code to compile. But then in the future if you put back the second assignment, the rest of your code would stop compiling! This would be needlessly confusing.
Upvotes: 1
Reputation: 698
You have to determine the type of the object anyway eventually.
i guess you want to avoid "supresswarning("casting")" kind of warning?
if ture, here it goes:
ArrayList<Object> list = new ArrayList<Object>();
list.add(1);
list.add("abc");
list.add(new Double(3.1415926));
list.add(true);
for (Object o : list) {
// or more accurate
String type;
if (o instanceof Integer) {
type = "int";
// logic here...
int i = (Integer) o; // no casting warning
} else if (o instanceof String) {
type = "string";
// logic here...
}
// other possibilities if you want
else { // unmatched
type = o.getClass().getSimpleName();
}
System.out.println(type + ": " + o);
}
Upvotes: 1
Reputation: 1943
Misunderstood the question - why on earth would you want to do that? You are not creating a new ArrayList you are just using a Pointer without the type - its still the same ArrayList!
ArrayList<ArrayList<Object>> array = new ArrayList<ArrayList<Object>>();
array.add(new ArrayList<Integer>());
array.add(new ArrayList<String>());
This should do the trick, since all other possible Objects will inherit from Object in hence be accepted.
Upvotes: 0