我想比较2个Java列表,其中包含2种不同类型的对象。但是,这两种类型的对象都有一些共同的属性,我想对它们进行比较。
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;
}
}
是否有一种通过java流简洁地编写此代码的好方法?
答案 0 :(得分:2)
一种方法是使用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()
进行改进:
boolean equal = IntStream.range(0, listA.size())
.noneMatch(i -> listA.get(i).id != listB.get(i).id2);
答案 1 :(得分:0)
最简单的方法是,您实际上可以检查和控制要比较的所有变量,如下所示。只需保持模式并在要进行.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;
}
}
}
}
答案 2 :(得分:0)
我认为您应该引入一些服务类,其方法使用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)));
}
}
答案 3 :(得分:0)
使用您的代码,如果A大于B,则可能抛出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;
}
}
答案 4 :(得分:0)
首先创建一个包含通用属性的接口。然后将实现NewInterface添加到类A和类B。然后实现比较器,比较这些接口。然后使用该比较器进行比较。
答案 5 :(得分:0)
给出两个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));
}