360 public final DoubleStream distinct() { 361 // While functional and quick to implement, this approach is not very efficient. 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 // TODO: better algorithm to compensate for errors 381 return reduce(0.0, Double::sum); 382 } 383 384 @Override 385 public final OptionalDouble min() { 386 return reduce(Math::min); 387 } 388 389 @Override 390 public final OptionalDouble max() { 391 return reduce(Math::max); 392 } 393 394 @Override 395 public final OptionalDouble average() { 396 double[] avg = collect(() -> new double[2], 397 (ll, i) -> { 398 ll[0]++; 399 ll[1] += i; 400 }, 401 (ll, rr) -> { 402 ll[0] += rr[0]; 403 ll[1] += rr[1]; 404 }); 405 return avg[0] > 0 406 ? OptionalDouble.of(avg[1] / avg[0]) 407 : OptionalDouble.empty(); 408 } 409 410 @Override 411 public final long count() { 412 return mapToObj(e -> null).mapToInt(e -> 1).sum(); 413 } 414 415 @Override 416 public final DoubleSummaryStatistics summaryStatistics() { 417 return collect(DoubleSummaryStatistics::new, DoubleSummaryStatistics::accept, 418 DoubleSummaryStatistics::combine); 419 } 420 421 @Override 422 public final double reduce(double identity, DoubleBinaryOperator op) { 423 return evaluate(ReduceOps.makeDouble(identity, op)); 424 } 425 426 @Override | 360 public final DoubleStream distinct() { 361 // While functional and quick to implement, this approach is not very efficient. 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 double[] summation = collect(() -> new double[2], 381 (ll, d) -> { 382 Collectors.sumWithCompensation(ll, d); 383 }, 384 (ll, rr) -> { 385 Collectors.sumWithCompensation(ll, rr[0]); 386 Collectors.sumWithCompensation(ll, rr[1]); 387 }); 388 return summation[0]; 389 } 390 391 @Override 392 public final OptionalDouble min() { 393 return reduce(Math::min); 394 } 395 396 @Override 397 public final OptionalDouble max() { 398 return reduce(Math::max); 399 } 400 401 /** 402 * {@inheritDoc} 403 * 404 * @implNote The {@code double} format can represent all 405 * consecutive integers in the range -2<sup>53</sup> to 406 * 2<sup>53</sup>. If the pipeline has more than 2<sup>53</sup> 407 * values, the divisor in the average computation will saturate at 408 * 2<sup>53</sup>, leading to additional numerical errors. 409 */ 410 @Override 411 public final OptionalDouble average() { 412 double[] avg = collect(() -> new double[3], 413 (ll, d) -> { 414 ll[2]++; 415 Collectors.sumWithCompensation(ll, d); 416 }, 417 (ll, rr) -> { 418 Collectors.sumWithCompensation(ll, rr[0]); 419 Collectors.sumWithCompensation(ll, rr[1]); 420 ll[2] += rr[2]; 421 }); 422 return avg[0] > 0 423 ? OptionalDouble.of(avg[0] / avg[2]) 424 : OptionalDouble.empty(); 425 } 426 427 @Override 428 public final long count() { 429 return mapToObj(e -> null).mapToInt(e -> 1).sum(); 430 } 431 432 @Override 433 public final DoubleSummaryStatistics summaryStatistics() { 434 return collect(DoubleSummaryStatistics::new, DoubleSummaryStatistics::accept, 435 DoubleSummaryStatistics::combine); 436 } 437 438 @Override 439 public final double reduce(double identity, DoubleBinaryOperator op) { 440 return evaluate(ReduceOps.makeDouble(identity, op)); 441 } 442 443 @Override |