【问题标题】:Java Remove common elements between 2 ArrayList of objectsJava删除对象的2个ArrayList之间的公共元素
【发布时间】:2012-07-25 09:40:01
【问题描述】:

我有一个 Java 类

class Students{
    private String fName;   
    private String lName;
    private String uName;


    public Students(String fName, String lName, String uName) {
            this.fName = fName;
            this.lName = lName;
            this.uName = uName;
     }      

    public String getuName() {
        return uName;
    }
    public void setuName(String uName) {
        this.uName = uName;
    }
    public String getfName() {
        return fName;
    }
    public void setfName(String fName) {
        this.fName = fName;
    }
    public String getlName() {
        return lName;
    }
    public void setlName(String lName) {
        this.lName = lName;
    }

}

我也这样称呼它

public class TestClass {
public static void main(String[] args) {

    Students students1 = new Students("xyz","abc","xyzAbc");
    Students students2 = new Students("poi","son","poison");
    Students students3 = new Students("yog","jos","yogjos");

    Students students4 = new Students("xyz","abc","xyzAbc");
    Students students5 = new Students("pon","son","xyzAbc");
    Students students6 = new Students("yog","jos","someotherUName");
    Students students7 = new Students("yog","jos","someotherUName2");

    List studentList1 = new ArrayList();
    List studentList2 = new ArrayList();

    studentList1.add(students1);
    studentList1.add(students2);
    studentList1.add(students3);

    studentList2.add(students4);
    studentList2.add(students5);
    studentList2.add(students6);
}
}

现在我想要一个仅包含唯一“uName”值的过滤列表。 因此,我想要比较每个列表的“uName”字段并删除常见的字段。

最后我想要 2 个用于 studentList1 和 studentList2 的过滤列表。

我阅读了 removeAll 方法,但它似乎适用于整数/字符串数据列表,而不适用于对象列表(如我的情况)。

请提出建议。

【问题讨论】:

标签: java arraylist


【解决方案1】:

您可以设置您的列表,然后(如果需要)将其取回:

new ArrayList(new HashSet<String>(list)) 创建的列表仅包含源列表中的唯一元素。

【讨论】:

    【解决方案2】:

    1.如果您希望每个列表具有唯一 uName 值,那么您可以使用java.util.Collection 中的TreeSet 以及接口 Comparator 来自 java.util.Comparator

    2.如果您想要合并两个列表并拥有唯一的 uName,请合并两个列表,然后使用 TreeSetComparator。 p>

    3.Comparator 提供了以多种方式进行比较的灵活性...

    【讨论】:

    • 非常感谢...您能否提供第二个选项的示例(仅将两个列表与唯一的 uName 合并)?
    • 首先合并两个列表......然后将其插入到使用比较器的 TreeSet 中,该比较器将学生与他们的 uName 进行比较......请参阅这些关于带有比较器的 TreeSet 的示例。 .javaexamples4u.com/2009/04/treeset-comparator.html ...我现在在上班...等我回到家,我会尽量回复
    【解决方案3】:

    如果List 中的对象正确实现equals(),您仍然可以使用removeAll

    AbstractCollection,这是大多数List 实现的基础(包括ArrayList)在its implementation of removeAll 中使用contains()ArrayListimplementation of contains 依赖于indexOf(),最后使用equals()

    您可以在 Student 类中实现 equals() 以指定 Student 等于另一个,如果且仅它们的 uName 字段相等。

    请注意equals 具有相关的语义(参见其javadoc),在选择如何实现它时应该小心。考虑两个学生实例在uNames 相等时是否真的代表同一个学生。在我看来,这听起来像是一个非常具体的要求,即如何整理这些东西,并且不应该影响类的语义。

    使用@AlexR@KumarVivekMitra 的方法会更好。

    【讨论】:

    • 你能提供一个相同的例子吗?同样在我的情况下,我想要学生对象的 ivars 之间的比较。
    【解决方案4】:

    首先,您应该输入您的列表:

    List<Students> studentList1 = new ArrayList<Students>();
    

    其次,在您的Students 类上实现hashCode()equals(),它们都委托给uName

    public boolean equals(Object o) {
        return o instanceof Students && ((Students)o).uName.equals(uName);
    }
    
    public int hashCode() {
        return uName.hashCode();
    }
    

    现在removeAll() 可以正常工作了。


    另一种选择是使用Set,它只允许由equals() 方法确定的唯一值。如果您将上述方法添加到您的类中,您可以这样做:

    Set<Students> students = new HashSet<Students>();
    

    然后添加您喜欢的内容,其中只会有唯一的uName 学生。


    顺便说一句,你应该用单数命名你的班级 - 即Student而不是Students

    【讨论】:

    • 非常感谢您的帮助...我该如何调用 removeAll() 方法?
    • 都在javadoc里,不过就是list1.removeAll(list2);
    【解决方案5】:

    您也可以尝试使用 apache commons CollectionUtils.disjunction。 (链接:http://commons.apache.org/collections/apidocs/org/apache/commons/collections/CollectionUtils.html#disjunction(java.util.Collection,java.util.Collection))

    【讨论】:

      【解决方案6】:

      你的Student类应该重写方法hashcodeequals,所以你的对象可以是唯一的名称。 Here 你可以阅读如何做到这一点。

      还请注意,在某个集合中维护的所有对象都应覆盖这些方法,因此您始终知道它们是如何进行比较的。

      下一步你可以使用removeAll 方法或带有Set的解决方案,这取决于你:-)

      树立榜样

      List&lt;String&gt; list = new ArrayList(new HashSet&lt;String&gt;(studentList)); // 这是你的唯一列表

      或者您可以使用自定义比较器而不是覆盖哈希码和等号,但如果您希望您的学生始终是唯一的,您应该覆盖它们

      【讨论】:

        【解决方案7】:

        一个完整的工作解决方案可能如下。

        Class Student{
        
        
        .....
        ......
        .....
        
           public boolean equals(Object o) {
               return o instanceof Students && ((Students)o).uName.equals(uName);
           }
        
           public int hashCode() {
               return uName.hashCode();
           }
        
        
        
        
        }
        
        
        Set studentList1 = new hashSet();
        Set studentList2 = new hashSet();
        

        将您的元素放入这些集合中。

        此外,如果您想要两个 Set 中的唯一不匹配元素。然后写如下。

        studentList1.removeAll(studentList2 );
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2021-03-30
          • 1970-01-01
          • 2023-04-07
          • 1970-01-01
          • 1970-01-01
          • 2021-11-13
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多