package answers.section4;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import java.util.stream.Collectors;
import java.util.stream.DoubleStream;
import java.util.stream.IntStream;
import java.util.stream.Stream;
public class S403StreamInsteadOfFor {
public S403StreamInsteadOfFor() {
processStatistics();
processStatisticsAnswer1();
processStatisticsAnswer2();
processStatisticsAnswer3();
processStatisticsAnswer4();
}
private void processStatistics() {
// 乱数のリストを作成
Random random = new Random();
List<Double> numbers = new ArrayList<>();
for (int i = 0; i < 100; i++) {
numbers.add(random.nextDouble());
}
// 平均を算出
double ave = 0.0;
for (Double x : numbers) {
ave += x;
}
ave /= numbers.size();
// 分散を算出
double variance = 0.0;
for (Double x : numbers) {
variance += (x - ave) * (x - ave);
}
variance /= numbers.size();
System.out.println("Average: " + ave);
System.out.println("Diverse: " + variance);
}
private void processStatisticsAnswer1() {
// 乱数のリストを作成
Random random = new Random();
// 0 から 100 までの IntStream を使用して、100 個の DoubleStream を作成
// ボクシングを行ってから、リスト化する
List<Double> numbers = IntStream.range(0, 100)
.mapToDouble(x -> random.nextDouble())
.boxed()
.collect(Collectors.toList());
// reduce メソッドを使用して合計を算出し、平均を求める
double ave = numbers.stream()
.reduce(0.0, (x, y) -> x + y);
ave /= numbers.size();
// map メソッドで平均からの差の 2 乗を計算
// reduce メソッドで合算する
double ave2 = ave; // 実質的 final にするために新しい変数を定義
double variance = numbers.stream()
.map(x -> (x - ave2) * (x - ave2))
.reduce(0.0, (x, y) -> x + y);
variance /= numbers.size();
System.out.println("Average: " + ave);
System.out.println("Diverse: " + variance);
}
private void processStatisticsAnswer2() {
// 乱数のリストを作成
Random random = new Random();
// 0 から 100 までの IntStream を使用して、100 個の Stream<Double> を作成
// 最後にリスト化する
List<Double> numbers = IntStream.range(0, 100)
.mapToObj(x -> random.nextDouble())
.collect(Collectors.toList());
// collect メソッドを使用して合計を算出し、平均を求める
double ave = numbers.stream()
.collect(Collectors.summingDouble(x -> x));
ave /= numbers.size();
// map メソッドで平均からの差の 2 乗を計算
// collect メソッドで合算する
double ave2 = ave; // 実質的 final にするために新しい変数を定義
double variance = numbers.stream()
.map(x -> (x - ave2) * (x - ave2))
.collect(Collectors.summingDouble(x -> x));
variance /= numbers.size();
System.out.println("Average: " + ave);
System.out.println("Diverse: " + variance);
}
private void processStatisticsAnswer3() {
// 乱数のリストを作成
Random random = new Random();
// generate メソッドを使用して、Double クラスの無限ストリームを作成し
// limit メソッドで個数を 100 に制限する。最後にリスト化する
List<Double> numbers = Stream.generate(() -> random.nextDouble())
.limit(100)
.collect(Collectors.toList());
// collect メソッドを統計情報を算出し、そこから平均をえる
double ave = numbers.stream()
.collect(Collectors.summarizingDouble(x -> x))
.getAverage();
// map メソッドで平均からの差の 2 乗を計算
// collect メソッドを統計情報を算出し、そこから平均をえる
double variance = numbers.stream()
.map(x -> (x - ave) * (x - ave))
.collect(Collectors.summarizingDouble(x -> x))
.getAverage();
System.out.println("Average: " + ave);
System.out.println("Diverse: " + variance);
}
private void processStatisticsAnswer4() {
// Random クラスの double メソッドで DoubleStream オブジェクトを生成できるので
// それを配列化する
double[] numbers = new Random().doubles(100)
.toArray();
// DoubleStream クラスの average メソッドで平均を算出
// average メソッドの返り値の型は OptionalDouble クラスなので、getAsDouble メソッドで値を取得する
double ave = DoubleStream.of(numbers)
.average()
.getAsDouble();
// map メソッドで平均からの差の 2 乗を計算
// average メソッドで平均を算出
double variance = DoubleStream.of(numbers)
.map(x -> (x - ave) * (x - ave))
.average()
.getAsDouble();
System.out.println("Average: " + ave);
System.out.println("Diverse: " + variance);
}
public static void main(String[] args) {
new S403StreamInsteadOfFor();
}
}