0

I have an ArrayList of Person ordered by ids the 0 as the id:1 the 1 as the id:2 etc and I want to get only some of them in another ArrayList using stream here's what I tried but it don't seems to work:

public ArrayList<Person> getPersonfoById(int... ids) {
    if (IntStream.of(ids).anyMatch(id -> id > totalpersonnumber)) {
        throw new IllegalArgumentException("the given person id" + Arrays.asList(IntStream.of(ids).filter(i -> i >= totalpersonnumber).boxed().toArray()) + " dosen't exist in " + fileName);
    }
    try (IntStream stream = Arrays.stream(ids)) {
        return (ArrayList<Pokemon>) stream.boxed().map(x -> myArrayOfPerson.get(x))
                                                  .collect(Collectors.toList());
    }
}
3
  • 5
    Have you tried Stream::filter in combination with Stream::collect and Collectors.toList()? Commented Dec 29, 2019 at 23:39
  • "I want to get only some of them in another ArrayList" what's your filter criteria? Commented Dec 29, 2019 at 23:39
  • I have an array list of Person a person is defined by an id, a name and his gender all my Person are in an array list I want with this method to enter ids like 1,2,18,20 and get a new array list of person with only the ids I gave Commented Dec 30, 2019 at 17:04

2 Answers 2

2

Since the input of selected ids might vary, the best way is to use List::contains in the filter's predicate:

// Get a list of ids at the beginning once and use with each iteration
List<Integer> idsList = Arrays.stream(ids).boxed().collect(Collectors.toList());

List<Person> personList myArrayOfPerson.stream()         // Stream<Person>
    .filter(person -> idsList.contains(person.getId()))  // Stream<Person> of the given ids
    .collect(Collectors.toList());                       // List<Person>

This is the solution where the id is a part of the object Person and not driven by the behavior of the List which is not a good practice.

However, if you insist to get these on the certain positions in the List, then a bit different approach is required:

List<Person> personList = Arrays.stream(ids)             // IntStream
    .boxed()                                             // Stream<Integer>
    .map(myArrayOfPerson::get)                           // Stream<Person>
    .collect(Collectors.toList());                       // List<Person>

This is a fail-fast approach which doesn't handle the ids out of the bounds. You should know that List::get might throw an IndexOutOfBoundsException, so to avoid this, filter out the ids which doesn't fit the list size:

List<Person> personList = Arrays.stream(ids)             // IntStream
    .filter(id -> id > 0 && id < myArrayOfPerson.size()) // IntStream (wanted ids only)
    .boxed()                                             // Stream<Integer>
    .map(myArrayOfPerson::get)                           // Stream<Person>
    .collect(Collectors.toList());                       // List<Person>

An alternative way would be to return null objects for unusual ids or log a message or handle it another way which is out of the scope of this answer.

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

1 Comment

I like the way @Nikolas writes the solution, he always adds up comment at each step in #stream, making it comfortable for newbies to know what is going on.
0

Maybe you need something like this

Arrays.stream(ids).filter(id->id>20).toArray();

For stream uses visit this link

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.