本文目录导读:

我来详细介绍Java数据统计案例的几种常见实现方式。
基础数据统计示例
1 描述性统计分析
import java.util.*;
import java.util.stream.Collectors;
public class DescriptiveStatistics {
// 计算平均值
public static double mean(double[] data) {
return Arrays.stream(data).average().orElse(0.0);
}
// 计算中位数
public static double median(double[] data) {
double[] sorted = Arrays.copyOf(data, data.length);
Arrays.sort(sorted);
int n = sorted.length;
if (n % 2 == 0) {
return (sorted[n/2 - 1] + sorted[n/2]) / 2.0;
} else {
return sorted[n/2];
}
}
// 计算众数
public static List<Double> mode(double[] data) {
Map<Double, Long> frequencyMap = Arrays.stream(data)
.boxed()
.collect(Collectors.groupingBy(e -> e, Collectors.counting()));
long maxFrequency = frequencyMap.values().stream()
.max(Long::compareTo)
.orElse(0L);
return frequencyMap.entrySet().stream()
.filter(entry -> entry.getValue() == maxFrequency)
.map(Map.Entry::getKey)
.collect(Collectors.toList());
}
// 计算标准差
public static double standardDeviation(double[] data) {
double mean = mean(data);
double sum = Arrays.stream(data)
.map(x -> Math.pow(x - mean, 2))
.sum();
return Math.sqrt(sum / data.length);
}
// 计算方差
public static double variance(double[] data) {
double mean = mean(data);
return Arrays.stream(data)
.map(x -> Math.pow(x - mean, 2))
.sum() / data.length;
}
public static void main(String[] args) {
double[] data = {1, 2, 3, 4, 5, 5, 6, 7, 8, 9, 10};
System.out.println("数据: " + Arrays.toString(data));
System.out.println("平均值: " + mean(data));
System.out.println("中位数: " + median(data));
System.out.println("众数: " + mode(data));
System.out.println("标准差: " + standardDeviation(data));
System.out.println("方差: " + variance(data));
}
}
使用Apache Commons Math库
import org.apache.commons.math3.stat.descriptive.DescriptiveStatistics;
import org.apache.commons.math3.stat.descriptive.SummaryStatistics;
public class ApacheStatsExample {
public static void main(String[] args) {
double[] values = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
// 使用DescriptiveStatistics
DescriptiveStatistics stats = new DescriptiveStatistics();
for (double value : values) {
stats.addValue(value);
}
System.out.println("样本数: " + stats.getN());
System.out.println("平均值: " + stats.getMean());
System.out.println("标准差: " + stats.getStandardDeviation());
System.out.println("最小值: " + stats.getMin());
System.out.println("最大值: " + stats.getMax());
System.out.println("中位数: " + stats.getPercentile(50));
System.out.println("四分位距: " + (stats.getPercentile(75) - stats.getPercentile(25)));
// 使用SummaryStatistics(更高效)
SummaryStatistics summaryStats = new SummaryStatistics();
for (double value : values) {
summaryStats.addValue(value);
}
System.out.println("\nSummary Statistics:");
System.out.println("总和: " + summaryStats.getSum());
System.out.println("平均值: " + summaryStats.getMean());
System.out.println("方差: " + summaryStats.getVariance());
}
}
分组统计案例
import java.util.*;
import java.util.stream.Collectors;
public class GroupStatistics {
// 学生成绩类
static class Student {
private String name;
private String grade;
private double score;
public Student(String name, String grade, double score) {
this.name = name;
this.grade = grade;
this.score = score;
}
public String getGrade() { return grade; }
public double getScore() { return score; }
@Override
public String toString() {
return String.format("Student{name='%s', grade='%s', score=%.1f}",
name, grade, score);
}
}
public static void main(String[] args) {
List<Student> students = Arrays.asList(
new Student("张三", "A班", 85.5),
new Student("李四", "A班", 92.0),
new Student("王五", "B班", 78.5),
new Student("赵六", "A班", 95.5),
new Student("钱七", "B班", 88.0),
new Student("孙八", "C班", 72.0)
);
// 按班级分组统计
Map<String, DoubleSummaryStatistics> statsByGrade = students.stream()
.collect(Collectors.groupingBy(
Student::getGrade,
Collectors.summarizingDouble(Student::getScore)
));
System.out.println("分组统计结果:");
statsByGrade.forEach((grade, stats) -> {
System.out.printf("%s - 学生数: %d, 平均分: %.2f, 最高分: %.1f, 最低分: %.1f%n",
grade, stats.getCount(), stats.getAverage(),
stats.getMax(), stats.getMin());
});
// 按班级分组(自定义统计)
Map<String, List<Student>> studentsByGrade = students.stream()
.collect(Collectors.groupingBy(Student::getGrade));
System.out.println("\n详细分组:");
studentsByGrade.forEach((grade, studentList) -> {
System.out.println(grade + ": " + studentList);
});
}
}
时间序列统计分析
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.stream.Collectors;
public class TimeSeriesStatistics {
static class SalesRecord {
LocalDate date;
double amount;
public SalesRecord(String date, double amount) {
this.date = LocalDate.parse(date, DateTimeFormatter.ISO_DATE);
this.amount = amount;
}
public LocalDate getDate() { return date; }
public double getAmount() { return amount; }
}
public static void main(String[] args) {
List<SalesRecord> records = Arrays.asList(
new SalesRecord("2024-01-05", 1000),
new SalesRecord("2024-01-12", 1500),
new SalesRecord("2024-01-19", 1200),
new SalesRecord("2024-01-26", 1800),
new SalesRecord("2024-02-02", 2000),
new SalesRecord("2024-02-09", 1600)
);
// 按月统计
Map<String, DoubleSummaryStatistics> monthlyStats = records.stream()
.collect(Collectors.groupingBy(
r -> r.getDate().getYear() + "-" +
String.format("%02d", r.getDate().getMonthValue()),
Collectors.summarizingDouble(r -> r.amount)
));
System.out.println("月度统计:");
monthlyStats.forEach((month, stats) -> {
System.out.printf("%s - 总销售额: %.0f, 平均: %.0f, 交易次数: %d%n",
month, stats.getSum(), stats.getAverage(), stats.getCount());
});
// 计算移动平均(3期)
System.out.println("\n3期移动平均:");
for (int i = 2; i < records.size(); i++) {
double sum = records.get(i-2).amount +
records.get(i-1).amount +
records.get(i).amount;
double movingAvg = sum / 3;
System.out.printf("%s - %.0f (移动平均: %.0f)%n",
records.get(i).getDate(), records.get(i).amount, movingAvg);
}
}
}
简单回归分析
import org.apache.commons.math3.stat.regression.SimpleRegression;
public class RegressionAnalysis {
public static void main(String[] args) {
// 创建回归模型
SimpleRegression regression = new SimpleRegression();
// 添加数据点 (x, y)
regression.addData(1, 2);
regression.addData(2, 4);
regression.addData(3, 6);
regression.addData(4, 8);
regression.addData(5, 10);
// 输出回归结果
System.out.println("回归分析结果:");
System.out.println("斜率 (Slope): " + regression.getSlope());
System.out.println("截距 (Intercept): " + regression.getIntercept());
System.out.println("R平方: " + regression.getRSquare());
System.out.println("相关系数: " + regression.getR());
System.out.println("显著性水平: " + regression.getSignificance());
// 预测
double x = 6;
System.out.printf("预测 x=%f 时的y值: %f%n", x, regression.predict(x));
// 手动实现简单线性回归
double[] xValues = {1, 2, 3, 4, 5};
double[] yValues = {2, 4, 6, 8, 10};
ManualLinearRegression manualLR = new ManualLinearRegression();
manualLR.fit(xValues, yValues);
System.out.println("\n手动回归结果:");
System.out.println("斜率: " + manualLR.getSlope());
System.out.println("截距: " + manualLR.getIntercept());
}
}
// 简单线性回归手动实现
class ManualLinearRegression {
private double slope;
private double intercept;
public void fit(double[] x, double[] y) {
int n = x.length;
double sumX = 0, sumY = 0, sumXY = 0, sumX2 = 0;
for (int i = 0; i < n; i++) {
sumX += x[i];
sumY += y[i];
sumXY += x[i] * y[i];
sumX2 += x[i] * x[i];
}
// 计算斜率: (n*Σxy - Σx*Σy) / (n*Σx² - (Σx)²)
slope = (n * sumXY - sumX * sumY) / (n * sumX2 - sumX * sumX);
// 计算截距: (Σy - slope*Σx) / n
intercept = (sumY - slope * sumX) / n;
}
public double getSlope() { return slope; }
public double getIntercept() { return intercept; }
public double predict(double x) {
return slope * x + intercept;
}
}
Maven依赖配置
<dependencies>
<!-- Apache Commons Math -->
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-math3</artifactId>
<version>3.6.1</version>
</dependency>
<!-- Google Guava (可选,提供额外统计工具) -->
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>31.0.1-jre</version>
</dependency>
</dependencies>
这些示例涵盖了Java数据统计的常见场景:
- 基础统计:均值、中位数、标准差等
- 高级统计:使用Apache Commons Math库
- 分组统计:按类别进行数据汇总
- 时间序列:处理时间相关数据
- 回归分析:预测和相关性分析
根据具体需求,可以选择适当的实现方式,对于简单统计,使用Java 8+的Stream API就足够了;对于复杂的统计分析,推荐使用成熟的第三方库如Apache Commons Math。