user156441
user156441

Reputation: 185

Processing a collection taking two adjacent elements at a time (use of stream)

I have a list of objects that represent different cities. What I want to do with that list is obtain the sum of the distance between adjacent cities in the list. So if my list is l = {c1,c2,c3},the result would be total sum = distance(c1,c2) + distance(c2,c3).

I was trying to make use of the stream API but I couldn't find a way to process the elements on a list in this particular case where the processing is not one element at a time but involves two adjacent elements of the list at each step.

I would really appreciate if someone has any idea how to apply stream in this way, to give me a hand.

Upvotes: 2

Views: 388

Answers (3)

M. Justin
M. Justin

Reputation: 21255

The windowSliding gatherer in the upcoming Java 24 (added as part of the Stream Gatherers feature) can be used to achieve the stated goal, operating on each adjacent pair of elements:

int sum = cities.stream()
        .gather(Gatherers.windowSliding(2))
        .mapToInt(w -> distance(w.getFirst(), w.getLast()))
        .sum();

This first converts the Stream<City> to a Stream<List<City>>. Each list element in the new stream is a 2-element list of an adjacent pair of orders. It then maps this to an IntStream, where each element is the result of distance(City c1, City c2) on each pair. Finally, all the values in the stream are added into one combined sum.

Upvotes: 0

Samuel Philipp
Samuel Philipp

Reputation: 11050

You can just use this:

double distance = IntStream.range(0, cities.size() - 1)
        .mapToDouble(i -> distance(cities.get(i), cities.get(i + 1)))
        .sum();

This creates an IntStream and maps the calculated distance for the neighbor cities. At the end all distance are summed up.

Upvotes: 1

samzz
samzz

Reputation: 117

Try this:

n = l.size();
Stream.iterate(0, i -> i + 1)
      .limit(n-1)
      .map( i -> distance(l.get(i), l.get(i+1))
      .reduce(0, (totalDistance, currDistance) -> totalDistance + currDistance, (distance1, distance2) -> distance1 + distance2);

Upvotes: 1

Related Questions