【问题标题】:Compare two arraylist contents and store unmatched contents in another arraylist比较两个arraylist内容并将不匹配的内容存储在另一个arraylist中
【发布时间】:2012-11-22 09:33:48
【问题描述】:

我想比较两个数组列表的内容。

我以这种方式将对象存储在其中。

对于数组列表 1:

Employee e1=new Employee();

e1.setID("1");
e1.setID("2");

ArrayList<Employee>list1 = new ArrayList<Employee>(); 

if(e1!=null){
    list1.add(e1);
}

对于数组列表 2:

Employee e2=new Employee();

e2.setID("1");
e2.setID("2");
e2.setID("4");

ArrayList<Employee>list2 = new ArrayList<Employee>(); 

if(e2!=null){
    list2.add(e2);
}

现在我正在尝试以这种方式比较上面的arraylist内容

ArrayList<Employee>unmatchedList = new ArrayList<Employee>();   

for (Employee l1 : list1){                               
    if(!list2.contains(l1.getID())){    
        System.out.println("list2 does not contains this ID"+l1.getID());   
        Employee e3=new Employee();          
        e3.setID(l1.getID());

        if(unmatchedList==null){            
        unmatchedList=new ArrayList<Employee>();            
        unmatchedList.add(e3);          
        }

        if(unmatchedList!=null){                            
            unmatchedList.add(e3);              
        }                       
    }
}

但我没有将正确的 unmatchedList 内容设置为“4”。 我得到 unmatchedList 为“1”和“2”,这是错误的。 那么如何才能仅在“unmatchedList”中获得不匹配的内容

【问题讨论】:

  • 您可能希望使用Set 而不是ArrayList。在那里很容易进行比较。虽然 Set 不会让您存储重复值。
  • 请提供Employee类的代码。
  • @svz 诚然,重复的员工听起来有点怪异——或者可能是双胞胎?我的意思是我的雇主很想复制我们,但他从来没有成功过......

标签: java arraylist compare


【解决方案1】:

如果你的班级Employee 是这样定义的:

public class Employee {

private int id;

public Employee(int id){
    this.id = id;
}

public int getId() {
    return id;
}

@Override
public String toString() {
    return "Id : " + this.id;
}

@Override
public boolean equals(Object obj) {
    return (obj instanceof Employee) && this.id == ((Employee)obj).getId();
}

在 Main 方法中,您可以像这样检索不匹配的内容:

 public static void main( String[] args )
{
   List<Employee> l1 = new ArrayList<Employee>();
   l1.add(new Employee(1));
   l1.add(new Employee(2));
   l1.add(new Employee(3));
   l1.add(new Employee(4));
   l1.add(new Employee(5));


   List<Employee> l2 = new ArrayList<Employee>();
   l2.add(new Employee(4));
   l2.add(new Employee(5));


   l1.removeAll(l2);
   System.out.println(l1);

}

这将打印:[Id : 1, Id : 2, Id : 3]

请注意,对于这项工作,您必须重写 equals 方法。

【讨论】:

