2
\$\begingroup\$

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<Task> source, List<Task> actual) {
    Set<Task> intersection = new HashSet<>(source);
    Set<Task> sourceDifference = new HashSet<>(source);
    Set<Task> actualDifference = new HashSet<>(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() && actualDifference.isEmpty();
}

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

\$\endgroup\$

2 Answers 2

1
\$\begingroup\$

How about streams API?

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

    Set<Task> actualDifference = actual.stream()
          .filter(t->!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() && actualDifference.isEmpty();
}
\$\endgroup\$
0
0
\$\begingroup\$

Since Timothy already proposed a solution using java 8, let's review the actual code:

From what I can tell, you're doing everything right here:

  • Left hand side of variables is declared as interface type
  • Use of copy-constructors
  • Simple and descriptive naming
  • Use of the proper Collections API (retainAll is often forgotten)
  • Simple boolean return instead of strange if-else constructions.

Long story short: Good job on this code, for java 7 this is probably the best you can get.

\$\endgroup\$
3
  • \$\begingroup\$ "you're doing everything right here" accept separation of concerns. The output might not belong to this method... \$\endgroup\$ Commented Mar 5, 2017 at 17:22
  • \$\begingroup\$ would require either returning a tuple or modifying global state .. seems like the lesser evil to me \$\endgroup\$
    – Vogel612
    Commented Mar 5, 2017 at 17:27
  • \$\begingroup\$ "would require either returning a tuple or modifying global state" or passing in an output component... \$\endgroup\$ Commented Mar 5, 2017 at 17:46

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.