比较两个ArrayLists以获取唯一值和重复值

时间:2012-12-05 07:51:14

标签: java

我显示了两个ArrayLists - pinklistnormallist。我正在比较它们并从两者中找到唯一和重复的值,如下面的代码所示:

List<String> pinklist = t2.getList();
List<String> normallist = t.getList();
ArrayList<String> duplicatevalues = new ArrayList<String>();
ArrayList<String> uniquevalues = new ArrayList<String>();

for (String finalval : pinklist) {
    if (pinklist.contains(normallist)) {
        duplicatevalues.add(finalval);
    } else if (!normallist.contains(pinklist)) {
        uniquevalues.add(finalval);
    }
}

我正确地获得了duplicateValues,但我没有得到唯一的值。

7 个答案:

答案 0 :(得分:15)

您在条件中忽略了finalval,而是询问一个列表是否包含其他列表

你可以这样做:

// Variable names edited for readability
for (String item : pinkList) {
    if (normalList.contains(item)) {
        duplicateList.add(item);
    } else {
        uniqueList.add(item);
    }
}

我不会真的称这些“独特”或“重复”的项目 - 这些通常是关于一个集合中的项目 。这只是测试一个列表中的每个项目是否在另一个列表中。在这种情况下,它更像是“现有的”和“新的”,我会说。

请注意,当您以基于集合的方式处理这些内容时,我建议使用诸如HashSet<E>之类的集合实现而不是列表。 Sets中的Guava类提供了处理集合的有用方法。

答案 1 :(得分:13)

这应该做:

List<String> pinklist = t2.getList();
List<String> normallist = t.getList();

ArrayList<String> duplicates = new ArrayList<String>(normallist);
dublicates.retainAll(pinklist);

ArrayList<String> uniques = new ArrayList<String>(normallist);
uniques.removeAll(pinklist);  

阐释:

  • 每个List都可以将另一个列表作为构造函数参数,并复制它的值。

  • retainAll(list2)将删除list2中不存在的所有条目。

  • removeAll(list2)将删除list2中确实存在的所有条目。

  • 我们不想删除/保留原始列表,因为这会修改它,所以我们在构造函数中复制它们。

答案 2 :(得分:0)

这样做 -

for (String finalval : pinklist)
{   
    if(normallist.contains(finalval))
    {
        // finalval is both in pinklist and in
        // normallist. Add it as a duplicate.
        duplicatevalues.add(finalval);  // this will get you the duplicate values
    }
    else {
        // finalval is in pinklist but not in
        // normallist. Add it as unique.
        uniquevalues.add(finalval);    // this will get you the values which are in 
                                       // pinklist but not in normallist
    }
}

// This will give you the values which are
// in normallist but not in pinklist.
for(String value : normallist) {
    if(!pinklist.contains(value)) {
        uniquevalues.add(value);
    }
}

答案 3 :(得分:0)

使用Java8 Stream API,我们可以过滤列表并获得预期的结果。

List<String> listOne = // Your list1
List<String> listTwo = // Your list2

List<String> uniqueElementsFromBothList = new ArrayList<>();
List<String> commonElementsFromBothList = new ArrayList<>();

// Duplicate/Common elements from both lists
commonElementsFromBothList.addAll(
         listOne.stream()
        .filter(str -> listTwo.contains(str))
        .collect(Collectors.toList()));

// Unique element from listOne
uniqueElementsFromBothList.addAll(
         listOne.stream()
        .filter(str -> !listTwo.contains(str))
        .collect(Collectors.toList())); 

// Unique element from listOne and listTwo 
// Here adding unique elements of listTwo in existing unique elements list (i.e. unique from listOne)
uniqueElementsFromBothList.addAll(
         listTwo.stream()
        .filter(str -> !listOne.contains(str))
        .collect(Collectors.toList()));

答案 4 :(得分:0)

尝试使用ListUtils https://commons.apache.org/proper/commons-collections/apidocs/org/apache/commons/collections4/ListUtils.html

要获取重复值,请使用ListUtils.intersection(list1,list2) 要获取唯一值,可以使用ListUtils.sum(list1,list2),然后减去重复列表

答案 5 :(得分:0)

这是我解决问题的方法。 我们可以创建一个包含两个列表中的元素的集合。

对于唯一元素,使用Stream API,我们可以根据返回contains方法的XOR的谓词过滤掉元素。它只会对true ^ falsefalse ^ true返回true,确保其中只有一个包含它。

对于不同的元素,只需将XOR更改为&&,它将检查两个列表是否都包含对象。

代码:

private static void uniqueAndDuplicateElements(List<String> a, List<String> b) {
    Set<String> containsAll = new HashSet<String>();
    containsAll.addAll(a);
    containsAll.addAll(b);

    List<String> uniquevalues = containsAll.stream()
                                .filter(str -> a.contains(str) ^ b.contains(str))
                                .collect(Collectors.toList());
        
    List<String> duplicatevalues = containsAll.stream()
                                   .filter(str -> a.contains(str) && b.contains(str))
                                   .collect(Collectors.toList());

    System.out.println("Unique elements from both lists: " + uniquevalues);
    System.out.println("Elements present in both lists: " + duplicatevalues);
}

答案 6 :(得分:-1)

为什么要将整个列表传递给contains方法?你应该通过finalval