Lazy streams and their terminal operations.

Okay, I have been bending over backwords trying to use streams inappropriately. So I found this issue about using DoubleStream#max and DoubleStream#min, they are both terminal operations.
For example lets say we have a bunch of Rectangle2D’s and we want to make a histogram of the widths. To do this we have to find the min, the max, create some bins, and iterate over the rectangles to place each one in its respective bin.
import javafx.geometry.Rectangle2D;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.DoubleStream;
import java.util.stream.IntStream;
/**
 * Created by odinsbane on 3/25/15.
 */
public class StreamCheck {
    /**
     * Broken version of making a histogram of rectangle widths.
     * @param rectangles collection of rectangles that will be histogrammed.
     * @return a list of bin, count pairs.
     */
    static List<double[]> broken(List<Rectangle2D> rectangles){
        double[] extrema = new double[]{-Double.MAX_VALUE, Double.MAX_VALUE};
        //since I cannot use both widths.max() and widths.min(), I tried to get
        //these values on the mapToDouble loop.
        DoubleStream widths = rectangles.stream().mapToDouble((rect)->{
            double w = rect.getWidth();
            extrema[0] = w>extrema[0]?w:extrema[0];
            extrema[1] = w<extrema[1]?w:extrema[1];
            return w;
        });
        /*
         * This is broken, because min and max have not been set yet.
         */
        int bins = 20;
        double min = extrema[1];
        double max = extrema[0];
        double delta = (max - min)/bins;
        System.out.printf("before %2.2f\t%2.2f\n",extrema[0], extrema[1]);
        List<double[]> op = IntStream.range(0, bins).mapToObj(
                (i)->new double[]{(i+0.5)*delta + min, 0}
        ).collect(Collectors.toCollection(ArrayList::new));
        //put the data in the bins.
        widths.forEach((d)->{
            int dex = (int)((d - min)/delta);
            dex = dex==op.size()?dex-1:dex;
            op.get(dex)[1] = op.get(dex)[1]+1;
        });
        System.out.printf("after %2.2f\t%2.2f\n", extrema[0], extrema[1]);
        return op;
    }
    /**
     * Fixed by using a for each to make the histogram of rectangle widths.
     * @param rectangles
     * @return a list of bin, count pairs.
     */
    static List<double[]> fixed(List<Rectangle2D> rectangles){
        //input is List<Rectangle2D> rectangles.
        double[] extrema = new double[]{-Double.MAX_VALUE, Double.MAX_VALUE};
        rectangles.stream().forEach((rect)->{
            double w = rect.getWidth();
            extrema[0] = w>extrema[0]?w:extrema[0];
            extrema[1] = w<extrema[1]?w:extrema[1];
        });
        DoubleStream widths = rectangles.stream().mapToDouble(Rectangle2D::getWidth);
        int bins = 20;
        double min = extrema[1];
        double max = extrema[0];
        double delta = (max - min)/bins;
        System.out.printf("before %2.2f\t%2.2f\n",extrema[0], extrema[1]);
        List<double[]> op = IntStream.range(0, bins).mapToObj(
                (i)->new double[]{(i+0.5)*delta + min, 0}
        ).collect(Collectors.toCollection(ArrayList::new));
        //put the data in the bins.
        widths.forEach((d)->{
            int dex = (int)((d - min)/delta);
            dex = dex==op.size()?dex-1:dex;
            op.get(dex)[1] = op.get(dex)[1]+1;
        });
        System.out.printf("after %2.2f\t%2.2f\n", extrema[0], extrema[1]);
        return op;
    }
    static Rectangle2D random(){
        return new Rectangle2D(Math.random(), Math.random(), Math.random(), Math.random());
    }
    public static void main(String[] args){
        List<Rectangle2D> rectangles = new ArrayList<>();
        IntStream.range(0,100).forEach((i)->rectangles.add(random()));
        broken(rectangles);
        fixed(rectangles);
    }
}

Since mapToDouble is an intermediate operation it happens lazily and does not get executed until the .forEach is called later on. So I had to use a terminal operation, in the fixed version a forEach is used.