第五章(5) 數值範圍及數值流綜合使用案例----獲取勾股數勾股數
阿新 • • 發佈:2018-11-02
1.產生一個數值範圍
和數字打交道時,有一個常用的東西就是數值範圍。比如,假設你想要生成1和100之間的所有數字。Java 8引入了兩個可以用於IntStream和LongStream的靜態方法,幫助生成這種範圍:range和rangeClosed。這兩個方法都是第一個引數接受起始值,第二個引數接受結束值。但range是不包含結束值的,而rangeClosed則包含結束值。讓我們來看一個例子:
var numbers = IntStream.rangeClosed(1,100).filter(n->n%2==0);//宣告一個數值範圍,並篩選偶數 numbers.forEachOrdered(System.out::println);//打印出所有偶數,終端操作 System.out.println(numbers.count());//打印出偶數個數,終端操作,只是展示,實際執行會報錯,因為流已經被上一個終端消費掉了
2.數值流案例的集大成者---勾股數流
那麼以上案例中flatMap是怎麼回事呢?我們看到flatMap中對映成一個流,也就是說flatMap建立了一個流的流,故需要使用使用flatMap扁平化一下,使它成為一個“單一”的流。請注意,你在filter之後呼叫boxed,從rangeClosed返回的IntStream生成一個Stream<Integer>。這是因為你的map會為流中的每個元素返回一個int陣列。而IntStream中的map方法只能為流中的每個元素返回另一個int,這可不是你想要的!你可以用IntStream的mapToObj方法改寫它,這個方法會返回一個物件值流
你可以像下面這樣採取更好的方案
Stream<double[]> pythagoreanTriples2 = IntStream.rangeClosed(1, 100) .boxed() .flatMap ( a -> IntStream.rangeClosed(a, 100) .mapToObj( b -> new double[]{a, b, Math.sqrt(a*a + b*b)}).filter(t -> t[2] % 1 == 0) ); pythagoreanTriples2.limit(6).forEach(t->System.out.println(t[0]+","+t[1]+","+t[2]));