From 96e171c9967b2cae415c9076788a04a205e6486c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=95=85=E6=98=A5?= <3481369387@qq.com> Date: Sat, 28 Mar 2026 01:01:15 +0800 Subject: [PATCH] =?UTF-8?q?=E6=B7=BB=E5=8A=A0W3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- W3/Car.java | 96 +++++++++++++++++++++++++++ W3/Main.java | 180 ++++++--------------------------------------------- 2 files changed, 114 insertions(+), 162 deletions(-) create mode 100644 W3/Car.java diff --git a/W3/Car.java b/W3/Car.java new file mode 100644 index 0000000..58c8584 --- /dev/null +++ b/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 + " 万"); + } +} \ No newline at end of file diff --git a/W3/Main.java b/W3/Main.java index 51537f5..7ee5440 100644 --- a/W3/Main.java +++ b/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 static void main(String[] args) { - try { - // 1. 爬取电影数据 - MovieCrawler crawler = new MovieCrawler(); - List movies = crawler.crawlTopMovies(50); // 爬取50部电影 - - // 2. 数据清洗 - List 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 cleanData(List 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 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; - } + // 测试 1:无参构造 + Car car1 = new Car(); + car1.showInfo(); - private static void analyzeData(List movies) { - System.out.println("\n=== 数据分析结果 ==="); - - // 1. 评分分布 - System.out.println("\n1. 评分分布:"); - Map 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 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 directorCount = movies.stream() - .collect(Collectors.groupingBy(Movie::getDirector, Collectors.counting())); - directorCount.entrySet().stream() - .sorted(Map.Entry.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); - } + // 测试 2:带参构造(品牌+型号) + Car car2 = new Car("Toyota", "Camry"); + car2.showInfo(); - private static void displayResults(List 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)); - } - } + // 测试 3:全参构造(合法数据) + Car car3 = new Car("Tesla", "Model 3", 2024, 28.9); + car3.showInfo(); - private static String truncate(String text, int maxLength) { - return text.length() > maxLength ? text.substring(0, maxLength - 3) + "..." : text; - } + // 测试 4:全参构造(非法数据,触发校验) + Car car4 = new Car("BYD", "Han", 1899, -20.0); + car4.showInfo(); - private static void generateCharts(List movies) throws IOException { - // 1. 评分分布饼图 - DefaultPieDataset ratingDataset = new DefaultPieDataset(); - Map 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 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"); + // 测试 5:通过 setter 修改并校验 + car4.setYear(2025); + car4.setPrice(25.9); + System.out.println("修改后:"); + car4.showInfo(); } -} +} \ No newline at end of file