How to use Collections (removeAll () and retainAll ()) methods for two objects

I expected to get lower, but not really. Although this worked when I tried to use String instead of Item Object. I would like to know why the reasons for this and how to code to get the expected result. Thanks.

EXPECTED ------------------------------ removed object are: 2 same object are: 1 3 add object are: 4 ------------------------------ 

 ACTUAL ------------------------------ removed object are: 1 2 3 same object are: add object are: 1 3 4 ------------------------------ 

 package com.javastudy; import java.util.ArrayList; import java.util.List; public class CollectionCompareToObjects { public static void main(String[] args) { List<Item> before = new ArrayList<Item>(); List<Item> after = new ArrayList<Item>(); before.add(new Item(1L)); before.add(new Item(2L)); // delete before.add(new Item(3L)); after.add(new Item(1L)); after.add(new Item(3L)); after.add(new Item(4L)); // added List<Item> removed = new ArrayList<Item>(before); removed.removeAll(after); System.out.println("removed objects are:"); for(Item item : removed){ System.out.println(item.getId()); } List<Item> same = new ArrayList<Item>(before); same.retainAll(after); System.out.println("same objects are:"); for(Item item : same){ System.out.println(item.getId()); } List<Item> added = new ArrayList<Item>(after); added.removeAll(before); System.out.println("add objects are:"); for(Item item : added){ System.out.println(item.getId()); } } } package com.javastudy; public class Item { Long id; public Item(Long id) { this.id = id; } public Long getId() { return id; } public void setId(Long id) { this.id = id; } } 
0
source share
5 answers

You did not implement equals (), so ALL of your objects are different objects, some of which have the same field.

You need to implement equals.

I also suggest you use long instead of Long if you don't want id = null.

+4
source

You should override the equals(..) method of your Item and compare the id field (basically, the equals method should just do return id.equals(other.getId()) with the corresponding null checks.

When using equals and hashCode() - both methods should always be executed together with the same fields.

And you need to override these methods, because the removeAll and retainAll work by iterating through collections and comparing existing elements with elements from the past collection via equals(..)

+2
source

implement equals() and hashCode() in your product class, for example. eg:

 @Override public int hashCode(){ return Objects.hash(id); } @Override public boolean equals(Object obj){ if(this == obj) return true; else if(obj instanceOf Item){ // implicit null check Item other = (Item) obj; return Objects.equals(this.id, other.id); } else return false; } 

I assume that after that it will work as expected.

+2
source

You need to override the equals and hashCode methods of your Item class. If you do not, then Java uses the standard equals implementation, which is equivalent to == :

 Item first = new Item(1); Item second = new Item(1); System.out.println(first == second); // Prints false, as expected: they are different objects. System.out.println(first.equals(second)); // Prints false because of the default equals method. 

If you implement equals correctly, the output will be false , followed by true .

0
source

When you instantiate twice an element even with the same parameter, you will have 2 objects with different values. Two solutions:

  • use the same link
  • override equals from object
0
source

Source: https://habr.com/ru/post/1332370/


All Articles