0

I have two lists filled with object elements. Using these two lists, I want to create another list which contains only the uncommon elements between them.

I tried using an iterator:

for(Row currentRowObject: currentRow) {
    for (Iterator<Row> newError = newErrorRow.iterator(); newError.hasNext(); ) {
        Row rowObject = newError.next();
        if (rowObject.getAll().equals(currentRowObject.getAll())) {
            newError.remove();
        }
    }
}

After I run this, the newError list is completely removed. I checked that the two lists are different, they differ in size and there are objects that differ between these two lists.

How can I solve this problem?

APerson
  • 8,140
  • 8
  • 35
  • 49
John Smith
  • 777
  • 2
  • 14
  • 37

3 Answers3

2

You can use Sets retainAll property & the use removeAll !

Set < Row > rows1 = new HashSet(currentRow);
Set < Row > rows2 = new HashSet(newErrorRow);
rows1.retainAll(rows2); // rows1 now contains only elements in both set !
rows2.removeAll(rows1); // rows2 now contains only the unique elements !
StackFlowed
  • 6,664
  • 1
  • 29
  • 45
  • +1/ You can initialize `row1` as `Set row1 = new HashSet<>(currentRow);` and do the same for `row2` with `newErrorRow`. And also fix the typo in retai**l**All to retai**n**All. – vefthym Nov 05 '14 at 16:24
  • I just saw that the OP asks for the uncommon elements! – vefthym Nov 05 '14 at 16:37
  • I think that it's still wrong, as you are missing the unique elements of currentRow. I think nafas' solution is where you are getting to sooner or later, but my first thoughts were exactly the same as yours. – vefthym Nov 05 '14 at 16:46
2

to explain this in logic format(not Java):

UncommonRows = (currentRow union newErrorRow ) - (currentRow intersection newErrorRow)

here is a quick and dirty way of doing it in Java. hope the comments explains what I've done.

Set<Row> uncommonRows=new HashSet<Row>(currentRow);
uncommonRows.addAll(newErrorRow); //at this point uncommonRows contains all the Rows
Set<Row> retained=new HashSet<Row>(currentRow);
retained.retainAll(newErrorRow); //retained contains all rows that are in both sets.
uncommonRows.removeAll(retained) ; // at this point uncommonRows contains the uncommon Rows
nafas
  • 5,283
  • 3
  • 29
  • 57
  • 1
    @JohnSmith could you upload how you defined your class Row. you must have equal(Object o) and hashCode() method overridden (make them unique) this link should help you [http://stackoverflow.com/questions/27581/what-issues-should-be-considered-when-overriding-equals-and-hashcode-in-java](http://stackoverflow.com/questions/27581/what-issues-should-be-considered-when-overriding-equals-and-hashcode-in-java) – nafas Nov 05 '14 at 16:36
  • @JohnSmith btw make sure, u print out uncommonRows :) – nafas Nov 05 '14 at 16:38
  • @vefthym yeah, I think not having equals method was the reason why the original method didn't work to begin with – nafas Nov 05 '14 at 16:55
  • I solved the problem, the reason was I inversed the lists by mistake that's why it didn't worked, I was confused why it doesn't work because I had the equals and hashcode methods :) – John Smith Nov 05 '14 at 17:18
1

Using java8 you can do something like:

    final List<Row> allErrors = new ArrayList<>();
    allErrors.addAll(currentRow);
    allErrors.addAll(newErrorRow);

and then:

final List<Row> result = allErrors.stream().filter(p -> Collections.frequency(allErrors, p) == 1)
            .collect(Collectors.toList());
jjlema
  • 850
  • 5
  • 8