If there is an instance of Java Collection which may carry primitive type, generic array, and/or iterable collection, I want to treat the generic array as Iterable collection, but how? e.g. the following pseudo java code
List<?> list1;
list1.add(new int[2]);
list1.add(new String[3]);
list1.add(new ArrayList());
for (Object e : list1){
if (e instanceof Iterable){
//The int[2] and String[3] will not fall in this case that I want it be
//Iterate within e
}
}
Please advise how to make the int[2] and String[3] fall in the case.
Thanks & regards, William
Java allows generic classes, methods, etc. that can be declared independent of types. However, Java does not allow the array to be generic. The reason for this is that in Java, arrays contain information related to their components and this information is used to allocate memory at runtime.
You can do this: E[] arr = (E[])new Object[INITIAL_ARRAY_LENGTH]; This is one of the suggested ways of implementing a generic collection in Effective Java; Item 26. No type errors, no need to cast the array repeatedly.
If generic array creation were legal, then compiler generated casts would correct the program at compile time but it can fail at runtime, which violates the core fundamental system of generic types.
Use Array class from reflection package:
final List<Object> list = new ArrayList<Object>();
list.add(new int[] { 1, 2 });
list.add(new String[] { "a", "b", "c" });
final List<String> arrayList = new ArrayList<String>();
arrayList.add("el1");
list.add(arrayList);
for (Object element : list) {
if (element instanceof Iterable) {
for (Object objectInIterable : (Iterable) element) {
System.out.println(objectInIterable);
}
}
if (element.getClass().isArray()) {
for (int i = 0; i < Array.getLength(element); i++) {
System.out.println(Array.get(element, i));
}
}
}
Within your loop, you could use the appropriate array operand for instanceof
.
For int[]
:
if (e instanceof int[]) {
// ...
}
For Object
arrays (including String[]
):
if (e instanceof Object[]){
// ...
}
Alternatively, when adding your arrays to your master List
, you could wrap each one in Arrays.asList()
. In that case, you could use the List<List>
generic instead of the wildcard generic List<?>
and avoid the need to check the data type with instanceof
. Something like this:
List<List> list1;
list1.add(Arrays.asList(new int[2]));
list1.add(Arrays.asList(new String[3]));
list1.add(new ArrayList());
for (List e : list1){
// no need to check instanceof Iterable because we guarantee it's a List
for (Object object : e) {
// ...
}
}
Anytime you're using instanceof
and generics together, it's a smell that you may be doing something not quite right with your generics.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With