Compare commits

...

5 Commits
main ... w5

  1. 67
      article类
  2. 57
      主程序和案例
  3. 40
      命令别名+URL工具类
  4. 24
      命令历史记录类
  5. 6
      思考题

67
article类

@ -0,0 +1,67 @@
import java.time.LocalDate;
public class Article {
private String title;
private String content;
private String url;
// 作业要求新增
private String author;
private LocalDate publishDate;
public Article() {
}
public Article(String title, String content, String url, String author, LocalDate publishDate) {
this.title = title;
this.content = content;
this.url = url;
this.author = author;
this.publishDate = publishDate;
}
// getter & setter
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getContent() {
return content;
}
public void setContent(String content) {
this.content = content;
}
public String getUrl() {
return url;
}
public void setUrl(String url) {
this.url = url;
}
public String getAuthor() {
return author;
}
public void setAuthor(String author) {
this.author = author;
}
public LocalDate getPublishDate() {
return publishDate;
}
public void setPublishDate(LocalDate publishDate) {
this.publishDate = publishDate;
}
// 打印文章信息
public void showInfo() {
System.out.println("标题:" + title);
System.out.println("作者:" + author);
System.out.println("发布日期:" + publishDate);
System.out.println("链接:" + url);
System.out.println("内容:" + content);
}
}

57
主程序和案例

@ -0,0 +1,57 @@
import java.time.LocalDate;
import java.util.Scanner;
public class MainTest {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
HistoryCommand history = new HistoryCommand();
// 实验案例1:创建Article对象测试
System.out.println("----- 实验案例1:创建并打印文章对象 -----");
Article art = new Article(
"Java入门教程",
"面向对象、集合、作业讲解",
"https://test.com/java",
"张老师",
LocalDate.of(2025,5,7)
);
art.showInfo();
System.out.println();
// 实验案例2:命令别名 + 历史记录 + URL校验 交互测试
System.out.println("----- 实验案例2:命令行交互测试 -----");
System.out.println("指令示例:c 网址、h、exit");
while(true){
System.out.print("请输入命令:");
String input = sc.nextLine().trim();
// 记录原始命令到历史
history.addCommand(input);
// 解析别名
String realCmd = CommandUtil.parseAlias(input);
System.out.println("解析后命令:" + realCmd);
// 简单指令分发
if(realCmd.startsWith("crawl")){
String[] parts = realCmd.split(" ",2);
if(parts.length >= 2){
String url = parts[1];
if(CommandUtil.checkUrl(url)){
System.out.println("URL合法,开始爬取:" + url);
}else{
System.out.println("URL格式不合法!");
}
}
}else if(realCmd.equals("history")){
// 查看历史
history.showHistory();
}else if(realCmd.equals("exit")){
System.out.println("退出程序");
break;
}
System.out.println("------------------------");
}
sc.close();
}
}

40
命令别名+URL工具类

@ -0,0 +1,40 @@
import java.util.HashMap;
import java.util.Map;
import java.util.regex.Pattern;
public class CommandUtil {
// 命令别名映射
private static Map<String,String> aliasMap;
// URL正则校验
private static final Pattern URL_REG = Pattern.compile("^https?://.+");
static {
aliasMap = new HashMap<>();
// 作业要求:别名 c 代表 crawl
aliasMap.put("c", "crawl");
// 可扩展其他别名
aliasMap.put("h", "history");
aliasMap.put("e", "exit");
}
// 解析别名,返回真实命令
public static String parseAlias(String input) {
String[] arr = input.split(" ", 2);
String cmd = arr[0];
// 如果有别名就替换
if(aliasMap.containsKey(cmd)){
cmd = aliasMap.get(cmd);
}
// 拼接参数
if(arr.length > 1){
return cmd + " " + arr[1];
}
return cmd;
}
// 校验URL是否合法
public static boolean checkUrl(String url) {
if(url == null || url.isBlank()) return false;
return URL_REG.matcher(url).matches();
}
}

24
命令历史记录类

@ -0,0 +1,24 @@
import java.util.ArrayList;
import java.util.List;
public class HistoryCommand {
// 用List保存所有输入过的命令
private List<String> cmdList;
public HistoryCommand() {
cmdList = new ArrayList<>();
}
// 添加命令到历史
public void addCommand(String cmd) {
cmdList.add(cmd);
}
// 打印全部历史命令
public void showHistory() {
System.out.println("===== 命令历史记录 =====");
for (int i = 0; i < cmdList.size(); i++) {
System.out.println((i+1) + ". " + cmdList.get(i));
}
}
}

6
思考题

@ -0,0 +1,6 @@
当多个模块共享同一个 List<Article> 引用时,会存在多方面风险:
1. 线程安全问题:若多线程同时读写该列表,会出现并发修改异常、数据不一致,甚至数据损坏。
2. 数据污染:一个模块对列表或内部 Article 对象的修改(如修改 title)会直接影响所有持有该引用的模块,导致数据意外变更。
3. 封装性破坏:外部代码可直接修改列表结构(add/remove),违背了数据封装原则,难以追踪数据变更来源。
4. 内存泄漏:若列表被静态或长生命周期对象持有,内部的 Article 对象无法被GC回收,造成内存泄漏。
建议通过返回不可修改视图、拷贝副本或使用线程安全集合来规避风险。
Loading…
Cancel
Save