edit - second class does not have indexed based access, instead it implements iterable
Suppose a class structure like this:
public class Values
{
public int getValue(int i)
{
return values_[i];
}
private int[] values_;
}
and a second class like this
public class ValuesCollection implements Iterable
{
private Values[] valuesCollection_;
}
Is there a way using java8 streams API to operate statistics along each dimension for instance: sum, mean, min, max, range, variance, std, etc. For example [[2,4,8],[1,5,7],[3,9,6]], for getting min it would return [1,4,6]
The closest I can come up with is something like this:
public int[] getMin(ValuesCollection valuesCollection)
{
IntStream.range(0, valuesCollection.size()).boxed().collect(Collectors.toList())
.forEach(i -> {
List<Integer> vals = valuesCollection.stream()
.map(values -> values.getValue(i))
.collect(Collectors.toList());
// operate statistics on vals
// no way to return the statistics
});
}
You can do it. I've used arrays rather than your wrapper classes. Also, I should probably have included some validation that the array is rectangular, and used orElseThrow rather than getAsInt, but you get the idea.
int[][] vals = {{2, 4, 8}, {1, 5, 7}, {3, 9, 6}};
int[] min = IntStream
.range(0, vals[0].length)
.map(j -> IntStream.range(0, vals.length).map(i -> vals[i][j]).min().getAsInt())
.toArray();
System.out.println(Arrays.toString(min)); // Prints [1, 4, 6] as expected
(Since I used arrays, I could have used this line instead
.map(j -> Arrays.stream(vals).mapToInt(arr -> arr[j]).min().getAsInt())
but I wrote it like I did to closely model your situation where your objects are not arrays but do have indexed based access.)
Doing it for standard deviation is obviously harder, but you can do it by combining my answer with this one.
Edit
If your outer class does not have indexed based access, but instead implements Iterable you can do it by converting the Iterable to a Stream.
Iterable<int[]> vals = Arrays.asList(new int[][] {{2, 4, 8}, {1, 5, 7}, {3, 9, 6}});
int[] min = IntStream
.range(0, vals.iterator().next().length)
.map(j -> StreamSupport.stream(vals.spliterator(), false).mapToInt(a -> a[j]).min().getAsInt())
.toArray();
System.out.println(Arrays.toString(min)); // Prints [1, 4, 6] as expected
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With