shreya
shreya

Reputation: 183

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.

Solution1:

     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

Upvotes: 0

Views: 206

Answers (2)

Qing Zhang
Qing Zhang

Reputation: 1

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);
    }
 }

Upvotes: 0

Sumit Singh
Sumit Singh

Reputation: 15896

This is not taking Fruit name in consideration because you didn't implemented equals method.

From List boolean contains(Object o)

Returns true if this list contains the specified element. 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)).

in this last condition the one which will check based on your equals implementation.

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:

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:

//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());

Upvotes: 2

Related Questions