2012-10-12 35 views
1

我有两个数组列表。每个都有用户类型的对象列表。如何比较在Java中至少有一个属性不同的类似对象的两个数组列表?

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<User> list1 = new ArrayList<User>(); 

     list1.add(new User("F11", "L1", "EMP01", "[email protected]")); 
     list1.add(new User("F2", "L2", "EMP02", "[email protected]")); 
     list1.add(new User("F3", "L3", "EMP03", "[email protected]")); 
     list1.add(new User("F4", "L4", "EMP04", "[email protected]")); 
     list1.add(new User("F5", "L5", "EMP05", "[email protected]")); 
     list1.add(new User("F9", "L9", "EMP09", "[email protected]")); 
     list1.add(new User("F10", "L10", "EMP10", "[email protected]")); 

     List<User> list2 = new ArrayList<User>(); 

     list2.add(new User("F1", "L1", "EMP01", "[email protected]")); 
     list2.add(new User("F2", "L2", "EMP02", "[email protected]")); 
     list2.add(new User("F6", "L6", "EMP06", "[email protected]")); 
     list2.add(new User("F7", "L7", "EMP07", "[email protected]")); 
     list2.add(new User("F8", "L8", "EMP08", "[email protected]")); 
     list2.add(new User("F9", "L9", "EMP09", "[email protected]")); 
     list2.add(new User("F100", "L100", "EMP10", "[email protected]")); 

     List<User> resultList = new ArrayList<User>(); 
     // 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) 


    } 

} 

如果你看到示例代码,两个列表有四个用户EMP代码EMP01,EMP02,EMP09和EMP10常见。

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

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

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

+0

resutList包含两个相似的用户吗? –

+0

@Bhesh Gurung。不只是列表中的用户1. – ashishjmeshram

+0

empcode的情况如何,他们需要匹配吗? –

回答

1

我想这个你应该做的 -

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只服务于这个目的。他们应该以更有意义的方式被覆盖。

+0

覆盖equals和hashcode,甚至你正在建议的工作。我也同意这样的事实:'用户重写equal和hashCode只是为了达到这个目的可能没有意义。但是,如果list1和list2像每个列表中的1000对象一样大。如果我比较十个属性,它会影响性能。 – ashishjmeshram

+0

无论您选择什么,都不会发生迭代。表现明智,他们应该几乎相同。 –

1

这很简单。在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); 
    } 
} 
5

User

实施 equalshashcode
@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

+1 for'retainAll' –

+0

您并未比较所有属性。它不应该是确切的副本。 –

+0

如果EmpId是商业关键并且保证唯一性,那么我不必这样做。 –

2

的规范做法如下:

  1. 写方法countDifferences计数的用户之间的差异数量
  2. 对于一个列表中的每个对象,相比其他名单时,发现最低对象
  3. 报告中的所有对象,其中最小的是不为0

如果把权重的DIF不同的属性,你也可以控制例如ID属性中的匹配比名称中的匹配更强。

更新:对不起,您的评论误认为ID属性必须与匹配。

用“查找具有相同ID的对象”代替2)。除此之外,我仍然推荐计算差异数。它更灵活,因为您可以定义好或不好比赛的门槛等。

2

此方法添加到您的用户等级:

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);     
      } 
     } 
    } 
0

我用下面的办法比较两个自定义ArrayList

List<SinglePostData> allPosts = new ArrayList<>(); 
List<SinglePostData> 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)); 
} 
相关问题