traki111
traki111

Reputation: 521

How to get unique elements in list based on one of attribute of inner list

I need to get unique elements in list based on job attribute - name - of inner list. So from below example I would like to have in result list only person/person3 (we remove person2 as it has the same job's name). I just want to have unique elements in list based on job's name.

 Person person = new Person("andri", "pik", Collections.singletonList(new Job("piotzr", 12)));
        Person person2 = new Person("kotak", "zik", Collections.singletonList(new Job("piotzr", 112)));
        Person person3 = new Person("lame", "sri", Collections.singletonList(new Job("piotra", 12)));

    public class Person {
            String name;
            String surname;
            List<Job> job;
    
    }

public class Job {

    String name;
    int pension;
}

Another example: I have 3 people in list, 2 from them have the same job's names. So i want to delete second person as it might be duplicated and in result list I will have just 2 people

I have found something like:

 private <T> Predicate<T> distinctByKey(Function<? super T, ?> keyExtractor) {
        Map<Object, Boolean> seen = new ConcurrentHashMap<>();
        return t -> seen.putIfAbsent(keyExtractor.apply(t), Boolean.TRUE) == null;
    }

but it refers only to attribute of iterated list, I do not know how to get to inner and based on it collect elements of upper list.

Upvotes: 0

Views: 409

Answers (2)

Rajan Kali
Rajan Kali

Reputation: 12953

Using streams you can do that as below

ArrayList<Person> persons = new ArrayList<>();
String requiredJobName = "";
List<Person> filteredByJob = persons.stream()
                .filter(person -> hasJobWithName(person.job, requiredJobName))
                .collect(Collectors.toList());


public boolean hasJobWithName(List<Job> jobs, String name){
    for(Job job : jobs){
        if(job.name.equals(name)){
            return true;
        }
    }
    return false;
}

Upvotes: 1

H&#252;lya
H&#252;lya

Reputation: 3433

You can use anyMatch() in the filter:

Person output = list.stream().filter(p -> p.getJob().stream().anyMatch(j -> j.getName().equals("piotra")))
        .findFirst().get();

Upvotes: 0

Related Questions