1

relatively new to java and am looking into Streams

I was wondering how I can convert a Stream of Integers based on conditions.

For example, my stream will look something like 1,2,3,4,5 and I want to iterate and check if the next number is 3. If it is, i will add 1, else i will return 0. Thereafter, convert it into a List of Integers which will look like: [0,3,0,0,0]

What i currently have is something like this:

List<Integer> lst = new List.of(1,2,3,4,5);
Stream<Integer> strlst = lst.stream();
strlst.forEach(x -> {if (x.get(x+1).equals(3)) { return x + 1 } else {return 0} });
strlst.toList();
asd-qwert
  • 41
  • 5
  • https://stackoverflow.com/questions/31650157/is-it-possible-to-get-next-element-in-the-stream – azro Mar 29 '22 at 21:04
  • Does this answer your question? [get prime numbers from List using java stream](https://stackoverflow.com/questions/69800742/get-prime-numbers-from-list-using-java-stream) – Michael Shopsin Mar 30 '22 at 13:49

1 Answers1

0

Here is one way. It uses a nested ternary construct.
a ? b : c says if a is true, do b else do c.

  • stream some indices to reference the list
  • if the index is the last one, put a 0 on the stream
  • otherwise process as required.
List<Integer> list = List.of(1, 2, 3, 4, 5);

List<Integer> result = IntStream.range(0, list.size())
        .map(i -> i == list.size()-1 ? 0 : list.get(i + 1) == 3 ? list.get(i) + 1 : 0)
        .boxed()
        .toList()

prints

[0, 3, 0, 0, 0]

Note: a 3 as the first number in the stream does not have any effect since there is no prior number to increment.

I was wondering how I can convert a Stream of Integers based on conditions.

You should also take a look at Stream.mapMulti

WJS
  • 36,363
  • 4
  • 24
  • 39
  • thanks! what happens if now i want the 2 elements on both sides of 3 (next number, previous number) to +1? e.g. [0,3,0,5,0] I tried with || statement but im getting index out of bounds – asd-qwert Mar 29 '22 at 21:44
  • Well, that's a different problem. Since you cannot see what is coming before a given item, streams are not the best choice for those types of operations. This is probably more suited to a simple loop and taking care to monitor the index. A stack comes to mind since you can easily peek, push and pop values as needed. – WJS Mar 29 '22 at 21:49
  • why can't i do this way: IntStream.range(0, x.size() - 1) .map(y -> x.get(y) == 1 ? x.get(y-1) + 1 && x.get(y+1) + 1: 0) .boxed() .toList(); is it because I cannot add both at the same time? – asd-qwert Mar 29 '22 at 21:53
  • Because your stream sized is limited by the IntStream elements and you can't easily insert any into the stream (unless you use `mapMulti`). But there are still problems to resolve. I would use a loop if I were doing this. Also writing a customized collector might make it easier. – WJS Mar 29 '22 at 22:01
  • are you able to show a way to do it with Streams? really want to learn with streams instead of a loop – asd-qwert Mar 29 '22 at 22:05
  • 1
    There are *many* applications and things to do with streams. This one is not the best choice and any stream solution (which I can't think of at the moment) would not be very efficient. Sorry I couldn't provide more. – WJS Mar 30 '22 at 15:30
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/243453/discussion-between-asd-qwert-and-wjs). – asd-qwert Mar 30 '22 at 16:42