使用自定义逻辑比较2个java列表
我想比较两个java列表,其中包含两种不同类型的对象。但是,这两种类型的对象都有一些共同的属性,我想对它们进行比较使用自定义逻辑比较2个java列表,java,java-stream,Java,Java Stream,我想比较两个java列表,其中包含两种不同类型的对象。但是,这两种类型的对象都有一些共同的属性,我想对它们进行比较 class A { int id; } class B { int id2; } List<A> listA; // contains some objects List<B> listB // comparison logic boolean isEqual = true; if(listA.size() != listB.size())
class A {
int id;
}
class B {
int id2;
}
List<A> listA; // contains some objects
List<B> listB
// comparison logic
boolean isEqual = true;
if(listA.size() != listB.size())
isEqual = false;
for(int i=0;i<listA.size();++i) {
if(!listA.get(i).equals(listB.get(i)) {
isEqual = false;
break;
}
}
A类{
int-id;
}
B类{
INTID2;
}
列表a;//包含一些对象
列表B
//比较逻辑
布尔相等=真;
如果(listA.size()!=listB.size())
isEqual=假;
对于(inti=0;i一种方法是使用IntStream
:
boolean equal = (IntStream.range(0, listA.size())
.filter(i -> listA.get(i).equals(listB.get(i))).count() == listA.size());
这对不同大小的列表不起作用,但这只是一个简单的条件(listA.size()==listB.size()
),为了简洁起见,我省略了它
编辑:
可以使用noneMatch()
对其进行改进:
最简单的方法是,您可以实际检查和控制所有要比较的变量,如下所示。只需保留模式并在希望进行.equals()
检查的位置添加更多ifs,并且它将适用于任何大小的列表,您不会得到IndexOutOfBounds异常
class A {
int id;
}
class B {
int id2;
}
List<A> listA; // contains some objects
List<B> listB;
// comparison logic
boolean isEqual = true;
for(int i=0;i<listA.size();++i) {
A objectA = listA.get(i);
for(int y=0; y<listB.size();y++){
B objectB = listB.get(y);
if(!objectA.getVar().equals(objectB.getVar())) {
//And so on for every same object the two classes have and can be compared.
isEqual = false;
break;
}
}
}
}
A类{
int-id;
}
B类{
INTID2;
}
List listA;//包含一些对象
名单b;
//比较逻辑
布尔相等=真;
对于(int i=0;i我认为您应该引入一些服务类,其方法使用A和B作为对象参数,并比较这些对象并返回布尔值。这种方法允许您通过属性比较两个不同的对象。类似于:
public class CompareService {
public boolean comparteObjectAToB(ObjectA a, ObjectB b) {
//logic
}
}
public class SomeService {
private CompareService compareService = new CompareService();
public boolean compare() {
List<ObjectA> listA = new ArrayList<>();
List<ObjectB> list2 = new ArrayList<>();
//some logic which fill lists, empty checks etc
return listA.stream().anyMatch(o1 -> list2.stream().anyMatch(o2 -> compareService.comparteObjectAToB(o1, o2)));
}
}
公共类比较服务{
公共布尔比较ObjectAtoB(ObjectA,ObjectB){
//逻辑
}
}
公共类服务{
private CompareService CompareService=新的CompareService();
公共布尔比较({
List listA=new ArrayList();
List list2=新的ArrayList();
//填写列表、空支票等的逻辑
返回listA.stream().anyMatch(o1->list2.stream().anyMatch(o2->compareService.comparteObjectAToB(o1,o2));
}
}
对于您的代码,如果A大于B,则可能引发if IndexOutOfBoundsException
对我来说,我会这样做
//Change id in class A and B from int to Integer
Boolean isEqual = Boolean.True;
Iterator<A> iterA = listA.iterator();
Iterator<B> iterB = listB.iterator();
while( iterA.hasNext() && iterB.hasNext()){
A a = iterA.next();
B b = iterB.next();
if( !a.getA().equals(b.getB()){
isEqual = Boolean.False;
return;
}
}
//将类A和B中的id从int更改为整数
布尔isEqual=Boolean.True;
迭代器iterA=listA.Iterator();
迭代器iterB=listB.Iterator();
while(iterA.hasNext()&&iterB.hasNext()){
A=iterA.next();
B=iterB.next();
如果(!a.getA().等于(b.getB()){
isEqual=Boolean.False;
返回;
}
}
首先创建一个包含公共属性的接口。然后将implements NewInterface添加到类A和类B。然后实现comparator,比较这些接口。然后使用该comparator比较它们。给定两个bean类,例如
@Immutable
static class Person {
private final String firstName;
private final String secondName;
private final String phoneNumber;
public Person(String firstName, String secondName, String phoneNumber) {
this.firstName = firstName;
this.secondName = secondName;
this.phoneNumber = phoneNumber;
}
public String getFirstName() {
return this.firstName;
}
public String getSecondName() {
return this.secondName;
}
public String getPhoneNumber() {
return this.phoneNumber;
}
}
@Immutable
static class Company {
private final String name;
private final String phoneNumber;
public Company(String name, String phoneNumber) {
this.name = name;
this.phoneNumber = phoneNumber;
}
public String getName() {
return this.name;
}
public String getPhoneNumber() {
return this.phoneNumber;
}
}
公共属性可以放在第三类中,例如
static class CommonData {
private final String phoneNumber;
public CommonData(String phoneNumber) {
this.phoneNumber = phoneNumber;
}
public String getPhoneNumber() {
return this.phoneNumber;
}
@Override
public boolean equals(Object obj) {
if (obj instanceof ListComparisTest.CommonData) {
ListComparisTest.CommonData rhs = (ListComparisTest.CommonData) obj;
return new EqualsBuilder()
.append(this.phoneNumber, rhs.phoneNumber)
.isEquals();
}
return false;
}
@Override
public int hashCode() {
return new HashCodeBuilder()
.append(phoneNumber)
.toHashCode();
}
}
还有两个列表是这样比较的
@Test
public void testCompareLists() {
Function<Person, CommonData> person2CommonData = p->new CommonData(p.getPhoneNumber());
Function<Company, CommonData> company2CommonData = c->new CommonData(c.getPhoneNumber());
List<Person> persons = Arrays.asList(new Person("James", "Cook", "1234566" ), new Person("Francis", "Drake", "2345667" ));
List<Company> companys = Arrays.asList(new Company("Google", "1234566" ), new Company("IBM", "2345667" ));
List<CommonData> personsCommonData = persons.stream().map(person2CommonData).collect(Collectors.toList());
List<CommonData> companysCommonData = companys.stream().map(company2CommonData).collect(Collectors.toList());
Assert.assertTrue(personsCommonData.equals(companysCommonData));
}
@测试
公共void testCompareLists(){
函数person2CommonData=p->newcommondata(p.getPhoneNumber());
函数company2CommonData=c->newcommondata(c.getPhoneNumber());
List persons=Arrays.asList(新人(“詹姆斯”、“库克”、“1234566”)、新人(“弗朗西斯”、“德雷克”、“234567”);
List companys=Arrays.asList(新公司(“谷歌”、“1234566”)、新公司(“IBM”、“234567”);
List personcommondata=persons.stream().map(person2CommonData.collect(Collectors.toList());
列出companysCommonData=companys.stream().map(company2CommonData.collect(Collectors.toList());
Assert.assertTrue(personCommonData.equals(CompanyCommonData));
}
不太可能(但我可能错了)。但我会使用迭代器
而不是get(int)
方法。比较逻辑怎么可能工作?a等于(b)当a.id=b.id2时为true?@Michal,你可以假设这是一个验证检查而不是相等,如果这更合理的话,我想问题和接受的答案在以b为参数的实例上都是相等的,我猜应该是a.id和b.id2。这只是一个玩具示例。在实际用例中,我想比较3个属性为类A和B对象设置一个参数,以确定验证是否成功。如果listB.size()
?如果listB的元素数量少于listA,它不会失败吗?如果第一个元素不相等,您仍然会检查其余的元素。我会使用带有相反条件的anyMatch
。谢谢,我之前误解了。这将按预期工作。但是,我现在不太确定这看起来是否比以前的方法更好。
@Test
public void testCompareLists() {
Function<Person, CommonData> person2CommonData = p->new CommonData(p.getPhoneNumber());
Function<Company, CommonData> company2CommonData = c->new CommonData(c.getPhoneNumber());
List<Person> persons = Arrays.asList(new Person("James", "Cook", "1234566" ), new Person("Francis", "Drake", "2345667" ));
List<Company> companys = Arrays.asList(new Company("Google", "1234566" ), new Company("IBM", "2345667" ));
List<CommonData> personsCommonData = persons.stream().map(person2CommonData).collect(Collectors.toList());
List<CommonData> companysCommonData = companys.stream().map(company2CommonData).collect(Collectors.toList());
Assert.assertTrue(personsCommonData.equals(companysCommonData));
}