Browse Source

添加W3

main
故春 3 weeks ago
parent
commit
96e171c996
  1. 96
      W3/Car.java
  2. 180
      W3/Main.java

96
W3/Car.java

@ -0,0 +1,96 @@
public class Car {
// 1. 私有成员变量(封装核心:隐藏内部数据)
private String brand; // 品牌
private String model; // 型号
private int year; // 生产年份
private double price; // 价格
// 2. 无参构造方法(构造方法重载 1)
public Car() {
// 默认值
this.brand = "未知品牌";
this.model = "未知型号";
this.year = 2020;
this.price = 0.0;
}
// 3. 带参构造方法(构造方法重载 2:只传入品牌和型号)
public Car(String brand, String model) {
this.brand = brand;
this.model = model;
this.year = 2020; // 默认年份
this.price = 0.0; // 默认价格
}
// 4. 全参构造方法(构造方法重载 3:传入所有属性,含数据校验)
public Car(String brand, String model, int year, double price) {
this.brand = brand;
this.model = model;
// 数据校验:年份必须在 1900~2026 之间
if (year >= 1900 && year <= 2026) {
this.year = year;
} else {
System.out.println("年份输入不合法,已设置为默认值 2020");
this.year = 2020;
}
// 数据校验:价格不能为负数
if (price >= 0) {
this.price = price;
} else {
System.out.println("价格输入不合法,已设置为默认值 0.0");
this.price = 0.0;
}
}
// 5. 公共 getter/setter 方法(封装核心:提供受控访问)
public String getBrand() {
return brand;
}
public void setBrand(String brand) {
this.brand = brand;
}
public String getModel() {
return model;
}
public void setModel(String model) {
this.model = model;
}
public int getYear() {
return year;
}
public void setYear(int year) {
// 校验年份
if (year >= 1900 && year <= 2026) {
this.year = year;
} else {
System.out.println("年份输入不合法,未修改");
}
}
public double getPrice() {
return price;
}
public void setPrice(double price) {
// 校验价格
if (price >= 0) {
this.price = price;
} else {
System.out.println("价格输入不合法,未修改");
}
}
// 6. 显示车辆信息的方法
public void showInfo() {
System.out.println("=== 车辆信息 ===");
System.out.println("品牌:" + this.brand);
System.out.println("型号:" + this.model);
System.out.println("生产年份:" + this.year);
System.out.println("价格:" + this.price + " 万");
}
}

180
W3/Main.java

@ -1,169 +1,25 @@
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) {
try { // 测试 1:无参构造
// 1. 爬取电影数据 Car car1 = new Car();
MovieCrawler crawler = new MovieCrawler(); car1.showInfo();
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) { // 测试 2:带参构造(品牌+型号)
System.out.println("\n=== 数据分析结果 ==="); Car car2 = new Car("Toyota", "Camry");
car2.showInfo();
// 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) { // 测试 3:全参构造(合法数据)
System.out.println("\n=== 电影数据列表 ==="); Car car3 = new Car("Tesla", "Model 3", 2024, 28.9);
System.out.printf("%-50s %-10s %-10s %-30s %-30s\n", "Title", "Year", "Rating", "Genre", "Director"); car3.showInfo();
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) { // 测试 4:全参构造(非法数据,触发校验)
return text.length() > maxLength ? text.substring(0, maxLength - 3) + "..." : text; Car car4 = new Car("BYD", "Han", 1899, -20.0);
} car4.showInfo();
private static void generateCharts(List<Movie> movies) throws IOException { // 测试 5:通过 setter 修改并校验
// 1. 评分分布饼图 car4.setYear(2025);
DefaultPieDataset ratingDataset = new DefaultPieDataset(); car4.setPrice(25.9);
Map<Double, Long> ratingDistribution = movies.stream() System.out.println("修改后:");
.collect(Collectors.groupingBy(Movie::getRating, Collectors.counting())); car4.showInfo();
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");
} }
} }
Loading…
Cancel
Save