Как работать с Set Differences в Java используя объекты? - PullRequest
2 голосов
/ 23 января 2020

Мне нужно получить разницу между двумя наборами / списками, но объекты в этих наборах строятся по-разному. Я хотел бы, чтобы разность наборов была рассчитана только для одного поля этих объектов, как я могу это сделать?

POJO o1 = new POJO();
o1.setName("Bean");
o1.setLocation("Boston");

POJO o2 = new POJO();
o2.setName("Bagel");
o2.setLocation("NYC");

POJO o3 = new POJO();
o3.setName("Bean");

List<POJO> p1 = new ArrayList<>();
p1.add(o1);
p1.add(o2);

List<POJO> p2 = new ArrayList<>();
p2.add(o3);

Collection<POJO> subList = CollectionUtils.subtract(p1, p2);
System.out.println("subList: "+subList.toString());

Вывод, который я вижу: subList: [POJO(name=Bean)] т.е. o3. Но для моего варианта использования o1 и o3 одинаковы - как мне этого добиться? Я переопределил метод equals() по умолчанию, но я не думаю, что он вызывается.

Ответы [ 2 ]

4 голосов
/ 24 января 2020

Вы можете использовать UnifiedSetWithHashingStrategy из Eclipse Collections :

POJO o1 = new POJO();
o1.setName("Bean");
o1.setLocation("Boston");

POJO o2 = new POJO();
o2.setName("Bagel");
o2.setLocation("NYC");

POJO o3 = new POJO();
o3.setName("Bean");

HashingStrategy<POJO> strategy = HashingStrategies.fromFunction(POJO::getName);

MutableSet<POJO> set1 =
        HashingStrategySets.mutable.with(strategy, o1, o2);
MutableSet<POJO> set2 =
        HashingStrategySets.mutable.with(strategy, o3);
MutableSet<POJO> difference = set1.difference(set2);

Assert.assertEquals("[POJO(name=Bagel)]", difference.toString());

Этот ответ объясняет, как UnifiedSetWithHashingStrategy работает более подробно.

Примечание: я являюсь коммиттером для Eclipse Collections.

3 голосов
/ 23 января 2020

Этого можно добиться с помощью перегруженного вычитания с предикатом .

  1. Переопределение hashcode и equals в классе POJO, (и toString для чистого вывода)

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        POJO pojo = (POJO) o;
        return Objects.equals(name, pojo.name);
    }
    
    @Override
    public int hashCode() {
        return name.hashCode();
    }
    
  2. Использовать предикат с установленным значением

    Collection<POJO> subList = CollectionUtils.subtract(p1, p2, new Predicate<POJO>() {
        @Override
        public boolean evaluate(POJO object) {
            return p1.contains(object); // might need to make p1 final
        }
    });
    

Результат:

subList: [Bagel]

Примечание : Apache common не поддерживает ничего вроде Java 8 BiPredicate

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...