user3483969 user3483969 - 3 months ago 10
Java Question

Getting sublist from a Java list with nth elements that fullfills a condition with streams

I have a very simple use case

Given a list of letters with A and Bs, I want to get the sublist that contains the first N Bs, for example:


  • f(3, [A A A B A B A B A A]) = [A A A B A B A B]

  • f(2, [A A A B A B A B A A]) = [A A A B A B]

  • f(1, [A A B A B A]) = [A A B]

  • f(0, [A A B A B]) = []



By following an imperative approach, this is relatively easy, count until we find N Bs, and then get the sublist until that position.

However, I couldn't find any functional solution with lambdas, since the operation on every node seems to be independent from the others (which I guess make sense for parallelization).

Any ideas?

Answer

If your input is a List with fast random access, you can solve your problem using the stream of indices:

public static List<String> f(int n, List<String> input) {
    int fence = IntStream.range(0, input.size())
                         .filter(idx -> input.get(idx).equals("B")) // leave only B's
                         .skip(n-1)
                         .findFirst() // an index of n-th B
                         .getAsInt(); // with throw NoSuchElementException if not enough B's
    return input.subList(0, fence+1);
}

Usage example:

System.out.println(f(3, Arrays.asList("A", "A", "A", "B", "A", "B", "A", "B", "A", "A")));
System.out.println(f(2, Arrays.asList("A", "A", "A", "B", "A", "B", "A", "B", "A", "A")));
System.out.println(f(1, Arrays.asList("A", "A", "A", "B", "A", "B", "A", "B", "A", "A")));

However despite I love Stream API I would solve this problem imperatively.

Comments