Home > Net >  Check if items in List<String> match with String attribute in list of objects
Check if items in List<String> match with String attribute in list of objects

Time:04-11

Let's say I have a list of names:

List<String> names = new ArrayList<>();
names.add("Paul");
names.add("Jeff");
names.add("Anna");

On the other hand, I have a list of people:

List<Person> people = new ArrayList<>();
people.add( new Person("Paul", 30) );
people.add( new Person("Jeff", 50) );

Person has name and age attributes. From the first list of names, I need to know what names are not present as names in the list of people. This is my attempt:

    List<String> namesNotPresent = new ArrayList<>();
    for (String name : names) {
        boolean nameNotPresent = people.stream()
                .noneMatch(p -> name.equals(p.getName()));
        if (nameNotPresent) {
            namesNotPresent.add(name);
        }
    }

I wonder if there is a better approach, a more functional one, and I also wonder if the list of people should be ordered?

This is working for me though. I don't expect the list of names and people to be a huge list, there might be exceptions where they could have around 1000 items though.

CodePudding user response:

A better approach would be to use some kind of Map, such as a HashMap<String,Person> to store the Person objects, indexed by name. That way, you're not iterating through the list to find each name.

Map<String,Person> personsByName = new HashMap<>();
personsByName.put( "Paul", new Person("Paul", 30));
personsByName.put( "Jeff", new Person("Jeff", 50));

names.removeIf(name->personsByName.contains(name));

Note that this removes things from names - if you want to keep this list, make a copy first.

CodePudding user response:

You don't need to stream over your people list for each name in your names list.

List<String> namesNotPresent = new ArrayList<>(names);
namesNotPresent.removeAll(people.stream().map(Person::getName).collect(Collectors.toList()));

CodePudding user response:

public List<String> findNameNotPresent(List<String> names, List<Person> people) {
    List<String> result = new ArrayList<>(names);
    people.stream()
        .map(Person::getName)
        .forEach(result::remove);
    return result;
}

CodePudding user response:

You are looking for a more functional approach. Functional means side effects must be avoided. This is a functional approach:

List<String> pnames = people.stream().map(Person::getName).toList();
List<String> namesNotPresent = names.stream().filter(n -> !pnames.contains(n)).toList();

Prior to Java 17 you would have to substitute toList() by collect(Collectors.toList()).

  •  Tags:  
  • java
  • Related