  • 注意这实际上改变了l1的内容。在 OP 的问题中,元素存储在第三个列表中。我在回答中给出了一个简短的示例,它只是另一个复制列表的构造函数调用。
  • 您的解决方案非常适合我。但是如果我想为多个变量实现它,我应该如何覆盖方法。例如:目前我们只有一个变量 private int id;但是如果我有其他变量,例如 private int id1, id2,id3 ;那么我怎样才能覆盖他们的equals方法呢?
  • 你应该重写equals方法。 equals 是 Object 中定义的一种方法,用于比较对象的内容。提供的 equals 方法只是示例。你必须定义你的 equals 方法,这样他才能满足你的需要。
  • 是的,我在 Employee 类中为 id1 覆盖了 equals 方法,但是如何在 Employee 类中为 id2、id3 等覆盖 equals 方法。
  • 你能说得更具体点吗?如果你想覆盖equals,这里是一个例子artima.com/lejava/articles/equality.html
【解决方案2】:

问题是这段代码:-

if(!list2.contains(l1.getID())){

您的list2ArrayList&lt;Employee&gt;,您正在检查l1.getId() 的收容。因此,您的 if 条件将始终为真。


您应该在 Employee 类中重写 equalshashCode 方法,然后使用:-

if(!list2.contains(l1))

用于检查list2是否包含员工l1


为什么在将id 添加到列表之前将其设置为 3 次。它不会添加所有三个 id,而只会添加一个 Employee,并为 id 设置最后一个值。你需要纠正它:-

e2.setID("1");
e2.setID("2");
e2.setID("4");

list.add(e2);  // Will only add one Employee with id = 4

【讨论】:

  • 那么我应该如何通过比较两个列表来检查以获得不匹配的内容?
  • @PravinG.. 另请注意,要获得不匹配的列表,您需要从两个列表中进行检查。先检查list1的elem是否在list2中,然后反之。
【解决方案3】:

为您的员工添加一个equals 方法,通过他们的ID 比较他们,复制list2 并调用removeAll

List<Employee> list1 = ...;
List<Employee> list2 = ...;
List<Employee> unmatchedList = new ArrayList<Employee>(list2);
unmatchedList.removeAll(list1);

有关完整示例,请参阅@Dimitri 的回答。

【讨论】:

    【解决方案4】:

    我认为你应该在你的场景中使用Set。可能这个例子会对你有所帮助。

    Employee

    package com.yourcomp;
    
    /**
     * <br>
     * <div style="width:600px;text-align:justify;">
     *
     * TODO: Class comment.
     *
     * </div>
     * <br>
     *
     */
    public class Employee {
    
        private int id;
    
        /**
         * Constructor for Employee. <tt></tt>
         */
        public Employee() {
            this(-1);
        }
    
        /**
         * Constructor for Employee. <tt></tt>
         */
        public Employee(int id) {
            this.id = id;
        }
    
        /**
         * Gets the id.
         * 
         * @return <tt> the id.</tt>
         */
        public int getId() {
            return id;
        }
    
        /**
         * Sets the id.
         *
         * @param id <tt> the id to set.</tt>
         */
        public void setId(int id) {
            this.id = id;
        }
    
        @Override
        public boolean equals(Object obj) {
            return this.id == ((Employee)obj).id;
        }
    
        /* (non-Javadoc)
         * @see java.lang.Object#toString()
         */
        @Override
        public String toString() {
            return "Employee [id=" + id + "]";
        }
    
        /* (non-Javadoc)
         * @see java.lang.Object#hashCode()
         */
        @Override
        public int hashCode() {
            // TODO Auto-generated method stub
            return new Integer(id).hashCode();
        }
    
    
    
    }
    

    TestEmployee 类:

    package com.yourcomp;
    
    import java.util.HashSet;
    import java.util.Set;
    
    /**
     * <br>
     * <div style="width:600px;text-align:justify;">
     *
     * TODO: Class comment.
     *
     * </div>
     * <br>
     * 
     */
    public class TestEmployee {
    
        public static void main(String[] args) {
            // creating the first set with employees having ID's 1 to 5
            Set<Employee> set1 = new HashSet<Employee>();
            for(int i=1;i<5;i++) 
                set1.add(new Employee(i));
    
            System.out.println(set1); // printing it
    
            // creating the first set with employees having ID's 3 to 8.
            // note that now you have two employees with same ID, 3 & 4
            Set<Employee> set2 = new HashSet<Employee>();
            for(int i=3;i<8;i++)
                set2.add(new Employee(i));
    
            System.out.println(set2);// printing the second set
    
            // creates a final set to contain all elements from above two sets without duplicates
            Set<Employee> finalSet = new HashSet<Employee>();
            for(Employee employee:set1)
                finalSet.add(employee); // adds first set content
    
    
            for(Employee employee:set2)
                finalSet.add(employee); // adds second set content. If any duplicates found, it will be overwritten
    
            System.out.println(finalSet); // prints the final set
    
    
    
        }
    }
    

    和输出

    [Employee [id=1], Employee [id=2], Employee [id=3], Employee [id=4]]
    [Employee [id=3], Employee [id=4], Employee [id=5], Employee [id=6], Employee [id=7]]
    [Employee [id=1], Employee [id=2], Employee [id=3], Employee [id=4], Employee [id=5], Employee [id=6], Employee [id=7]]
    

    【讨论】:

      【解决方案5】:

      我也会推荐一个 Set 来做差异,如果你可以使用 Sets 那么我会使用 Guava-Sets 的差异方法: http://google-collections.googlecode.com/svn/trunk/javadoc/com/google/common/collect/Sets.html#difference%28java.util.Set,%20java.util.Set%29

      【讨论】:

        猜你喜欢
        • 2011-03-27
        • 1970-01-01
        • 2016-01-23
        • 2014-06-15
        • 1970-01-01
        • 1970-01-01
        • 2015-04-19
        • 2021-03-11
        相关资源
        最近更新 更多