You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
200 lines
7.3 KiB
200 lines
7.3 KiB
package com.project.analyzer;
|
|
|
|
import com.project.model.PostInfo;
|
|
|
|
import java.util.*;
|
|
import java.util.stream.Collectors;
|
|
|
|
public class PostAnalyzer {
|
|
|
|
private final List<PostInfo> posts;
|
|
|
|
public PostAnalyzer(List<PostInfo> posts) {
|
|
this.posts = posts;
|
|
}
|
|
|
|
public List<PostInfo> getPosts() {
|
|
return posts;
|
|
}
|
|
|
|
public void analyzeAll() {
|
|
System.out.println("\n========== 数据分析报告 ==========\n");
|
|
|
|
analyzeSentimentDistribution();
|
|
analyzeEngagementMetrics();
|
|
analyzePopularAuthors();
|
|
analyzeContentLength();
|
|
analyzeTemporalTrends();
|
|
|
|
System.out.println("\n========== 分析完成 ==========\n");
|
|
}
|
|
|
|
public void analyzeSentimentDistribution() {
|
|
System.out.println("【情感倾向分布分析】");
|
|
System.out.println("----------------------------------------");
|
|
|
|
Map<String, Long> sentimentCounts = posts.stream()
|
|
.collect(Collectors.groupingBy(
|
|
PostInfo::getSentiment,
|
|
Collectors.counting()
|
|
));
|
|
|
|
System.out.printf("%-20s %s%n", "情感倾向", "帖子数量");
|
|
System.out.println("----------------------------------------");
|
|
|
|
sentimentCounts.entrySet().stream()
|
|
.sorted(Map.Entry.<String, Long>comparingByValue().reversed())
|
|
.forEach(entry -> System.out.printf("%-20s %d%n", entry.getKey(), entry.getValue()));
|
|
|
|
System.out.println();
|
|
}
|
|
|
|
public void analyzeEngagementMetrics() {
|
|
System.out.println("【互动指标分析】");
|
|
System.out.println("----------------------------------------");
|
|
|
|
double avgLikes = posts.stream()
|
|
.mapToInt(PostInfo::getLikeCount)
|
|
.average()
|
|
.orElse(0);
|
|
|
|
double avgComments = posts.stream()
|
|
.mapToInt(PostInfo::getCommentCount)
|
|
.average()
|
|
.orElse(0);
|
|
|
|
double avgViews = posts.stream()
|
|
.mapToInt(PostInfo::getViewCount)
|
|
.average()
|
|
.orElse(0);
|
|
|
|
System.out.printf("平均点赞数: %.1f%n", avgLikes);
|
|
System.out.printf("平均评论数: %.1f%n", avgComments);
|
|
System.out.printf("平均浏览量: %.1f%n", avgViews);
|
|
|
|
System.out.println();
|
|
}
|
|
|
|
public void analyzePopularAuthors() {
|
|
System.out.println("【热门作者排行】");
|
|
System.out.println("----------------------------------------");
|
|
System.out.printf("%-30s %10s %10s %10s%n", "作者", "帖子数", "总点赞", "总评论");
|
|
System.out.println("----------------------------------------");
|
|
|
|
Map<String, List<PostInfo>> authorPosts = posts.stream()
|
|
.collect(Collectors.groupingBy(PostInfo::getAuthor));
|
|
|
|
authorPosts.entrySet().stream()
|
|
.sorted(Map.Entry.<String, List<PostInfo>>comparingByValue((a, b) -> b.size() - a.size()))
|
|
.limit(10)
|
|
.forEach(entry -> {
|
|
String author = entry.getKey();
|
|
List<PostInfo> authorPostList = entry.getValue();
|
|
int postCount = authorPostList.size();
|
|
int totalLikes = authorPostList.stream().mapToInt(PostInfo::getLikeCount).sum();
|
|
int totalComments = authorPostList.stream().mapToInt(PostInfo::getCommentCount).sum();
|
|
|
|
System.out.printf("%-30s %10d %10d %10d%n",
|
|
author.length() > 28 ? author.substring(0, 28) : author,
|
|
postCount, totalLikes, totalComments);
|
|
});
|
|
|
|
System.out.println();
|
|
}
|
|
|
|
public void analyzeContentLength() {
|
|
System.out.println("【内容长度分析】");
|
|
System.out.println("----------------------------------------");
|
|
|
|
double avgLength = posts.stream()
|
|
.mapToInt(post -> post.getContent().length())
|
|
.average()
|
|
.orElse(0);
|
|
|
|
int maxLength = posts.stream()
|
|
.mapToInt(post -> post.getContent().length())
|
|
.max()
|
|
.orElse(0);
|
|
|
|
int minLength = posts.stream()
|
|
.mapToInt(post -> post.getContent().length())
|
|
.min()
|
|
.orElse(0);
|
|
|
|
System.out.printf("平均内容长度: %.1f 字符%n", avgLength);
|
|
System.out.printf("最长内容: %d 字符%n", maxLength);
|
|
System.out.printf("最短内容: %d 字符%n", minLength);
|
|
|
|
System.out.println();
|
|
}
|
|
|
|
public void analyzeTemporalTrends() {
|
|
System.out.println("【时间趋势分析】");
|
|
System.out.println("----------------------------------------");
|
|
|
|
Map<String, Long> monthlyPosts = posts.stream()
|
|
.filter(post -> post.getPostDate() != null)
|
|
.collect(Collectors.groupingBy(
|
|
post -> post.getPostDate().format(java.time.format.DateTimeFormatter.ofPattern("yyyy-MM")),
|
|
Collectors.counting()
|
|
));
|
|
|
|
System.out.printf("%-10s %s%n", "月份", "帖子数量");
|
|
System.out.println("----------------------------------------");
|
|
|
|
monthlyPosts.entrySet().stream()
|
|
.sorted(Map.Entry.comparingByKey())
|
|
.forEach(entry -> System.out.printf("%-10s %d%n", entry.getKey(), entry.getValue()));
|
|
|
|
System.out.println();
|
|
}
|
|
|
|
public Map<String, Long> getSentimentDistributionData() {
|
|
return posts.stream()
|
|
.collect(Collectors.groupingBy(
|
|
PostInfo::getSentiment,
|
|
Collectors.counting()
|
|
));
|
|
}
|
|
|
|
public Map<String, Double> getEngagementData() {
|
|
Map<String, Double> engagementData = new LinkedHashMap<>();
|
|
|
|
double avgLikes = posts.stream()
|
|
.mapToInt(PostInfo::getLikeCount)
|
|
.average()
|
|
.orElse(0);
|
|
|
|
double avgComments = posts.stream()
|
|
.mapToInt(PostInfo::getCommentCount)
|
|
.average()
|
|
.orElse(0);
|
|
|
|
double avgViews = posts.stream()
|
|
.mapToInt(PostInfo::getViewCount)
|
|
.average()
|
|
.orElse(0);
|
|
|
|
engagementData.put("点赞", avgLikes);
|
|
engagementData.put("评论", avgComments);
|
|
engagementData.put("浏览", avgViews);
|
|
|
|
return engagementData;
|
|
}
|
|
|
|
public Map<String, Integer> getAuthorPostCount() {
|
|
return posts.stream()
|
|
.collect(Collectors.groupingBy(
|
|
PostInfo::getAuthor,
|
|
Collectors.summingInt(post -> 1)
|
|
)).entrySet().stream()
|
|
.sorted(Map.Entry.<String, Integer>comparingByValue().reversed())
|
|
.limit(10)
|
|
.collect(Collectors.toMap(
|
|
Map.Entry::getKey,
|
|
Map.Entry::getValue,
|
|
(e1, e2) -> e1,
|
|
LinkedHashMap::new
|
|
));
|
|
}
|
|
}
|
|
|