我显示了两个ArrayLists
- pinklist
和normallist
。我正在比较它们并从两者中找到唯一和重复的值,如下面的代码所示:
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
,但我没有得到唯一的值。
答案 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 ^ false
或false ^ 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
。