javajava-streamatomicinteger

How to use AtomicInteger getAndSet correctly?


I want to get the difference between consecutive list elements using Java stream and AtomicInteger:

List<Integer> list  = List.of(1,2,3,5,6,8,9,10,22,23,27);
AtomicInteger diff  = new AtomicInteger(1);


List<Integer> result = list.stream()
                           .skip(1)
                           .map(i -> diff.getAndSet(i - diff.get()))
                           .toList();

System.out.println(result);

Output is:

[1, 1, 2, 3, 3, 5, 4, 6, 16, 7]

I was expecting to get the difference of each element from previous like below:

[1, 1, 2, 1, 2, 1, 1, 12, 1, 4]

What am I doing wrong? How to get the desired output?


Solution

  • I wouldn't use an atomic type for this. Instead I would start with a stream of the list indexes:

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

    Note that the ending number passed to IntStream#range is exclusive while the start is inclusive. The range is half-open.

    This (IMO) is simpler and cleaner (and more functional) than relying on side-effects.