362 // An efficient version requires a double-specific map/set implementation. 363 return boxed().distinct().mapToDouble(i -> (double) i); 364 } 365 366 // Terminal ops from DoubleStream 367 368 @Override 369 public void forEach(DoubleConsumer consumer) { 370 evaluate(ForEachOps.makeDouble(consumer, false)); 371 } 372 373 @Override 374 public void forEachOrdered(DoubleConsumer consumer) { 375 evaluate(ForEachOps.makeDouble(consumer, true)); 376 } 377 378 @Override 379 public final double sum() { 380 /* 381 * In the arrays allocated for the collect operation, index 0 382 * holds the high-order bits of the running sum and index 1 383 * holds the low-order bits of the sum computed via 384 * compensated summation. 385 */ 386 double[] summation = collect(() -> new double[2], 387 (ll, d) -> { 388 Collectors.sumWithCompensation(ll, d); 389 }, 390 (ll, rr) -> { 391 Collectors.sumWithCompensation(ll, rr[0]); 392 Collectors.sumWithCompensation(ll, rr[1]); 393 }); 394 395 // Better error bounds to add both terms as the final sum 396 return summation[0] + summation[1]; 397 } 398 399 @Override 400 public final OptionalDouble min() { 401 return reduce(Math::min); 402 } 403 404 @Override 405 public final OptionalDouble max() { 406 return reduce(Math::max); 407 } 408 409 /** 410 * {@inheritDoc} 411 * 412 * @implNote The {@code double} format can represent all 413 * consecutive integers in the range -2<sup>53</sup> to 414 * 2<sup>53</sup>. If the pipeline has more than 2<sup>53</sup> 415 * values, the divisor in the average computation will saturate at 416 * 2<sup>53</sup>, leading to additional numerical errors. 417 */ 418 @Override 419 public final OptionalDouble average() { 420 /* 421 * In the arrays allocated for the collect operation, index 0 422 * holds the high-order bits of the running sum, index 1 holds 423 * the low-order bits of the sum computed via compensated 424 * summation, and index 2 holds the number of values seen. 425 */ 426 double[] avg = collect(() -> new double[3], 427 (ll, d) -> { 428 ll[2]++; 429 Collectors.sumWithCompensation(ll, d); 430 }, 431 (ll, rr) -> { 432 Collectors.sumWithCompensation(ll, rr[0]); 433 Collectors.sumWithCompensation(ll, rr[1]); 434 ll[2] += rr[2]; 435 }); 436 return avg[2] > 0 437 // Better error bounds to add both terms as the final sum to compute average 438 ? OptionalDouble.of((avg[0] + avg[1]) / avg[2]) 439 : OptionalDouble.empty(); 440 } 441 442 @Override 443 public final long count() { 444 return mapToObj(e -> null).mapToInt(e -> 1).sum(); 445 } 446 447 @Override 448 public final DoubleSummaryStatistics summaryStatistics() { 449 return collect(DoubleSummaryStatistics::new, DoubleSummaryStatistics::accept, 450 DoubleSummaryStatistics::combine); 451 } 452 453 @Override 454 public final double reduce(double identity, DoubleBinaryOperator op) { 455 return evaluate(ReduceOps.makeDouble(identity, op)); 456 } 457 458 @Override | 362 // An efficient version requires a double-specific map/set implementation. 363 return boxed().distinct().mapToDouble(i -> (double) i); 364 } 365 366 // Terminal ops from DoubleStream 367 368 @Override 369 public void forEach(DoubleConsumer consumer) { 370 evaluate(ForEachOps.makeDouble(consumer, false)); 371 } 372 373 @Override 374 public void forEachOrdered(DoubleConsumer consumer) { 375 evaluate(ForEachOps.makeDouble(consumer, true)); 376 } 377 378 @Override 379 public final double sum() { 380 /* 381 * In the arrays allocated for the collect operation, index 0 382 * holds the high-order bits of the running sum, index 1 holds 383 * the low-order bits of the sum computed via compensated 384 * summation, and index 2 holds the simple sum used to compute 385 * the proper result if the stream contains infinite values of 386 * the same sign. 387 */ 388 double[] summation = collect(() -> new double[3], 389 (ll, d) -> { 390 Collectors.sumWithCompensation(ll, d); 391 ll[2] += d; 392 }, 393 (ll, rr) -> { 394 Collectors.sumWithCompensation(ll, rr[0]); 395 Collectors.sumWithCompensation(ll, rr[1]); 396 ll[2] += rr[2]; 397 }); 398 399 return Collectors.computeFinalSum(summation); 400 } 401 402 @Override 403 public final OptionalDouble min() { 404 return reduce(Math::min); 405 } 406 407 @Override 408 public final OptionalDouble max() { 409 return reduce(Math::max); 410 } 411 412 /** 413 * {@inheritDoc} 414 * 415 * @implNote The {@code double} format can represent all 416 * consecutive integers in the range -2<sup>53</sup> to 417 * 2<sup>53</sup>. If the pipeline has more than 2<sup>53</sup> 418 * values, the divisor in the average computation will saturate at 419 * 2<sup>53</sup>, leading to additional numerical errors. 420 */ 421 @Override 422 public final OptionalDouble average() { 423 /* 424 * In the arrays allocated for the collect operation, index 0 425 * holds the high-order bits of the running sum, index 1 holds 426 * the low-order bits of the sum computed via compensated 427 * summation, index 2 holds the number of values seen, index 3 428 * holds the simple sum. 429 */ 430 double[] avg = collect(() -> new double[4], 431 (ll, d) -> { 432 ll[2]++; 433 Collectors.sumWithCompensation(ll, d); 434 ll[3] += d; 435 }, 436 (ll, rr) -> { 437 Collectors.sumWithCompensation(ll, rr[0]); 438 Collectors.sumWithCompensation(ll, rr[1]); 439 ll[2] += rr[2]; 440 ll[3] += rr[3]; 441 }); 442 return avg[2] > 0 443 ? OptionalDouble.of(Collectors.computeFinalSum(avg) / avg[2]) 444 : OptionalDouble.empty(); 445 } 446 447 @Override 448 public final long count() { 449 return mapToObj(e -> null).mapToInt(e -> 1).sum(); 450 } 451 452 @Override 453 public final DoubleSummaryStatistics summaryStatistics() { 454 return collect(DoubleSummaryStatistics::new, DoubleSummaryStatistics::accept, 455 DoubleSummaryStatistics::combine); 456 } 457 458 @Override 459 public final double reduce(double identity, DoubleBinaryOperator op) { 460 return evaluate(ReduceOps.makeDouble(identity, op)); 461 } 462 463 @Override |