Compare two ArrayList in a two way comparison? I have a class called Task which I cannot touch because it's a legacy code and I have two ArrayList made up of Task class which I need to compare. Items can be in any order or there can be duplicates as well in the ArrayList.

What is the best way to compare two ArrayList which has object in it and print out the missing elements as well which are not present in either of the list. Is below code is the right and efficient way to do it? I cannot use any external library for this.

I need to compare my two array list in a two way comparison. 


If data is in source but not in actual, then return false and print out missing elements.
If data is in actual but not in source, then return false as well and print out missing elements.


Below is my code:

public boolean compare(List&lt;Task&gt; source, List&lt;Task&gt; actual) {
    Set&lt;Task&gt; intersection = new HashSet&lt;&gt;(source);
    Set&lt;Task&gt; sourceDifference = new HashSet&lt;&gt;(source);
    Set&lt;Task&gt; actualDifference = new HashSet&lt;&gt;(actual);

    intersection.retainAll(actualDifference);

    sourceDifference.removeAll(intersection);
    for (Task t: sourceDifference) {
        System.out.println(String.format("Task %s not present in actual", t));
    }

    actualDifference.removeAll(intersection);
    for (Task t: actualDifference) {
        System.out.println(String.format("Task %s not present in source", t));
    }

    return sourceDifference.isEmpty() &amp;&amp; actualDifference.isEmpty();
}


Is there any better and efficient way to do this? I am using Java 7.
How about streams API?

public boolean compare(List&lt;Task&gt; source, List&lt;Task&gt; actual) {
    Set&lt;Task&gt; sourceDifference = source.stream()
          .filter(t-&gt;!actual.contains(t))
          .collect(Collectors.toSet());
    for (Task t: sourceDifference) {
        System.out.println(String.format("Task %s not present in actual", t));
    }

    Set&lt;Task&gt; actualDifference = actual.stream()
          .filter(t-&gt;!source.contains(t))
          .collect(Collectors.toSet());
    for (Task t: actualDifference) {
        System.out.println(String.format("Task %s not present in source", t));
    }

    return sourceDifference.isEmpty() &amp;&amp; actualDifference.isEmpty();
}