I am attempting to write a helper print method so I can print items out to the console with less code and in an easier fashion.
I am however, running into issues printing arrays that are passed into my method because I cannot loop over a regular generic variable (E), but I am not seeing a way to fix it without possibly overloading the method.
Why does looping not work in my instance when I check that the variable is an array of generic type? I feel like this should at least allow a cast to an array (which is what the commented code shows now), but that fails too, which makes me think a cast from E to E[] is not possible in Java.
Here is my code:
@SafeVarargs@SuppressWarnings("unchecked")//SAFE
public static <E> void print(E... toPrint){
//USED TO ENHANCE SYSTEM.OUT.PRINTLN AND MAKE EASIER TO TYPE
E[] itemArray;
for(E item: toPrint){
if(item.getClass().isArray()){//IS ARRAY
//System.out.println(item.getClass());
//itemArray = (E[]) item;//WILL NOT WORK, CANNOT CONVERT
////IF LOOP ITEM ERROR NOT ITERABLE, BUT IT IS ARRAY?
//for(E innerItem: itemArray)
//System.out.println(innerItem);
}else{
System.out.println(item);
}
}
}
Updated code based on @Sweeper's Suggestion:
@SafeVarargs//SAFE
public static <E> void print(E... toPrint){
//USED TO ENHANCE SYSTEM.OUT.PRINTLN AND MAKE EASIER TO TYPE
for(E item: toPrint){
if(item.getClass().isArray()){//IF IS ARRAY
printHelperForArrays(item);//MUST CHECK IF PRIMITIVE[] OR OBJECT[]
}else if (item instanceof List){//IF ITEM IS LIST
String[] stringArray = item.toString()
.replace("[","")//REMOVE [
.replace("]","")//REMOVE ]
.split(", ");//TURN TO ARRAY
for(String innerItem: stringArray)
System.out.println(innerItem);//NOW PRINT EVERYTHING OUT
}else{
System.out.println(item);
}
}//END FOR
}
@SuppressWarnings("unchecked")//SAFE
public static <E> void printHelperForArrays(E item){
//USED TO PRINT OUT ARRAY ELEMENTS
if(item.getClass() == int[].class){//IS INT[]
String[] stringArray = Arrays.toString((int[])item)
.replace("[","")//REMOVE [
.replace("]","")//REMOVE ]
.split(", ");//TURN TO ARRAY
for(String innerItem: stringArray)
System.out.println(innerItem);//NOW PRINT EVERYTHING
}else if(item.getClass() == double[].class){//IS DOUBLE[]
String[] stringArray = Arrays.toString((double[])item)
.replace("[","")//REMOVE [
.replace("]","")//REMOVE ]
.split(", ");//TURN TO ARRAY
for(String innerItem: stringArray)
System.out.println(innerItem);//NOW PRINT EVERYTHING OUT
}else if(item.getClass() == float[].class){//IS FLOAT[]
String[] stringArray = Arrays.toString((float[])item)
.replace("[","")//REMOVE [
.replace("]","")//REMOVE ]
.split(", ");//TURN TO ARRAY
for(String innerItem: stringArray)
System.out.println(innerItem);//NOW PRINT EVERYTHING OUT
}else if(item.getClass() == char[].class){//IS CHAR[]
String[] stringArray = Arrays.toString((char[])item)
.replace("[","")//REMOVE [
.replace("]","")//REMOVE ]
.split(", ");//TURN TO ARRAY
for(String innerItem: stringArray)
System.out.println(innerItem);//NOW PRINT EVERYTHING OUT
}else if(item.getClass() == boolean[].class){//IS BOOLEAN[]
String[] stringArray = Arrays.toString((boolean[])item)
.replace("[","")//REMOVE [
.replace("]","")//REMOVE ]
.split(", ");//TURN TO ARRAY
for(String innerItem: stringArray)
System.out.println(innerItem);//NOW PRINT EVERYTHING OUT
}else if(item.getClass() == byte[].class){//IS BYTE[]
String[] stringArray = Arrays.toString((byte[])item)
.replace("[","")//REMOVE [
.replace("]","")//REMOVE ]
.split(", ");//TURN TO ARRAY
for(String innerItem: stringArray)
System.out.println(innerItem);//NOW PRINT EVERYTHING OUT
}else if(item.getClass() == short[].class){//IS SHORT[]
String[] stringArray = Arrays.toString((short[])item)
.replace("[","")//REMOVE [
.replace("]","")//REMOVE ]
.split(", ");//TURN TO ARRAY
for(String innerItem: stringArray)
System.out.println(innerItem);//NOW PRINT EVERYTHING OUT
}else if(item.getClass() == long[].class){//IS LONG[]
String[] stringArray = Arrays.toString((long[])item)
.replace("[","")//REMOVE [
.replace("]","")//REMOVE ]
.split(", ");//TURN TO ARRAY
for(String innerItem: stringArray)
System.out.println(innerItem);//NOW PRINT EVERYTHING OUT
}else{//IS OBJECT[] LIKE INTEGER[], STRING[], CHARACTER[]... SO E[] WORKS
String[] stringArray = Arrays.toString((E[])item)
.replace("[","")//REMOVE [
.replace("]","")//REMOVE ]
.split(", ");//TURN TO ARRAY
for(String innerItem: stringArray)
System.out.println(innerItem);//NOW PRINT EVERYTHING OUT
}
}
Passed Args:
int[] int1 = {4, 5, 6};
Integer[] Integer2 = {7, 8, 9};
double[] double3 = {10.01, 11.01, 12.01};
Double[] Double4 = {13.01, 14.01, 15.01};
char[] char5 = {'A', 'B', 'C'};
Character[] Character6 = {'D', 'E', 'F'};
float[] float7 = {1.999f, 2.999f};
Float[] Float8 = {3.999f, 4.999f};
LinkedList<String> listOfStrings = new LinkedList<>();
listOfStrings.add("List Item 1");
listOfStrings.add("List Item 2");
//CALLED AS
print(1, 2, 3, "Hello", int1, Integer2, double3,
Double4, char5, Character6, float7, Float8, listOfStrings);
Output
1
2
3
Hello
4
5
6
7
8
9
10.01
11.01
12.01
13.01
14.01
15.01
A
B
C
D
E
F
1.999
2.999
3.999
4.999
List Item 1
List Item 2
Now everything prints on its own line whether it is a primitive, an element in a Wrapper class, an array, a list, or whatever.
Your code doesn't work because you are trying to cast an array type E
to an array of arrays - E[]
.
If the execution goes into the if statement, that mean E
is an array type. So E[]
is an array of arrays. E[]
and E
are unrelated types.
So you need to some how let the compiler know that you are sure that E
is an array and it can be looped over. However, there is no way to do that in Java.
So yeah, you need to overload print
. This technique is widely used in the standard library. Just look in the Arrays
class, almost every method there has overloads for all kinds of arrays. Java arrays have many limitations that you have to live with.
By the way, do you know there is a handy method called Arrays.toString
? It can simplify your array printing process:
System.out.println(Arrays.toString(arr));
Maybe you don't need your print
after all.
Note:
Your code works, just not for primitive type arrays, so if you pass in a Integer[]
it will print it out successfully.
Edit:
You could work around this problem by checking the type against each type of primitive array:
public static void print(Object... toPrint) {
for (Object item : toPrint) {
if (item.getClass() == int[].class) {
System.out.println(Arrays.toString((int[])item));
} else if (item.getClass() == double[].class) { // check for all primitive types
System.out.println(Arrays.toString((double[])item));
} else if (item instanceof Object[]){
System.out.println(Arrays.toString((Object[])item));
} else {
System.out.println(item);
}
}
}