1

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.

4 Answers 4

1

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.

Sign up to request clarification or add additional context in comments.

Comments

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

Comments

0

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

Comments

0

You are looking for a more functional approach. Functional means side effects must be avoided. Do not update a collection after ist has been created. E. g. do not use .foreach or .removeIf. Avoid the classical foreach loop. 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()).

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.