Find elements in a list that are not present in another list using java 8

ε祈祈猫儿з 提交于 2021-02-07 08:13:45

问题


I have 2 lists. The requirement is to filter out elements in list1 that are not in list2 based on condition.

  Class Fighter
  {
    String name;
    String address;
  }     
  List<Fighter> pairs1 = new ArrayList();
    pairs1.add(new Fighter("a", "a"));
    pairs1.add(new Fighter("b", "a"));

    List<Fighter> pairs2 = new ArrayList();
    pairs2.add(new Fighter("a", "c"));
    pairs2.add(new Fighter("a", "d"));
    Set<Fighter> finalValues = new HashSet<>();


    finalValues = pairs1.stream().filter(firstList -> 
   pairs2.stream().noneMatch(secondList -> 
   firstList.getName().equals(secondList.getName())
            && firstList.getName().equals(secondList.getName()))).collect(Collectors.toSet());

    System.out.println(finalValues);

Expected Output : a=a, b=a

Explanation: Elements in list1 that are not in list2

The above code is not giving the expected output. Please let me know how the above stream code can be corrected to get the output


回答1:


First override the equals and hashcode methods in Fighter class.

@Override
public boolean equals(Object o) {
    if (o == this)
        return true;
    if (!(o instanceof Fighter))
        return false;
    Fighter f = (Fighter) o;
    return f.name.equals(name) && f.address.equals(address);
}

@Override
public int hashCode() {
    int result = name.hashCode();
    result = 31 * result + address.hashCode();
    return result;
}

Then create a Set from pairs2. Finally use it's contains method to get the set difference. Here's how it looks,

Set<Fighter> pairs2Set = new HashSet<>(pairs2);
Set<Fighter> setDiff = pairs1.stream()
    .filter(f -> !pairs2Set.contains(f))
    .collect(Collectors.toSet());



回答2:


You do not use address when matching inside the filter.

List<Fighter> res = pairs1.stream()
                    .filter(f -> !pairs2.stream()
                                        .anyMatch(s -> f.getName().equals(s.getName())
                                                  && f.getAddress().equals(s.getAddress())))
                   .collect(Collectors.toList());

Here filter the element of first list if contains in second list based on condition.

Better approach:

Using List's contains method

List<Fighter> res = pairs1.stream()
                            .filter(e -> !pairs2.contains(e)) 
                            .collect(Collectors.toList());

You need to override equals() method in Fighter class. contains() method you will use the equals() method to evaluate if two objects are the same.

@Override
public boolean equals(Object o) {
    if (o == this)
        return true;
    if (!(o instanceof Fighter))
        return false;
    Fighter f = (Fighter) o;
    return f.name.equals(name) && f.address.equals(address);
}

But using Set it will be more faster. See similar problem solution using Set



来源:https://stackoverflow.com/questions/57621371/find-elements-in-a-list-that-are-not-present-in-another-list-using-java-8

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!