自定义功能接口 SummaryStatistics
Custom Functional Interface SummaryStatistics
我有一个基本的 Spring 启动应用程序。使用 Spring 初始化程序、JPA、嵌入式 Tomcat、Thymeleaf 模板引擎,并打包为可执行 JAR 文件
我想基于具有 2 个字段、价格和更新日期的 POJO 创建自定义 SummaryStatistics。此统计信息应该获取最低/最高价格和此最低/最高价格的日期。
public class MenuPriceSummaryStatistics implements Consumer<MenuPrice> {
private long count;
private double sum;
private double sumCompensation; // Low order bits of sum
private double simpleSum; // Used to compute right sum for non-finite inputs
private double min = Double.POSITIVE_INFINITY;
private double max = Double.NEGATIVE_INFINITY;
private Date maxDate;
private Date minDate;
public MenuPriceSummaryStatistics() {
}
/**
* Combines the state of another {@code DoubleSummaryStatistics} into this one.
*
* @param other
* another {@code DoubleSummaryStatistics}
* @throws NullPointerException
* if {@code other} is null
*/
public void combine(MenuPriceSummaryStatistics other) {
count += other.count;
simpleSum += other.simpleSum;
sumWithCompensation(other.sum);
sumWithCompensation(other.sumCompensation);
min = Math.min(min, other.min);
max = Math.max(max, other.max);
if (min==other.min) {
minDate=other.minDate;
}
if (max==other.max) {
maxDate=other.maxDate;
}
}
@Override
public void accept(MenuPrice cp) {
++count;
simpleSum += cp.getPrice();
sumWithCompensation(cp.getPrice());
min = Math.min(min, cp.getPrice());
max = Math.max(max, cp.getPrice());
if (min==cp.getPrice()) {
minDate=cp.getUpdateDate();
}
if (max==cp.getPrice()) {
maxDate=cp.getUpdateDate();
}
}
private void sumWithCompensation(double value) {
double tmp = value - sumCompensation;
double velvel = sum + tmp; // Little wolf of rounding error
sumCompensation = (velvel - sum) - tmp;
sum = velvel;
}
public final long getCount() {
return count;
}
public final double getSum() {
// Better error bounds to add both terms as the final sum
double tmp = sum + sumCompensation;
if (Double.isNaN(tmp) && Double.isInfinite(simpleSum))
// If the compensated sum is spuriously NaN from
// accumulating one or more same-signed infinite values,
// return the correctly-signed infinity stored in
// simpleSum.
return simpleSum;
else
return tmp;
}
public final double getMin() {
return min;
}
public final double getMax() {
return max;
}
public Date getMaxDate() {
return maxDate;
}
public Date getMinDate() {
return minDate;
}
public final double getAverage() {
return getCount() > 0 ? getSum() / getCount() : 0.0d;
}
@Override
public String toString() {
return "MenuPriceSummaryStatistics [count=" + count + ", sum=" + sum + ", sumCompensation="
+ sumCompensation + ", simpleSum=" + simpleSum + ", min=" + min + ", max=" + max + ", maxDate="
+ maxDate + ", minDate=" + minDate + "]";
}
}
但是当我尝试使用它时
MenuPriceSummaryStatistics statistics =
(menuPrices
.stream()
.map(cp -> cp))
.summaryStatistics();
我得到一个错误,因为我应该定义方法 .summaryStatistics();
我试图定义 class
public interface MenuPriceStream extends BaseStream<MenuPrice, MenuPriceStream> {
..
}
但后来我变得复杂了
提出解决方案:
public static Collector<MenuPrice, ?, MenuPriceSummaryStatistics> menuPriceSummary() {
return Collector.of(
MenuPriceSummaryStatistics::new,
MenuPriceSummaryStatistics::accept,
(a, b) -> {a.combine(b); return a;},
Collector.Characteristics.IDENTITY_FINISH
);
}
我有这个编译错误:
Multiple markers at this line
- Syntax error, insert "[ ]" to complete Dimension
- Syntax error, insert ";" to complete LocalVariableDeclarationStatement
- Syntax error on token "menuPriceSummary", AnnotationName expected after this
token
您可以将 class 与 3 个参数一起使用 collect
:
MenuPriceSummaryStatistics statistics = menuPrices.stream()
.collect(
MenuPriceSummaryStatistics::new,
MenuPriceSummaryStatistics::accept,
MenuPriceSummaryStatistics::combine
);
您可能想要定义一个收集器
public static Collector<MenuPrice, ?, MenuPriceSummaryStatistics> menuPriceSummary() {
return Collector.of(
MenuPriceSummaryStatistics::new,
MenuPriceSummaryStatistics::accept,
(a, b) -> {a.combine(b); return a;},
Collector.Characteristics.IDENTITY_FINISH
);
}
然后您就可以像使用任何其他收集器一样使用它了:
MenuPriceSummaryStatistics s = menuPrices.stream().collect(menuPriceSummary());
我有一个基本的 Spring 启动应用程序。使用 Spring 初始化程序、JPA、嵌入式 Tomcat、Thymeleaf 模板引擎,并打包为可执行 JAR 文件 我想基于具有 2 个字段、价格和更新日期的 POJO 创建自定义 SummaryStatistics。此统计信息应该获取最低/最高价格和此最低/最高价格的日期。
public class MenuPriceSummaryStatistics implements Consumer<MenuPrice> {
private long count;
private double sum;
private double sumCompensation; // Low order bits of sum
private double simpleSum; // Used to compute right sum for non-finite inputs
private double min = Double.POSITIVE_INFINITY;
private double max = Double.NEGATIVE_INFINITY;
private Date maxDate;
private Date minDate;
public MenuPriceSummaryStatistics() {
}
/**
* Combines the state of another {@code DoubleSummaryStatistics} into this one.
*
* @param other
* another {@code DoubleSummaryStatistics}
* @throws NullPointerException
* if {@code other} is null
*/
public void combine(MenuPriceSummaryStatistics other) {
count += other.count;
simpleSum += other.simpleSum;
sumWithCompensation(other.sum);
sumWithCompensation(other.sumCompensation);
min = Math.min(min, other.min);
max = Math.max(max, other.max);
if (min==other.min) {
minDate=other.minDate;
}
if (max==other.max) {
maxDate=other.maxDate;
}
}
@Override
public void accept(MenuPrice cp) {
++count;
simpleSum += cp.getPrice();
sumWithCompensation(cp.getPrice());
min = Math.min(min, cp.getPrice());
max = Math.max(max, cp.getPrice());
if (min==cp.getPrice()) {
minDate=cp.getUpdateDate();
}
if (max==cp.getPrice()) {
maxDate=cp.getUpdateDate();
}
}
private void sumWithCompensation(double value) {
double tmp = value - sumCompensation;
double velvel = sum + tmp; // Little wolf of rounding error
sumCompensation = (velvel - sum) - tmp;
sum = velvel;
}
public final long getCount() {
return count;
}
public final double getSum() {
// Better error bounds to add both terms as the final sum
double tmp = sum + sumCompensation;
if (Double.isNaN(tmp) && Double.isInfinite(simpleSum))
// If the compensated sum is spuriously NaN from
// accumulating one or more same-signed infinite values,
// return the correctly-signed infinity stored in
// simpleSum.
return simpleSum;
else
return tmp;
}
public final double getMin() {
return min;
}
public final double getMax() {
return max;
}
public Date getMaxDate() {
return maxDate;
}
public Date getMinDate() {
return minDate;
}
public final double getAverage() {
return getCount() > 0 ? getSum() / getCount() : 0.0d;
}
@Override
public String toString() {
return "MenuPriceSummaryStatistics [count=" + count + ", sum=" + sum + ", sumCompensation="
+ sumCompensation + ", simpleSum=" + simpleSum + ", min=" + min + ", max=" + max + ", maxDate="
+ maxDate + ", minDate=" + minDate + "]";
}
}
但是当我尝试使用它时
MenuPriceSummaryStatistics statistics =
(menuPrices
.stream()
.map(cp -> cp))
.summaryStatistics();
我得到一个错误,因为我应该定义方法 .summaryStatistics();
我试图定义 class
public interface MenuPriceStream extends BaseStream<MenuPrice, MenuPriceStream> {
..
}
但后来我变得复杂了
提出解决方案:
public static Collector<MenuPrice, ?, MenuPriceSummaryStatistics> menuPriceSummary() {
return Collector.of(
MenuPriceSummaryStatistics::new,
MenuPriceSummaryStatistics::accept,
(a, b) -> {a.combine(b); return a;},
Collector.Characteristics.IDENTITY_FINISH
);
}
我有这个编译错误:
Multiple markers at this line
- Syntax error, insert "[ ]" to complete Dimension
- Syntax error, insert ";" to complete LocalVariableDeclarationStatement
- Syntax error on token "menuPriceSummary", AnnotationName expected after this
token
您可以将 class 与 3 个参数一起使用 collect
:
MenuPriceSummaryStatistics statistics = menuPrices.stream()
.collect(
MenuPriceSummaryStatistics::new,
MenuPriceSummaryStatistics::accept,
MenuPriceSummaryStatistics::combine
);
您可能想要定义一个收集器
public static Collector<MenuPrice, ?, MenuPriceSummaryStatistics> menuPriceSummary() {
return Collector.of(
MenuPriceSummaryStatistics::new,
MenuPriceSummaryStatistics::accept,
(a, b) -> {a.combine(b); return a;},
Collector.Characteristics.IDENTITY_FINISH
);
}
然后您就可以像使用任何其他收集器一样使用它了:
MenuPriceSummaryStatistics s = menuPrices.stream().collect(menuPriceSummary());