Get min and max of supplier streams

Viewed 621

I know if i use:

double data[][] = new double[n][];
// fill the array

DoubleStream stream = Arrays.stream(data).flatMapToDouble(Arrays::stream);
int max = stream.max().getAsDouble();

DoubleStream stream = Arrays.stream(data).flatMapToDouble(Arrays::stream);
int min = stream.min().getAsDouble();

i will get the minimum and maximum of whatever value the stream has as a double.

However i cant for the life of me figure out how to make it into a "Supplier". since

Supplier<Stream> stream = (Supplier<Stream>) Arrays.stream(data).flatMapToDouble(Arrays::stream);
double max = stream.max().getAsDouble();
double min = stream.min().getAsDouble();

doesn not work, and Supplier<DoubleStream> does not work ether.

i managed to get it to work with

Supplier<DoubleStream> stream = () -> Arrays.stream(t).flatMapToDouble(Arrays::stream);
OptionalDouble max = stream.get().max();
OptionalDouble min = stream.get().min();

but why did the values in the stream become a OptionalDouble?

2 Answers

Casting a DoubleStream to a Supplier<DoubleStream> does not make a DoubleStream a Supplier<DoubleStream>.

You need a lambda expression () -> stream to form a supplier of the stream:

Supplier<DoubleStream> supplier = () -> Arrays.stream(data).flatMapToDouble(Arrays::stream);

The max value then can be determined by:

double max = supplier.get().max().orElse(Double.MIN_VALUE); 
// where Double.MIN_VALUE can be any other default 'double' value if max is not present

since the max() over DoubleStream returns an OptionalDouble.

The Supplier<T> functional interface has a single abstract method:

@FunctionalInterface
public Supplier<T> {

    T get();
}

As it's a functional interface, you could use a lambda expression (or a method reference) to create an instance of the Supplier type:

Supplier<Integer> supplier = () -> 1;

If you change the Integer generic type to DoubleStream, then you'd get what you want:

Supplier<DoubleStream> supplier = Arrays.stream(data).flatMapToDouble(Arrays::stream);

Casting is not magic: if you have a DoubleStream instance, you can't just cast that instance to Supplier<DoubleStream> and expect the cast to magically transform the stream to a supplier.

Despite all this, it's not clear at all why you need to get a supplier from the stream in the first place.

Regarding the return type of DoubleStream.max and DoubleStream.min methods, it's OptionalDouble (instead of just double) because the stream might be empty, in which case there would be neither a max nor a min value. In this case, the returned OptionalDouble instance would be empty.

Related