0

I have an arraylist of objects which has a field "name" and I have a list of names. I have to select all the objects which consist of any of the name from the list. How can I achieve this in java most efficiently. Any code snippet will be highly appreciated.

Example:

Let the class name be A

A consists of fields such as id, name, subject etc.

So let's assume I have a list
List<A> objectsA
whose length let's say is 10. In this list, the name field consists of various names for eg alpha, beta, gama, delta etc etc.

So suppose I have a second list

List<String> namesList = List.of("alpha","beta");

So I want to select only those objects from objectsA list whose name fields consist of the names from namesList i.e. I want to select only those objects whose name fields consists of "alpha" or "beta".

6
  • English is a terrible way to write Java code. Post some code. Show us something. Because I want to help you. But I have no idea what you are asking. Commented Sep 5, 2021 at 10:49
  • 1
    Okay sorry let me add some code Commented Sep 5, 2021 at 10:49
  • @ElliottFrisch have a look now. Commented Sep 5, 2021 at 10:59
  • 1
    You're welcome. You seem to be a beginner on StackOverflow, we have to give you some time to learn. Commented Sep 5, 2021 at 11:16
  • 1
    By the way, List.of is available since Java 9: docs.oracle.com/en/java/javase/11/docs/api/java.base/java/util/… Commented Sep 5, 2021 at 11:20

2 Answers 2

2
final ArrayList<MyNamedObject> namedObjectList = ...;
final List<String> nameList = ...;

Use

namedObjectList.stream()
   .filter((final MyNamedObject o) -> nameList.stream().anyMatch((final String name) -> Objects.equals(name, o.getName())))
   .collect(Collectors.toList());

If there are some duplicate values in the name list, either keep the list but use .distinct():

namedObjectList.stream()
    .filter((final MyNamedObject o) -> nameList.stream().distinct().anyMatch((final String name) -> Objects.equals(name, o.getName())))
    .collect(Collectors.toList());

or create a Set:

final Set<String> nameSet = nameList.stream()
    .distinct()
    .collect(Collectors.toSet());
namedObjectList.stream()
    .filter((final MyNamedObject o) -> nameSet.stream().anyMatch((final String name) -> Objects.equals(name, o.getName())))
    .collect(Collectors.toList());

If nameList or nameSet can contain null, use .filter(Objects::nonNull). If neither name nor o.getName() can be null, replace Objects.equals(name, o.getName()) by name.equals(o.getName()).

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

8 Comments

thanks. I was looking for this, by the way what is time complexity of this code?
I don't know but I don't see how to suggest something more efficient in your case.
If you're sure that there is no null values, you can simplify a very little bit my example.
okay. I think as @Alberto Sinigaglia using set can be more efficient
If o.getName() can return null, it will be enough. If nameList can contain null values, just add .filter(Objects::nonNull).
|
2

If you have a List of names, then it's probably convenient to transform it to a Set so that you can easily check if it contains a name or not:

final Set<String> names = new HashSet<>(namesList);
List<Person> people = ...;
List<Person> result = people.stream()
   .filter(p -> names.contains(p.getName()))
   .collect(Collectors.toList());

You can avoid using the Set and just use the namesList, because there is a List.contains method, however it would be fairly inefficient

4 Comments

You expect a list, rather use Collectors.toList().
@gouessej I don't understand
You fixed it several minutes ago, you replaced Collectors.toString() by Collectors.toList(), it's ok now.
@gouessej oh ok, yes sorry, it was a typo

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.