Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

how to compare two objects each containing primitive type and collection of objects in java?

Tags:

java

java-8

I have two DTO objects like following, please, note that I am using lombok to avoid boilerplate code.

DtoA

import lombok.Data;
import java.util.List;

@Data
public class DtoA {

    private String name;
    private String number;
    private List<String> aList;
}

DtoB

import lombok.Data;
import java.util.List;

@Data
public class DtoB {
    private String name;
    private String phone;
    private List<String> bList;
}

I want to compare specific fields of both objects so i have created an adaptor kind of object like following

DtoAdapter

import lombok.Data;
import java.util.List;

@Data
public class DtoAdapter {
    private String nameText;
    private List<String> xList;
}

Following is my Test class with main method where i am trying to do comparison This comparison is failing because of aList and bList contains strings in different orders. I want to compare the contents of the list without worrying about their order.

Test

import junit.framework.Assert;
import java.util.ArrayList;
import java.util.List;

public class Test {
    public static void main(String[] args) {
        DtoA a = new DtoA();
        List<String> aList = new ArrayList<>();
        aList.add("x"); aList.add("y"); aList.add("z");
        a.setName("abc"); a.setNumber("123"); a.setAList(aList);

        DtoB b = new DtoB();
        List<String> bList = new ArrayList<>();
        bList.add("z"); bList.add("x"); bList.add("y");
        b.setName("abc"); b.setPhone("123"); b.setBList(bList);

        DtoAdapter a1 = new DtoAdapter();
        a1.setNameText(a.getName()); a1.setXList(a.getAList());

        DtoAdapter b1 = new DtoAdapter();
        b1.setNameText(b.getName()); b1.setXList(b.getBList());

        // comparision failing because of lists contains string in different orders
        Assert.assertEquals(a1, b1);
    }
}

Note: I have tried writing compareTo (by implementing comparable interface into DtoAdapter class) But I couldn't write comparison of two lists with compareTo method like following

DtoAdapter with comparable interface

import lombok.Data;
import java.util.List;

@Data
public class DtoAdapter implements Comparable<DtoAdapter>{
    private String nameText;
    private List<String> xList;

    @Override
    public int compareTo(DtoAdapter o) {
        return this.getNameText().compareTo(o.getNameText());
        // how to compare this.getXList() and o.getXList() with compareTo?
    }
}
like image 232
praxnet Avatar asked Mar 03 '23 07:03

praxnet


2 Answers

What you are looking forward to is not extending a Comparable but an overriden equals implementation for the class(along with hashcode of course).

@Override
public boolean equals(Object o) {
    if (this == o) return true;
    if (o == null || getClass() != o.getClass()) return false;
    DtoAdapter that = (DtoAdapter) o;
    // following line of code specifically
    return Objects.equals(nameText, that.nameText) &&
            that.getXList().containsAll(xList) && xList.containsAll(that.getXList());
}

Further from the documentation of Comparable, the interface is primarily used for ordering elements and not for equality comparison :

This interface imposes a total ordering on the objects of each class that implements it. This ordering is referred to as the class's natural ordering, and the class's compareTo method is referred to as its natural comparison method.

like image 50
Naman Avatar answered Apr 06 '23 15:04

Naman


Like the answer from @Naman, you can should override the method equals but try to first compare the lists' length because if have the same length, you only need to check if the elements of the first list are in the other.

@Override
public boolean equals(Object o) {
    if (o == this) {
        return true;
    } 

    if (!(o instanceof DtoAdapter)) {
        return false;
    }

    DtoAdapter that = (DtoAdapter) o;

    return Objects.equals(nameText, that.nameText) && that.getXList().size() == xList.size() && that.getXList().containsAll(xList);

}
like image 40
Raquel Fernández González Avatar answered Apr 06 '23 17:04

Raquel Fernández González