Browse Source

添加W4

main
故春 3 weeks ago
parent
commit
b5716d10f0
  1. 0
      Main.class
  2. 178
      Main.java
  3. 0
      Movie.java
  4. 0
      MovieCrawler.java
  5. 169
      W3/Main.java
  6. 0
      W4/Circle.java
  7. 0
      W4/QQ20260327-221432.png
  8. 0
      W4/Rectangle.java
  9. 0
      W4/Shape.java
  10. 0
      W4/ShapeUtil.java
  11. 0
      W4/Test.java
  12. 0
      W4/Triangle.java
  13. 0
      W4/W3.txt
  14. 0
      jcommon-1.0.24.jar
  15. 0
      jfreechart-1.5.4.jar
  16. 0
      jsoup-1.17.2.jar
  17. 0
      movies.csv
  18. 0
      rating_distribution.png
  19. 0
      year_rating_relation.png

0
W3/Main.class → Main.class

178
Main.java

@ -1,27 +1,169 @@
import org.jfree.chart.ChartFactory;
import org.jfree.chart.ChartUtils;
import org.jfree.chart.JFreeChart;
import org.jfree.data.category.DefaultCategoryDataset;
import org.jfree.data.general.DefaultPieDataset;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.util.*;
import java.util.stream.Collectors;
public class Main { public class Main {
public static void main(String[] args) { public static void main(String[] args) {
int[] voltages = {10, -5, 7, 105, 999, 89, 76, 74}; try {
int validCount = 0; // 有效数据个数 // 1. 爬取电影数据
double validSum = 0; // 有效数据总和 MovieCrawler crawler = new MovieCrawler();
List<Movie> movies = crawler.crawlTopMovies(50); // 爬取50部电影
// 2. 数据清洗
List<Movie> cleanedMovies = cleanData(movies);
// 3. 数据存储
saveToCSV(cleanedMovies, "movies.csv");
// 4. 数据分析
analyzeData(cleanedMovies);
// 5. 结果展示
displayResults(cleanedMovies);
generateCharts(cleanedMovies);
System.out.println("爬取完成!共获取了 " + cleanedMovies.size() + " 部电影数据。");
} catch (Exception e) {
e.printStackTrace();
}
}
private static List<Movie> cleanData(List<Movie> movies) {
return movies.stream()
.map(movie -> {
// 去空格
movie.setTitle(movie.getTitle().trim());
movie.setGenre(movie.getGenre().trim());
movie.setDirector(movie.getDirector().trim());
movie.setActors(movie.getActors().trim());
movie.setSynopsis(movie.getSynopsis().trim());
return movie;
})
.collect(Collectors.toList());
}
private static void saveToCSV(List<Movie> movies, String fileName) throws IOException {
try (FileWriter writer = new FileWriter(fileName)) {
// 写入表头
writer.write("Title,Year,Rating,Genre,Director,Actors,Synopsis\n");
for (int voltage : voltages) { // 写入数据
if (voltage == 999) { for (Movie movie : movies) {
System.out.println("程序终止,传感器离线"); writer.write(String.format("%s,%d,%.1f,%s,%s,%s,%s\n",
break; // 遇到999,终止程序 escapeCSV(movie.getTitle()),
} else if (voltage < 0) { movie.getYear(),
System.out.println("警告:发现负数,数据已跳过"); movie.getRating(),
} else if (voltage >= 1 && voltage <= 100) { escapeCSV(movie.getGenre()),
validCount++; escapeCSV(movie.getDirector()),
validSum += voltage; escapeCSV(movie.getActors()),
escapeCSV(movie.getSynopsis())));
}
} }
// 其他情况(如>100)不处理
} }
if (validCount > 0) { private static String escapeCSV(String value) {
double average = validSum / validCount; if (value == null) return "";
System.out.printf("有效数据个数:%d,平均值:%.2f\n", validCount, average); if (value.contains(",") || value.contains("\n") || value.contains("\"")) {
} else { value = value.replace("\"", "\"\"");
System.out.println("没有收集到有效数据,打印初始状态"); return "\"" + value + "\"";
}
return value;
} }
private static void analyzeData(List<Movie> movies) {
System.out.println("\n=== 数据分析结果 ===");
// 1. 评分分布
System.out.println("\n1. 评分分布:");
Map<Double, Long> ratingDistribution = movies.stream()
.collect(Collectors.groupingBy(Movie::getRating, Collectors.counting()));
ratingDistribution.entrySet().stream()
.sorted(Map.Entry.comparingByKey())
.forEach(entry -> System.out.printf("评分 %.1f: %d 部\n", entry.getKey(), entry.getValue()));
// 2. 年份分布
System.out.println("\n2. 年份分布:");
Map<Integer, Long> yearDistribution = movies.stream()
.collect(Collectors.groupingBy(Movie::getYear, Collectors.counting()));
yearDistribution.entrySet().stream()
.sorted(Map.Entry.comparingByKey())
.forEach(entry -> System.out.printf("年份 %d: %d 部\n", entry.getKey(), entry.getValue()));
// 3. 导演作品数排行
System.out.println("\n3. 导演作品数排行:");
Map<String, Long> directorCount = movies.stream()
.collect(Collectors.groupingBy(Movie::getDirector, Collectors.counting()));
directorCount.entrySet().stream()
.sorted(Map.Entry.<String, Long>comparingByValue().reversed())
.limit(10)
.forEach(entry -> System.out.printf("%s: %d 部\n", entry.getKey(), entry.getValue()));
// 4. 平均评分
double averageRating = movies.stream()
.mapToDouble(Movie::getRating)
.average()
.orElse(0);
System.out.printf("\n4. 平均评分:%.2f\n", averageRating);
}
private static void displayResults(List<Movie> movies) {
System.out.println("\n=== 电影数据列表 ===");
System.out.printf("%-50s %-10s %-10s %-30s %-30s\n", "Title", "Year", "Rating", "Genre", "Director");
System.out.println("-------------------------------------------------------------------------------------------------------------------------------");
for (Movie movie : movies) {
System.out.printf("%-50s %-10d %-10.1f %-30s %-30s\n",
truncate(movie.getTitle(), 50),
movie.getYear(),
movie.getRating(),
truncate(movie.getGenre(), 30),
truncate(movie.getDirector(), 30));
}
}
private static String truncate(String text, int maxLength) {
return text.length() > maxLength ? text.substring(0, maxLength - 3) + "..." : text;
}
private static void generateCharts(List<Movie> movies) throws IOException {
// 1. 评分分布饼图
DefaultPieDataset ratingDataset = new DefaultPieDataset();
Map<Double, Long> ratingDistribution = movies.stream()
.collect(Collectors.groupingBy(Movie::getRating, Collectors.counting()));
ratingDistribution.forEach((rating, count) -> ratingDataset.setValue(String.valueOf(rating), count));
JFreeChart ratingChart = ChartFactory.createPieChart(
"电影评分分布",
ratingDataset,
true,
true,
false
);
ChartUtils.saveChartAsPNG(new File("rating_distribution.png"), ratingChart, 800, 600);
// 2. 年份与评分关系图
DefaultCategoryDataset yearRatingDataset = new DefaultCategoryDataset();
Map<Integer, Double> yearAverageRating = movies.stream()
.collect(Collectors.groupingBy(Movie::getYear,
Collectors.averagingDouble(Movie::getRating)));
yearAverageRating.forEach((year, avgRating) -> yearRatingDataset.addValue(avgRating, "评分", String.valueOf(year)));
JFreeChart yearRatingChart = ChartFactory.createBarChart(
"年份与平均评分关系",
"年份",
"平均评分",
yearRatingDataset
);
ChartUtils.saveChartAsPNG(new File("year_rating_relation.png"), yearRatingChart, 800, 600);
System.out.println("\n图表已生成:rating_distribution.png 和 year_rating_relation.png");
} }
} }

