Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
224 views
in Technique[技术] by (71.8m points)

How to use Java 8 streams to find all values preceding a larger value?

Use Case

Through some coding Katas posted at work, I stumbled on this problem that I'm not sure how to solve.

Using Java 8 Streams, given a list of positive integers, produce a list of integers where the integer preceded a larger value.

[10, 1, 15, 30, 2, 6]

The above input would yield:

[1, 15, 2]

since 1 precedes 15, 15 precedes 30, and 2 precedes 6.

Non-Stream Solution

public List<Integer> findSmallPrecedingValues(final List<Integer> values) {

    List<Integer> result = new ArrayList<Integer>();
    for (int i = 0; i < values.size(); i++) {
        Integer next = (i + 1 < values.size() ? values.get(i + 1) : -1);
        Integer current = values.get(i);
        if (current < next) {
            result.push(current);
        }
    }
    return result;
}

What I've Tried

The problem I have is I can't figure out how to access next in the lambda.

return values.stream().filter(v -> v < next).collect(Collectors.toList());

Question

  • Is it possible to retrieve the next value in a stream?
  • Should I be using map and mapping to a Pair in order to access next?
question from:https://stackoverflow.com/questions/30089761/how-to-use-java-8-streams-to-find-all-values-preceding-a-larger-value

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

Using IntStream.range:

static List<Integer> findSmallPrecedingValues(List<Integer> values) {
    return IntStream.range(0, values.size() - 1)
        .filter(i -> values.get(i) < values.get(i + 1))
        .mapToObj(values::get)
        .collect(Collectors.toList());
}

It's certainly nicer than an imperative solution with a large loop, but still a bit meh as far as the goal of "using a stream" in an idiomatic way.

Is it possible to retrieve the next value in a stream?

Nope, not really. The best cite I know of for that is in the java.util.stream package description:

The elements of a stream are only visited once during the life of a stream. Like an Iterator, a new stream must be generated to revisit the same elements of the source.

(Retrieving elements besides the current element being operated on would imply they could be visited more than once.)

We could also technically do it in a couple other ways:

  • Statefully (very meh).
  • Using a stream's iterator is technically still using the stream.

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...