General List Printing Method

I am trying to write a generic printing method that works for all classes that implement the Iterable interface

public class List<T> { public static <T extends Iterable<T>> void print(T[] list){ for (Object element : list){ System.out.println(element); } } public static void main(String[] args){ ArrayList<Integer> l = new ArrayList(); l.add(1); l.add(5); l.add(3); l.add(2); print(l); } } 

but I get the error message "The print (T []) method in List type is not applicable for arguments (ArrayList)"

+8
java list generics
source share
4 answers

Your parameter is T[] . This is an array of type that extends Iterable . You just want T . But you also need a type variable for the type parameter in Iterable . You need

 public static <T extends Iterable<E>, E> void print(T list) { 

You need this because you do not want the Iterable<ArrayList> to be what it is in your current implementation.

+7
source share

Your general definition is incorrect. You are trying to set the borders to <T extends Iterable<T>> , but the general parameter ( Integer ) is not T

You can make it work by entering a separate general parameter: one to indicate the collection and one to specify the values ​​of the collection.

Sidenote: You don’t need T[] . You just need T

 public class Main { public static void main(String[] args) { ArrayList<Integer> l = new ArrayList<>(); l.add(1); l.add(5); l.add(3); l.add(2); print(l); } public static <S, T extends Iterable<S>> void print(T list){ for (Object element : list){ System.out.println(element); } } } 

Exit

 1 5 3 2 
+4
source share

Since System.out.println accepts all Object s, and you really don't use your generics inside the method, I see no reason to use generics at all. This code will do the same thing:

 public static void print(Iterable<?> list) { for (Object element : list) { System.out.println(element); } } 

What have you done

I also want to add that you confuse T[] little. T[] means "array type T ". But you are trying to pass it an ArrayList that does not match the array (the ArrayList class uses regular arrays inside, but that doesn't matter).

Let's look at our original method declaration:

 public static <T extends Iterable<T>> void print(T[] list) { for (Object element : list) { System.out.println(element); } } 

This method is declared as a receiving parameter, which is: An array of generic type T, where generic type T is Iterable over the generic type T.

Let's read this last part again: where the generic type T is Iterable over the generic type T.

That is, the generic type must be iterable over itself.

You will need a class like this to use the current print method:

 class MyClass implements Iterable<MyClass> { ... } 

And then use your print method as follows:

 MyClass[] objects = new MyClass[5]; print(objects); 

However, using the current print method, it will only call the MyClass.toString method for each of the 5 elements in the array.

+2
source share

If T extends Iterable , just do this:

 public static <E, T extends Iterable<E>> void print(T list){ for (Object element : list){ System.out.println(element); } } 

Edit: what you declared was T extends Iterable<T> , which could be, for example, Iterable, which is probably not what you are trying to achieve. Then just add another type of list item.

Unless you specifically work with a type, you can also declare a generic type as:

 <T extends Iterable<?>> 
0
source share

All Articles