0
W3/Movie.java → Movie.java

0
W3/MovieCrawler.java → MovieCrawler.java

169
W3/Main.java

@ -1,169 +0,0 @@
import org.jfree.chart.ChartFactory;
import org.jfree.chart.ChartUtils;
import org.jfree.chart.JFreeChart;
import org.jfree.data.category.DefaultCategoryDataset;
import org.jfree.data.general.DefaultPieDataset;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.util.*;
import java.util.stream.Collectors;
public class Main {
public static void main(String[] args) {
try {
// 1. 爬取电影数据
MovieCrawler crawler = new MovieCrawler();
List<Movie> movies = crawler.crawlTopMovies(50); // 爬取50部电影
// 2. 数据清洗
List<Movie> cleanedMovies = cleanData(movies);
// 3. 数据存储
saveToCSV(cleanedMovies, "movies.csv");
// 4. 数据分析
analyzeData(cleanedMovies);
// 5. 结果展示
displayResults(cleanedMovies);
generateCharts(cleanedMovies);
System.out.println("爬取完成!共获取了 " + cleanedMovies.size() + " 部电影数据。");
} catch (Exception e) {
e.printStackTrace();
}
}
private static List<Movie> cleanData(List<Movie> movies) {
return movies.stream()
.map(movie -> {
// 去空格
movie.setTitle(movie.getTitle().trim());
movie.setGenre(movie.getGenre().trim());
movie.setDirector(movie.getDirector().trim());
movie.setActors(movie.getActors().trim());
movie.setSynopsis(movie.getSynopsis().trim());
return movie;
})
.collect(Collectors.toList());
}
private static void saveToCSV(List<Movie> movies, String fileName) throws IOException {
try (FileWriter writer = new FileWriter(fileName)) {
// 写入表头
writer.write("Title,Year,Rating,Genre,Director,Actors,Synopsis\n");
// 写入数据
for (Movie movie : movies) {
writer.write(String.format("%s,%d,%.1f,%s,%s,%s,%s\n",
escapeCSV(movie.getTitle()),
movie.getYear(),
movie.getRating(),
escapeCSV(movie.getGenre()),
escapeCSV(movie.getDirector()),
escapeCSV(movie.getActors()),
escapeCSV(movie.getSynopsis())));
}
}
}
private static String escapeCSV(String value) {
if (value == null) return "";
if (value.contains(",") || value.contains("\n") || value.contains("\"")) {
value = value.replace("\"", "\"\"");
return "\"" + value + "\"";
}
return value;
}
private static void analyzeData(List<Movie> movies) {
System.out.println("\n=== 数据分析结果 ===");
// 1. 评分分布
System.out.println("\n1. 评分分布:");
Map<Double, Long> ratingDistribution = movies.stream()
.collect(Collectors.groupingBy(Movie::getRating, Collectors.counting()));
ratingDistribution.entrySet().stream()
.sorted(Map.Entry.comparingByKey())
.forEach(entry -> System.out.printf("评分 %.1f: %d 部\n", entry.getKey(), entry.getValue()));
// 2. 年份分布
System.out.println("\n2. 年份分布:");
Map<Integer, Long> yearDistribution = movies.stream()
.collect(Collectors.groupingBy(Movie::getYear, Collectors.counting()));
yearDistribution.entrySet().stream()
.sorted(Map.Entry.comparingByKey())
.forEach(entry -> System.out.printf("年份 %d: %d 部\n", entry.getKey(), entry.getValue()));
// 3. 导演作品数排行
System.out.println("\n3. 导演作品数排行:");
Map<String, Long> directorCount = movies.stream()
.collect(Collectors.groupingBy(Movie::getDirector, Collectors.counting()));
directorCount.entrySet().stream()
.sorted(Map.Entry.<String, Long>comparingByValue().reversed())
.limit(10)
.forEach(entry -> System.out.printf("%s: %d 部\n", entry.getKey(), entry.getValue()));
// 4. 平均评分
double averageRating = movies.stream()
.mapToDouble(Movie::getRating)
.average()
.orElse(0);
System.out.printf("\n4. 平均评分:%.2f\n", averageRating);
}
private static void displayResults(List<Movie> movies) {
System.out.println("\n=== 电影数据列表 ===");
System.out.printf("%-50s %-10s %-10s %-30s %-30s\n", "Title", "Year", "Rating", "Genre", "Director");
System.out.println("-------------------------------------------------------------------------------------------------------------------------------");
for (Movie movie : movies) {
System.out.printf("%-50s %-10d %-10.1f %-30s %-30s\n",
truncate(movie.getTitle(), 50),
movie.getYear(),
movie.getRating(),
truncate(movie.getGenre(), 30),
truncate(movie.getDirector(), 30));
}
}
private static String truncate(String text, int maxLength) {
return text.length() > maxLength ? text.substring(0, maxLength - 3) + "..." : text;
}
private static void generateCharts(List<Movie> movies) throws IOException {
// 1. 评分分布饼图
DefaultPieDataset ratingDataset = new DefaultPieDataset();
Map<Double, Long> ratingDistribution = movies.stream()
.collect(Collectors.groupingBy(Movie::getRating, Collectors.counting()));
ratingDistribution.forEach((rating, count) -> ratingDataset.setValue(String.valueOf(rating), count));
JFreeChart ratingChart = ChartFactory.createPieChart(
"电影评分分布",
ratingDataset,
true,
true,
false
);
ChartUtils.saveChartAsPNG(new File("rating_distribution.png"), ratingChart, 800, 600);
// 2. 年份与评分关系图
DefaultCategoryDataset yearRatingDataset = new DefaultCategoryDataset();
Map<Integer, Double> yearAverageRating = movies.stream()
.collect(Collectors.groupingBy(Movie::getYear,
Collectors.averagingDouble(Movie::getRating)));
yearAverageRating.forEach((year, avgRating) -> yearRatingDataset.addValue(avgRating, "评分", String.valueOf(year)));
JFreeChart yearRatingChart = ChartFactory.createBarChart(
"年份与平均评分关系",
"年份",
"平均评分",
yearRatingDataset
);
ChartUtils.saveChartAsPNG(new File("year_rating_relation.png"), yearRatingChart, 800, 600);
System.out.println("\n图表已生成:rating_distribution.png 和 year_rating_relation.png");
}
}

0
W3/Circle.java → W4/Circle.java

0
W3/QQ20260327-221432.png → W4/QQ20260327-221432.png

Before

Width:  |  Height:  |  Size: 191 KiB

After

Width:  |  Height:  |  Size: 191 KiB

0
W3/Rectangle.java → W4/Rectangle.java

0
W3/Shape.java → W4/Shape.java

0
W3/ShapeUtil.java → W4/ShapeUtil.java

0
W3/Test.java → W4/Test.java

0
W3/Triangle.java → W4/Triangle.java

0
W3/W3.txt → W4/W3.txt

0
W3/jcommon-1.0.24.jar → jcommon-1.0.24.jar

0
W3/jfreechart-1.5.4.jar → jfreechart-1.5.4.jar

0
W3/jsoup-1.17.2.jar → jsoup-1.17.2.jar

0
W3/movies.csv → movies.csv

1 Title Year Rating Genre Director Actors Synopsis
2 肖申克的救赎 1994 9.7 美国
3 霸王别姬 1993 9.6 中国大陆 中国香港
4 泰坦尼克号 1997 9.5 剧情 爱情 灾难
5 阿甘正传 1994 9.5 美国
6 千与千寻 2001 9.4 日本
7 美丽人生 1997 9.5 剧情 喜剧 爱情 战争
8 星际穿越 2014 9.4 剧情 科幻 冒险
9 这个杀手不太冷 1994 9.4 法国 美国
10 盗梦空间 2010 9.4 剧情 科幻 悬疑 冒险
11 楚门的世界 1998 9.4 美国
12 辛德勒的名单 1993 9.5 剧情 历史 战争
13 忠犬八公的故事 2009 9.4 剧情
14 海上钢琴师 1998 9.3 意大利
15 疯狂动物城 2016 9.3 美国
16 三傻大闹宝莱坞 2009 9.2 印度
17 机器人总动员 2008 9.3 美国
18 放牛班的春天 2004 9.3 剧情 音乐
19 无间道 2002 9.3 梁朝伟 Tony Leung Chiu W... 2002
20 控方证人 1957 9.6 美国
21 寻梦环游记 2017 9.1 美国
22 大话西游之大圣娶亲 1995 9.2 中国香港 中国大陆
23 熔炉 2011 9.3 ... 2011
24 触不可及 2011 9.3 法国
25 教父 1972 9.3 剧情 犯罪
26 末代皇帝 1987 9.3 英国 意大利 中国大陆 法国
27 哈利·波特与魔法石 2001 9.2 Rupert Grint 2001
28 当幸福来敲门 2006 9.1 剧情 传记 家庭
29 龙猫 1988 9.2 日本
30 活着 1994 9.3 姜武 Wu Jiang 1994
31 怦然心动 2010 9.1 美国
32 蝙蝠侠:黑暗骑士 2008 9.2 剧情 动作 科幻 犯罪 惊悚
33 指环王3:王者无敌 2003 9.3 美国 新西兰
34 我不是药神 2018 9.0 周... 2018
35 乱世佳人 1939 9.3 美国
36 飞屋环游记 2009 9.1 美国
37 让子弹飞 2010 9.0 周润发 Yun-F... 2010
38 哈尔的移动城堡 2004 9.1 日本
39 十二怒汉 1957 9.4 美国
40 海蒂和爷爷 2015 9.3 德国 瑞士
41 素媛 2013 9.3 韩国
42 猫鼠游戏 2002 9.1 传记 犯罪 剧情
43 天空之城 1986 9.2 日本
44 鬼子来了 2000 9.3 ... 2000
45 摔跤吧!爸爸 2016 9.0 印度
46 少年派的奇幻漂流 2012 9.1 美国 中国台湾 英国 加拿大
47 钢琴家 2002 9.3 剧情 传记 战争 音乐
48 指环王2:双塔奇兵 2002 9.2 美国 新西兰
49 死亡诗社 1989 9.2 美国
50 大话西游之月光宝盒 1995 9.0 中国香港 中国大陆
51 绿皮书 2018 8.9 美国 中国大陆

0
W3/rating_distribution.png → rating_distribution.png

Before

Width:  |  Height:  |  Size: 39 KiB

After

Width:  |  Height:  |  Size: 39 KiB

0
W3/year_rating_relation.png → year_rating_relation.png

Before

Width:  |  Height:  |  Size: 37 KiB

After

Width:  |  Height:  |  Size: 37 KiB

Loading…
Cancel
Save