1

I have a user defined object called Employee like below and have two different lists which contains the Employee objects.

In the two different lists I need to findout unique object based on the name field in the object. Final list should contain only one object which the name is c.

Please suggest me how to do it using java 8?

import java.util.ArrayList;
import java.util.List;

class Employee{
    private String name;
    private String age;
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public String getAge() {
        return age;
    }
    public void setAge(String age) {
        this.age = age;
    }   
}


public class UniqueObjects {

    public static void main(String[] args) {
        List<Employee> empOneList= new ArrayList<Employee>();
        List<Employee> empTwoList= new ArrayList<Employee>();

        Employee empOne= new Employee();        
        empOne.setName("a");
        empOne.setAge("23");
        empOneList.add(empOne);

        Employee emptwo= new Employee();        
        emptwo.setName("b");
        emptwo.setAge("24");
        empOneList.add(emptwo);

        Employee em= new Employee();
        em.setName("a");
        em.setAge("23");
        empTwoList.add(em);

        Employee emp1= new Employee();
        emp1.setName("d");
        emp1.setAge("24");
        empTwoList.add(emp1);    
    }
}
5
  • Why should the final list have name c, when neither of the two starting lists have this name? Commented Nov 22, 2017 at 6:00
  • @TimBiegeleisen i understood it that way that the name of the object he's searching is c and not the list Commented Nov 22, 2017 at 6:17
  • In the above example the unique list should contain only one Employee object. If we have more than one unique elements with respect to the name field the final list should contain the list of Employee objects aswell Commented Nov 22, 2017 at 7:08
  • @Raju, can you add what the result should llok like in the example you give in your code to clarigy what you are trying to achieve? Should the result contain employees "b" and "d"? Commented Nov 23, 2017 at 9:53
  • Two different employees can have the same name. Joe, 35 is different from Joe 20. But then if it's a big company, you might have two Joe who are 20. Commented Dec 20, 2021 at 19:05

3 Answers 3

2

I think what your asking is how to find the single employee with a given name in either of two lists. If that's the case then the simplest thing is to just stream the two lists and filter for the unique employee:

Optional<Employee> employee = Stream.concat(list1.stream(), list2.stream())
    .filter(e -> e.getName().equals(name)).findAny();

If you want objects from both lists that have the name, then:

List<Employee> employees = Stream.concat(list1.stream(), list2.stream))
    .filter(e -> e.getName().equals(name)).collect(Collectors.toList());
Sign up to request clarification or add additional context in comments.

2 Comments

Hi , Thanks for the answer, I need the list of objects which should not have the same name.
@Raju I'm confused. In your comment you say you want "the list of object which should not have the same name" but in your question you say "list should contain only one object which the name is c". What exactly is your objective?
0

To findout unique object based on the name field you can use following code:

Map<String, List<Employee>> employeeMap = Stream.concat(empOneList.stream(), empTwoList.stream())
                .collect(Collectors.groupingBy(Employee::getName, Collectors.toList()));
  1. Using Guava

    Collection<List<Employee>> employeesWithUniqueName =
            Maps.filterValues(employeeMap, empList -> empList.size() == 1).values();
    
  2. Using Stream API

    Collection<Employee> employeesWithUniqueName =
            employeeMap.values().stream().filter(empList -> empList.size() == 1)
                    .flatMap(List::stream)
                    .collect(Collectors.toList());
    

Comments

0

If I understand your question correctly, you are looking for the elements that only appear in one of the lists, but not in both. This is called the disjunctive union. There is a very easy way to retrieve it using Collection.removeAll():

public static <T> Set<T> getDisjunctiveUnion(Set<T> set1, Set<T> set2)
{
    Collection<T> copy1 = new HashSet<>(set1);
    Collection<T> copy2 = new HashSet<>(set2);

    copy1.removeAll(set2);
    copy2.removeAll(set1);

    copy1.addAll(copy2);
    return copy1;
}

Note that this requires equals and hashCode to be implemented for Employee based on name (your IDE will do this for you):

@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;
    Employee other = (Employee) obj;
    if (name == null && other.name != null) return false;
    else if (!name.equals(other.name)) return false;
    return true;
}

If you do not want to implement those methods, you can use the new method Collection.removeIf():

copy1.removeIf(emp1 -> set2.stream().anyMatch(emp2 -> emp2.getName().equals(emp1.getName())));
copy2.removeIf(emp2 -> set1.stream().anyMatch(emp1 -> emp1.getName().equals(emp2.getName())));

Or, instead of copy/remove you use stream to filter the sets (be careful to use noneMatch instead of anyMatch):

Collection<Employee> disjunctiveUnion = new HashSet<>();
set1.stream()
    .filter(emp1 -> set2.stream().noneMatch(emp2 -> emp2.getName().equals(emp1.getName())))
    .forEach(disjunctiveUnion::add);
set2.stream()
    .filter(emp2 -> set1.stream().noneMatch(emp1 -> emp1.getName().equals(emp2.getName())))
    .forEach(disjunctiveUnion::add);
return disjunctiveUnion;

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.