如何比较两个在java中至少有一个属性不同的类似对象的数组列表?

我有两个数组列表。 每个都有User类型的对象列表。

User类如下所示

public class User { private long id; private String empCode; private String firstname; private String lastname; private String email; public User( String firstname, String lastname, String empCode, String email) { super(); this.empCode = empCode; this.firstname = firstname; this.lastname = lastname; this.email = email; } // getters and setters } import java.util.ArrayList; import java.util.List; public class FindSimilarUsersWithAtLeastOneDifferentProperty { /** * @param args */ public static void main(String[] args) { // TODO Auto-generated method stub List list1 = new ArrayList(); list1.add(new User("F11", "L1", "EMP01", "u1@test.com")); list1.add(new User("F2", "L2", "EMP02", "u222@test.com")); list1.add(new User("F3", "L3", "EMP03", "u3@test.com")); list1.add(new User("F4", "L4", "EMP04", "u4@test.com")); list1.add(new User("F5", "L5", "EMP05", "u5@test.com")); list1.add(new User("F9", "L9", "EMP09", "u9@test.com")); list1.add(new User("F10", "L10", "EMP10", "u10@test.com")); List list2 = new ArrayList(); list2.add(new User("F1", "L1", "EMP01", "u1@test.com")); list2.add(new User("F2", "L2", "EMP02", "u2@test.com")); list2.add(new User("F6", "L6", "EMP06", "u6@test.com")); list2.add(new User("F7", "L7", "EMP07", "u7@test.com")); list2.add(new User("F8", "L8", "EMP08", "u8@test.com")); list2.add(new User("F9", "L9", "EMP09", "u9@test.com")); list2.add(new User("F100", "L100", "EMP10", "u100@test.com")); List resultList = new ArrayList(); // this list should contain following users // EMP01 (common in both list but differs in firstname) // EMP02 (common in both list but differs in email) // EMP10 (common in both list but differs in firstname, lastname and email) } } 

如果您看到示例代码,则这两个列表有四个用户,其代码为EMP01,EMP02,EMP09和EMP10。

因此,我们只需要比较这四个用户的属性。

如果任何用户具有至少一个不同的属性,则应将其添加到结果列表中。

请告知我该如何解决这个问题?

我想你应该做的 –

 for(User user1 : list1) { for(User user2 : list2) { if(user1.getEmpCode().equals(user2.getEmpCode())) { if(!user1.getFirstName().equals(user2.getFirstName()) || !user1.getLastName().equals(user2.getLastName()) || !user1.getEmail().equals(user2.getEmail())) { resultList.add(user1); } } } } 

User覆盖equalhashCode仅用于此目的可能没有意义。 它们应该以区域方式更有意义的方式覆盖。

User实现equals , hashcode

  @Override public boolean equals(Object obj) { if (obj == null) return false; if (!(obj instanceof User)) return false; User u = (User) obj; return this.empCode == null ? false : this.empCode .equals(u.empCode); } @Override public int hashCode() { return this.empCode == null ? 0 : this.empCode.hashCode(); } @Override public String toString() { return "Emp Code: " + this.empCode; } 

然后使用retainAll

 list2.retainAll(list1);-->EMP01, EMP02, EMP09, EMP10 

规范方法如下:

  1. 编写方法countDifferences ,计算用户之间的差异数量
  2. 对于一个列表中的每个对象,找到与其他列表对象进行比较时的最小值
  3. 报告最小值不为0的所有对象。

如果您将权重放在不同的属性上,您也可以控制它,例如ID属性中的匹配强于名称中的匹配。

更新:抱歉,误读了ID属性必须匹配的评论。

用“查找具有相同ID的对象”替换2)。 除此之外,我仍然建议计算差异的数量 。 它更灵活,因为您可以定义好的或坏匹配的阈值等。

将此方法添加到User类:

 public boolean isSimilarButNotEqual(User other) { if(!this.empCode.equals(other.empCode)) return false; return !(this.firstname + this.lastname + this.email).equals(other.firstname + other.lastname + other.email); } 

然后,在main()执行:

  for(User user1: list1){ for(User user2: list2){ if(user1.isSimilarButNotEqual(user2)){ resultList.add(user1); resultList.add(user2); } } } 

这很简单。 在User类中覆盖equal方法。 一个非常简单的实现(您可以通过使用null检查等来增强它)如下所示:

 @override public boolean equals(Object obj) { User other = (User) obj; if(this.id==other.id && this.empCode.equals(other.empCode) && this.firstname.equals(other.firstname) && this.lastname.equals(other.lastname) && this.email.equals(other.email)){ return true; }else{ return false; } } 

完成后,您可以使用:

  for(user user: list1){ if(!resultList.contains(user)){ resultList.add(user); } } for(user user: list2){ if(!resultList.contains(user)){ resultList.add(user); } } 

我用以下方法比较两个自定义ArrayList

 List allPosts = new ArrayList<>(); List noRepeatAllPosts = new ArrayList<>(); for (int i = 0; i < allPosts.size(); i++) { boolean isFound = false; for (int j = i+1; j < allPosts.size(); j++) { if (allPosts.get(i).getTitle().equals(allPosts.get(j).getTitle())) { isFound = true; break; } } if (!isFound) noRepeatAllPosts.add(allPosts.get(i)); }