简体   繁体   English

在不使用流的情况下过滤 list1 中不在 list2 java 中的元素

[英]Filter elements in list1 that are not in list2 java without using streams

Have two lists有两个列表

     Class Fruit
     {
         private String name;
     }
     List<Fruit> list1 = new ArrayList<>;
     List<Fruit> list2 = new ArrayList<>;

Find elements in list1 that are not in list2 comparing by the field in Fruit - name.通过 Fruit - name 中的字段比较查找 list1 中不在 list2 中的元素。

Solution1:解决方案1:

     List list = new ArrayList<>;
     for(Fruit list : list1)
     {
          if(!list2.contains(list1)
          {
               list.add(list);
          }
     }

But this does not take into consideration the field - Name to compare.但这并没有考虑要比较的字段 - 名称。 Please suggest the solution that helps in filtering with Name field without using streams请建议有助于在不使用流的情况下使用 Name 字段进行过滤的解决方案

This is not taking Fruit name in consideration because you didn't implemented equals method.这没有考虑 Fruit 名称,因为您没有实现equals方法。

From List boolean contains(Object o)来自List boolean contains(Object o)

Returns true if this list contains the specified element.如果此列表包含指定元素,则返回 true。 More formally, returns true if and only if this list contains at least one element e such that (o==null? e==null: o.equals(e) ).更正式地说,当且仅当此列表包含至少一个满足 (o==null? e==null: o.equals(e) ) 的元素 e 时才返回 true。

in this last condition the one which will check based on your equals implementation.在最后一种情况下,将根据您的equals实施进行检查。

You have to implement equals method in you Fruit class to compare based on name Eclipse generate equals method is below you can change based on your requirement:您必须在 Fruit 类中实现equals方法才能根据name进行比较 Eclipse 生成 equals 方法如下,您可以根据需要进行更改:

public class Fruit {
    private String name;

    @Override
    public int hashCode() {
        final int prime = 31;
        int result = 1;
        result = prime * result + ((name == null) ? 0 : name.hashCode());
        return result;
    }

    @Override
    public boolean equals(Object obj) {
        if (this == obj)
            return true;
        if (obj == null)
            return false;
        if (getClass() != obj.getClass())
            return false;
        Fruit other = (Fruit) obj;
        if (name == null) {
            if (other.name != null)
                return false;
        } else if (!name.equals(other.name))
            return false;
        return true;
    } 

}

UPDATE更新
Anyway if you don't want to implement equals method you have to do bit more, here are stream code:无论如何,如果你不想实现 equals 方法,你必须做更多的事情,这里是流代码:

//It assume you have .getName() method in your Fruit class.
Predicate<Fruit> notInList2 = s -> list2.stream().noneMatch(e -> s.getName().equals(e.getName()));
List<Fruit> list3 =  list1.stream().filter(notInList2).collect(Collectors.toList());

In the case of a large amount of data, consider time complexity.在数据量很大的情况下,考虑时间复杂度。 In most cases, I will consider converting the list into a set and using the characteristics of the hash table to speed up the lookup.大多数情况下,我会考虑将列表转换为集合,利用哈希表的特性来加快查找速度。

 Set<String> set = new HashSet<>();
 for(Fruit e:list2){
    set.add(e.name);
 }
 List<Fruit> result = new ArrayList<>();
 for(Fruit e:list1){
    if(!set.contains(e.name)){
        result.add(e);
    }
 }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM