返回java中两个列表之间的差异

时间:2014-11-18 19:56:57

标签: java list object filtering

我有两个数组列表,例如

List<Date> a;
contains : 10/10/2014, 10/11/2016

List<Date> b;
contains : 10/10/2016

如何在列表ab之间进行检查,以便返回b中缺少的值?例如。 10/10/2014

12 个答案:

答案 0 :(得分:41)

您可以将它们转换为Set个集合,并对它们执行set difference操作。

像这样:

Set<Date> ad = new HashSet<Date>(a);
Set<Date> bd = new HashSet<Date>(b);
ad.removeAll(bd);

答案 1 :(得分:21)

如果您只想在b中找到缺失值,可以执行以下操作:

List toReturn = new ArrayList(a);
toReturn.removeAll(b);

return toReturn;

如果要查找列表中存在的值,可以执行两次上码。更改列表。

答案 2 :(得分:6)

您可以使用Apache Commons Collections 4.0中的CollectionUtils:

this.setState

答案 3 :(得分:5)

您可以使用Java 8 Stream库过滤器

List<String> aList = Arrays.asList("l","e","t","'","s");
List<String> bList = Arrays.asList("g","o","e","s","t");

List<String> result = aList.stream().filter(aObject -> {
     return bList.contains(aObject);
 }).collect(Collectors.toList());

//or more reduced without curly braces and return
List<String> result2 = aList.stream().filter(aObject -> 
!bList.contains(aObject)).collect(Collectors.toList());

System.out.println(result);

结果:

[e, t, s]

答案 4 :(得分:1)

我正在寻找一个不同的问题并遇到了这个问题,因此我会将解决方案添加到相关问题中:比较两个地图。

    // make a copy of the data
    Map<String,String> a = new HashMap<String,String>(actual);
    Map<String,String> e = new HashMap<String,String>(expected);
    // check *every* expected value
    for(Map.Entry<String, String> val : e.entrySet()){
        // check for presence
        if(!a.containsKey(val.getKey())){
            System.out.println(String.format("Did not find expected value: %s", val.getKey()));
        }
        // check for equality
        else{
            if(0 != a.get(val.getKey()).compareTo(val.getValue())){
                System.out.println(String.format("Value does not match expected: %s", val.getValue()));
            }
            // we have found the item, so remove it 
            // from future consideration. While it 
            // doesn't affect Java Maps, other types of sets
            // may contain duplicates, this will flag those
            // duplicates. 
            a.remove(val.getKey());
        }
    }
    // check to see that we did not receive extra values
    for(Map.Entry<String,String> val : a.entrySet()){
        System.out.println(String.format("Found unexpected value: %s", val.getKey()));
    }

它的工作原理与其他解决方案相同,但不仅要比较存在的值,还要包含相同的值。大多数情况下,我在会计软件中使用它来比较来自两个来源的数据(员工和经理输入的值匹配;客户和公司交易匹配;等等)

答案 5 :(得分:1)

这是解决此问题的通用方法。

public <T> List<T> difference(List<T> first, List<T> second) {
    List<T> toReturn = new ArrayList<>(first);
    toReturn.removeAll(second);
    return toReturn;
}

答案 6 :(得分:1)

使用 Stream API,您可以执行以下操作:

List<String> aWithoutB = a.stream()
    .filter(element -> !b.contains(element))
    .collect(Collectors.toList());

List<String> bWithoutA = b.stream()
    .filter(element -> !a.contains(element))
    .collect(Collectors.toList());

答案 7 :(得分:0)

您可以在underscore-java库中调用U.difference(lists)方法。我是该项目的维护者。 Live example

import com.github.underscore.U;
import java.util.Arrays;
import java.util.List;

public class Main {
    public static void main(String[] args) {
        List<Integer> list1 = Arrays.asList(1, 2, 3);
        List<Integer> list2 = Arrays.asList(1, 2);
        List<Integer> list3 = U.difference(list1, list2);
        System.out.println(list3);
        // [3]
    }
}

答案 8 :(得分:0)

我看上去很相似,但我想在两个列表中都有所不同(两个列表之间的元素不常见):

让我说:

List<String> oldKeys = Arrays.asList("key0","key1","key2","key5");
List<String> newKeys = Arrays.asList("key0","key2","key5", "key6");

我想知道已添加了哪个键,并删除了哪个键,即我想获取(key1,key6)

使用 org.apache.commons.collections.CollectionUtils

List<String> list = new ArrayList<>(CollectionUtils.disjunction(newKeys, oldKeys));

结果

[key1,key6]

答案 9 :(得分:0)

首先将列表转换为集合。

// create an empty set 
Set<T> set = new HashSet<>(); 

// Add each element of list into the set 
for (T t : list) 
    set.add(t); 

您可以使用Sets.difference(Set1, Set2),它返回Set1中存在的其他项目。
您可以使用Sets.difference(Set2, Set1),它返回Set2中存在的其他项目。

答案 10 :(得分:0)

List<String> l1 = new ArrayList<String>();
l1.add("apple");
l1.add("orange");
l1.add("banana");
l1.add("strawberry");

List<String> l2 = new ArrayList<String>();
l2.add("apple");
l2.add("orange");

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

for (String A: l2) {
  if (l1.contains(A))
    l1.remove(A);
}

System.out.println("output");
System.out.println(l1);

输出:

[apple, orange, banana, strawberry]
[apple, orange]
output
[banana, strawberry]

答案 11 :(得分:0)

Set 是下面的映射,我能够获得超过一百万个条目的两个列表之间的差异,每个条目将其包装在一个 HashSet 中,这是一个简单的代码。

private List<String>notPresentMethod(final List<String>left,final List<String>right){
    final Set<String>setIsFaster = new HashSet<>(right);
    return left.stream()
            .filter(((Predicate<String>)setIsFaster::contains).negate())
            .collect(Collectors.toList());
}

仅使用列表花费了一个多小时并且没有完成。使用此示例只需几秒钟。