Search code examples
javafunctionobjectgenericstreemap

Java Generics and Functions


I have a function

public static void printTreeMap (TreeMap <Object, ArrayList> map, PrintStream ps)

and a TreeMap:

TreeMap <Integer, ArrayList<MyClass>> tm = new TreeMap<>();

When I'm trying to call printTreeMap like that: printTreeMap(tm, System.out);, I get an exception

The method printTreeMap(TreeMap<Object,ArrayList>, PrintStream) in the type task_v7 is not applicable for the arguments (TreeMap<Integer,ArrayList<MyClass>>, PrintStream) Java(67108979)

How can I fix it?


Solution

  • I would suggest this approach. Note that for general methods of this type there is no a priori knowledge of those types. Therefore, this relies solely on the types involved overriding toString().

    public static <T,U> void printTreeMap(TreeMap<T,  ArrayList<U>> tm, PrintStream st) {
         tm.forEach((k,v)-> {
              st.println(k);
              for (U e : v) {
                  st.println("  " + e);
              }
         });
    }
    

    Note that T and U need not be different as both could be the same type.

    Here is an example.

    TreeMap<Integer, ArrayList<MyClass>> tm = new TreeMap<>();
    tm.put(10, new ArrayList<>(
            List.of(new MyClass("Alpha"), new MyClass("Beta"))));
    tm.put(30, new ArrayList<>(
            List.of(new MyClass("Gamma"), new MyClass("Delta"))));
    
    printTreeMap(tm, System.out);
    

    Prints

    10
      Alpha
      Beta
    30
      Gamma
      Delta
    

    The class

    class MyClass {
        String a;
        
        public MyClass(String a) {
            this.a = a;
        }
        
        public String toString() {
            return a;
        }
    }
    

    A more versatile approach for any Map of Lists would be the following:

    public static <L extends List<?>, M extends Map<?,L>> void printMapOfLists(M tm,
            PrintStream st) {
        tm.forEach((k, v) -> {
            st.println(k);
            for (Object e : v) {
                st.println("  " + e);
            }
        });
    }