简体   繁体   English

如何根据内部列表的属性之一获取列表中的唯一元素

[英]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).因此,从下面的示例中,我希望在结果列表中只有 person/person3(我们删除 person2,因为它具有相同的工作名称)。 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.另一个例子:我有 3 个人在列表中,其中 2 个人有相同的工作名称。 So i want to delete second person as it might be duplicated and in result list I will have just 2 people所以我想删除第二个人,因为它可能会重复,在结果列表中我只有 2 个人

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.但它仅指迭代列表的属性,我不知道如何进入内部并基于它收集上列表的元素。

Using streams you can do that as below使用streams ,您可以执行以下操作

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

You can use anyMatch() in the filter:您可以在过滤器中使用anyMatch()

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

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

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