Q:

About java Collections and generics:

I have been given the following school assignment:
Given two sorted lists of comparable items, L1 and L2
(a) Implement a method in Java to determinate if L1 and L2 are disjoints lists.
(b) Implement a method in Java to compute the difference (\) between L1 and L2. L1 \ L2 = { x | x ∈ L1 and x ∉ L2 }.
 (c) What is the running time complexity of your methods? Justify.

Note: For this problem you can use only the Java Collections API basic methods.
I have answered both questions but have found two possible solutions to problem (b), given that I am still learning java Generics and wildcards and have still yet to fully grasp this concept.
Here is my answer to question (a):
public static final <T> boolean disjoint(List<? extends T> list1, List<? extends T> list2 ){
        return Collections.disjoint(list1, list2);
    }

This method efficiently answers if both lists are disjoint or not. And uses Collections.disjoint just as the problem requested.
ex:
List<Float> lista = Arrays.asList(2.3f, 3.4f);
List <Object> listb = Arrays.asList("a","b","c","d", 1, 2, 3, 3.4f);

System.out.println(SetList.disjoint(list1, list9));//prints false;

Now for part (b) I created first the following method:
public static final <T> List<? super T> 
                              setDifference(List<? extends T> list1, List<? extends T> list2){

            List<? super T> resultSet = new ArrayList<>();

            for(T x : list1){
                if(!list2.contains(x)){
                    resultSet.add(x);
                }
            }
            return resultSet;
    }

This method allows me to do the following:
List <Object> list1 = Arrays.asList(1.2f,12f, "a","b","c","d", 1,2,3,3.4f);
List<Float> list9 = Arrays.asList(2.3f, 3.4f);

System.out.println(SetList.setDifference(list1, list9));
//Prints [1.2, 12.0, a, b, c, d, 1, 2, 3]

or this:
List<Integer> list3 = Arrays.asList(1,2,3,4,10);
List<Float> list9 = Arrays.asList(2.3f, 3.4f);
System.out.println(SetList.setDifference(list3, list9));
// this prints [1, 2, 3, 4, 10]

Now since the problem says that the lists are of comparable items I naively assumed that I must throw in comparable in the signature of this method so I implemented the following:
public static final <T extends Comparable<? super T>> List<? super T> 
                              setDifference2(List<? extends T> list1, List<? extends T> list2){

        List<T> resultSet = new ArrayList<>();

        for(T x: list1){
            if(Collections.binarySearch(list2, x)<0){
                resultSet.add(x);
            }
        }
        return resultSet;
    }  

  However with this signature it seems I can only take lists that have the same type, which was not the case before where I could take a list of type object and a list of Integers etc. 

It seems that now I can only work with lists of the same type. And I really do not know if that is was the problem intended me to do since the beginning. 

I understand that Binary search improves the performance of this problem but does it do it at the expense of the restriction it imposes over the input of the method? 

Also am I doing proper use of the wildcards for these methods signatures and Lists declarations?

I recently started reading the book: Java Generics and Collections by Maurice Naftalin and Philip Wadler and I am trying to follow the recommendations from the book, the gets and puts principle etc, would love some advice and consult about these answers I came up with and also some recommended further reading that would enable me to learn this topic better.  

A:

I understand that Binary search improves the performance of this problem but does it do it at the expense of the restriction it imposes over the input of the method? 

Yes.

Also am I doing proper use of the wildcards for these methods signatures and Lists declarations?

Yes.

