commit e8c50a3d78de89eb102f464f17b6083ecbbd051d Author: xuxin <840198532@qq.com> Date: Sun Dec 21 17:24:54 2025 +0800 init diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..01ed9e0 --- /dev/null +++ b/.gitignore @@ -0,0 +1,39 @@ +# 忽略任意目录层级下的 .iml 文件(核心规则) +**/*.iml + +# 保留 IDEA 其他核心忽略项(完整配置如下) +# --------------------------- IntelliJ IDEA 相关 --------------------------- +.idea/ +*.iws +*.ipr +out/ +*.idea_modules/ +.idea/misc.xml +.idea/workspace.xml +.idea/tasks.xml +.idea/gradle.xml +.idea/dictionaries +.idea/libraries +.idea/runConfigurations/ +.idea/shelf/ +.idea/vcs.xml + +# --------------------------- Java 项目通用 --------------------------- +*.class +*.jar +*.war +*.ear +*.tmp +*.bak +*.swp +target/ +build/ +.gradle/ +gradle-app.setting +!gradle-wrapper.jar +*.properties +!*.example.properties +logs/ +*.log +.DS_Store +Thumbs.db \ No newline at end of file diff --git a/a.txt b/a.txt new file mode 100644 index 0000000..abae0e0 --- /dev/null +++ b/a.txt @@ -0,0 +1,3 @@ +我是谁 +我在哪 +我在干嘛 \ No newline at end of file diff --git a/aa.jpg b/aa.jpg new file mode 100644 index 0000000..21ade94 Binary files /dev/null and b/aa.jpg differ diff --git a/bb.jpg b/bb.jpg new file mode 100644 index 0000000..21ade94 Binary files /dev/null and b/bb.jpg differ diff --git a/cc.jpg b/cc.jpg new file mode 100644 index 0000000..21ade94 Binary files /dev/null and b/cc.jpg differ diff --git a/csb.txt b/csb.txt new file mode 100644 index 0000000..4be9ca0 --- /dev/null +++ b/csb.txt @@ -0,0 +1,9 @@ +3.侍中、侍郎郭攸之、费祎、董允等,此皆良实,志虑忠纯,是以先帝简拔以遗陛下。愚以为宫中之事,事无大小,悉以咨之,然后施行,必得裨补阙漏,有所广益。 +8.愿陛下托臣以讨贼兴复之效,不效,则治臣之罪,以告先帝之灵。若无兴德之言,则责攸之、祎、允等之慢,以彰其咎;陛下亦宜自谋,以咨诹善道,察纳雅言,深追先帝遗诏,臣不胜受恩感激。 +4.将军向宠,性行淑均,晓畅军事,试用之于昔日,先帝称之曰能,是以众议举宠为督。愚以为营中之事,悉以咨之,必能使行阵和睦,优劣得所。 +2.宫中府中,俱为一体,陟罚臧否,不宜异同。若有作奸犯科及为忠善者,宜付有司论其刑赏,以昭陛下平明之理,不宜偏私,使内外异法也。 +1.先帝创业未半而中道崩殂,今天下三分,益州疲弊,此诚危急存亡之秋也。然侍卫之臣不懈于内,忠志之士忘身于外者,盖追先帝之殊遇,欲报之于陛下也。诚宜开张圣听,以光先帝遗德,恢弘志士之气,不宜妄自菲薄,引喻失义,以塞忠谏之路也。 +9.今当远离,临表涕零,不知所言。 +6.臣本布衣,躬耕于南阳,苟全性命于乱世,不求闻达于诸侯。先帝不以臣卑鄙,猥自枉屈,三顾臣于草庐之中,咨臣以当世之事,由是感激,遂许先帝以驱驰。后值倾覆,受任于败军之际,奉命于危难之间,尔来二十有一年矣。 +7.先帝知臣谨慎,故临崩寄臣以大事也。受命以来,夙夜忧叹,恐付托不效,以伤先帝之明,故五月渡泸,深入不毛。今南方已定,兵甲已足,当奖率三军,北定中原,庶竭驽钝,攘除奸凶,兴复汉室,还于旧都。此臣所以报先帝而忠陛下之职分也。至于斟酌损益,进尽忠言,则攸之、祎、允之任也。 +5.亲贤臣,远小人,此先汉所以兴隆也;亲小人,远贤臣,此后汉所以倾颓也。先帝在时,每与臣论此事,未尝不叹息痛恨于桓、灵也。侍中、尚书、长史、参军,此悉贞良死节之臣,愿陛下亲之信之,则汉室之隆,可计日而待也 \ No newline at end of file diff --git a/csb1.txt b/csb1.txt new file mode 100644 index 0000000..5b3cedd --- /dev/null +++ b/csb1.txt @@ -0,0 +1,9 @@ +1.先帝创业未半而中道崩殂,今天下三分,益州疲弊,此诚危急存亡之秋也。然侍卫之臣不懈于内,忠志之士忘身于外者,盖追先帝之殊遇,欲报之于陛下也。诚宜开张圣听,以光先帝遗德,恢弘志士之气,不宜妄自菲薄,引喻失义,以塞忠谏之路也。 +2.宫中府中,俱为一体,陟罚臧否,不宜异同。若有作奸犯科及为忠善者,宜付有司论其刑赏,以昭陛下平明之理,不宜偏私,使内外异法也。 +3.侍中、侍郎郭攸之、费祎、董允等,此皆良实,志虑忠纯,是以先帝简拔以遗陛下。愚以为宫中之事,事无大小,悉以咨之,然后施行,必得裨补阙漏,有所广益。 +4.将军向宠,性行淑均,晓畅军事,试用之于昔日,先帝称之曰能,是以众议举宠为督。愚以为营中之事,悉以咨之,必能使行阵和睦,优劣得所。 +5.亲贤臣,远小人,此先汉所以兴隆也;亲小人,远贤臣,此后汉所以倾颓也。先帝在时,每与臣论此事,未尝不叹息痛恨于桓、灵也。侍中、尚书、长史、参军,此悉贞良死节之臣,愿陛下亲之信之,则汉室之隆,可计日而待也 +6.臣本布衣,躬耕于南阳,苟全性命于乱世,不求闻达于诸侯。先帝不以臣卑鄙,猥自枉屈,三顾臣于草庐之中,咨臣以当世之事,由是感激,遂许先帝以驱驰。后值倾覆,受任于败军之际,奉命于危难之间,尔来二十有一年矣。 +7.先帝知臣谨慎,故临崩寄臣以大事也。受命以来,夙夜忧叹,恐付托不效,以伤先帝之明,故五月渡泸,深入不毛。今南方已定,兵甲已足,当奖率三军,北定中原,庶竭驽钝,攘除奸凶,兴复汉室,还于旧都。此臣所以报先帝而忠陛下之职分也。至于斟酌损益,进尽忠言,则攸之、祎、允之任也。 +8.愿陛下托臣以讨贼兴复之效,不效,则治臣之罪,以告先帝之灵。若无兴德之言,则责攸之、祎、允等之慢,以彰其咎;陛下亦宜自谋,以咨诹善道,察纳雅言,深追先帝遗诏,臣不胜受恩感激。 +9.今当远离,临表涕零,不知所言。 diff --git a/day01/books-schema.xml b/day01/books-schema.xml new file mode 100644 index 0000000..99565d5 --- /dev/null +++ b/day01/books-schema.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/day01/books.dtd b/day01/books.dtd new file mode 100644 index 0000000..932ea66 --- /dev/null +++ b/day01/books.dtd @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/day01/books.xml b/day01/books.xml new file mode 100644 index 0000000..5daa7ea --- /dev/null +++ b/day01/books.xml @@ -0,0 +1,25 @@ + + + + + + + + + java入门到精通 + 999 + 小王 + + + 数据库从删库到跑路 + 666 + 老王 + + \ No newline at end of file diff --git a/day01/books1.xsd b/day01/books1.xsd new file mode 100644 index 0000000..783a72e --- /dev/null +++ b/day01/books1.xsd @@ -0,0 +1,26 @@ + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/day01/src/com/inmind/ChildClass.java b/day01/src/com/inmind/ChildClass.java new file mode 100644 index 0000000..7a35cfa --- /dev/null +++ b/day01/src/com/inmind/ChildClass.java @@ -0,0 +1,4 @@ +package com.inmind; + +public class ChildClass { +} diff --git a/day01/src/com/inmind/Demo01.java b/day01/src/com/inmind/Demo01.java new file mode 100644 index 0000000..2c5bde5 --- /dev/null +++ b/day01/src/com/inmind/Demo01.java @@ -0,0 +1,92 @@ +package com.inmind; + +public class Demo01 { + public static void main(String[] args) { + // 假设 player1 和 player2 已经初始化 + Player player1 = new Player("y", "qfz", 22, new Weapon("AK47", 36, 28)); + Player player2 = new Player("s", "bwz", 16, new Weapon("M4A1", 36, 28)); + + // 打印对战结果 + System.out.println("\n===== 第8回合 ====="); + System.out.println("潜伏者 影 使用 AK47 向保卫者 隼 开火!"); + System.out.println("AK47剩余弹药: (28/36)"); + System.out.println("未命中"); + + System.out.println("保卫者 隼 使用 M4A1 向潜伏者 影 开火!"); + System.out.println("M4A1剩余弹药: (28/36)"); + System.out.println("保卫者 隼 使用 M4A1 对潜伏者 影 造成了 39 点伤害"); + player1.setCurrentHealth(player1.getCurrentHealth() - 39); + System.out.println("潜伏者 影受到 39 点伤害 剩余血量为: " + player1.getCurrentHealth()); + + // 显示当前状态 + System.out.println("\n【当前状态】"); + System.out.printf("| %-8s | %-8s | %-9s |\n", "player-X", "smz", "dqwq"); + System.out.printf("| %-8s | %-8d | %-9s |\n", + player1.getFaction() + "-" + player1.getName(), + player1.getCurrentHealth(), + player1.getCurrentWeapon().getName()); + System.out.printf("| %-8s | %-8d | %-9s |\n", + player2.getFaction() + "-" + player2.getName(), + player2.getCurrentHealth(), + player2.getCurrentWeapon().getName()); + + // 战斗结果 + System.out.println("\n===== 战斗结束! ====="); + Player winner = player1.isEliminated() ? player2 : player1; + System.out.println("胜者: " + winner.getFaction() + "-" + winner.getName()); + } +} + +class Player { + private String name; + private String faction; + private int currentHealth; + private Weapon currentWeapon; + + public Player(String name, String faction, int currentHealth, Weapon currentWeapon) { + this.name = name; + this.faction = faction; + this.currentHealth = currentHealth; + this.currentWeapon = currentWeapon; + } + + public String getName() { + return name; + } + + public String getFaction() { + return faction; + } + + public int getCurrentHealth() { + return currentHealth; + } + + public void setCurrentHealth(int currentHealth) { + this.currentHealth = currentHealth; + } + + public Weapon getCurrentWeapon() { + return currentWeapon; + } + + public boolean isEliminated() { + return currentHealth <= 0; + } +} + +class Weapon { + private String name; + private int maxAmmo; + private int currentAmmo; + + public Weapon(String name, int maxAmmo, int currentAmmo) { + this.name = name; + this.maxAmmo = maxAmmo; + this.currentAmmo = currentAmmo; + } + + public String getName() { + return name; + } +} \ No newline at end of file diff --git a/day01/src/com/inmind/Demo02.java b/day01/src/com/inmind/Demo02.java new file mode 100644 index 0000000..a0fff23 --- /dev/null +++ b/day01/src/com/inmind/Demo02.java @@ -0,0 +1,25 @@ +package com.inmind; + +public class Demo02 { + public static void main(String[] args) { + /* String a = "abc"; + String b = "ab"; + String c = ""; + for (int i = 0; i < 1000000; i++) { + c+=a+b; + } + System.out.println(c);*/ + method(); + } + + public static void method() { + String a = "abc"; + String b = "ab"; + + StringBuilder sb = new StringBuilder(); + for (int i = 0; i < 1000000; i++) { + sb.append(a).append(b); + } + System.out.println(sb); + } +} diff --git a/day01/src/com/inmind/DemoMethod.java b/day01/src/com/inmind/DemoMethod.java new file mode 100644 index 0000000..35ce04c --- /dev/null +++ b/day01/src/com/inmind/DemoMethod.java @@ -0,0 +1,45 @@ +package com.inmind; +/* + 方法的定义格式 + 修饰符 返回值类型 方法名(参数列表){ + 方法体; + } + + a. 修饰符 public static (固定) + b. 返回值类型: + 没有返回值:void + 有返回值:基本数据类型(4类型八种) + c.方法名:标识符(硬性要求,软性建议小驼峰) + d.():参数列表 + 如果没有参数() + 如果有参数,直接在()定义 + 2个int参数(int a,int b) + e.方法体:java代码的集合 + 在方法中可以使用关键return,就是结束当前方法,并且,如果有返回值,直接在 + return之后 编写。将return后的值,返回到方法调用处。 + + 方法定义的2个明确: + 1.明确返回值类型 + 2.明确参数列表 + + 案例:定义一个方法,实现2个整数值的相加操作,并将和值返回 + */ +public class DemoMethod { + public static void main(String[] args) { + MyInterfaceImpl myInterface = new MyInterfaceImpl(); + myInterface.method(); + myInterface.method2(); + } + + /** + * + * @param a + * @param b + * @return + */ + public static int getSum(int a,int b){ + int sum = a+b; + return sum; + } + +} diff --git a/day01/src/com/inmind/FinalClass.java b/day01/src/com/inmind/FinalClass.java new file mode 100644 index 0000000..79c9a51 --- /dev/null +++ b/day01/src/com/inmind/FinalClass.java @@ -0,0 +1,4 @@ +package com.inmind; + +public final class FinalClass { +} diff --git a/day01/src/com/inmind/ForTest.java b/day01/src/com/inmind/ForTest.java new file mode 100644 index 0000000..ab2d28b --- /dev/null +++ b/day01/src/com/inmind/ForTest.java @@ -0,0 +1,24 @@ +package com.inmind; + +public class ForTest { + public static void main(String[] args) { + printJiuJiu(); + } + + public static void printJiuJiu() { + /* + 方法_回顾_打印九九乘法表 + 11 + 12 22 + 13 23 33 + 14 24 34 44 + */ + for (int i = 1; i < 10; i++) { +// System.out.println(i); + for (int j = 1; j <= i ; j++) { + System.out.print(j+"*"+i+"="+(i*j)+" "); + } + System.out.println(); + } + } +} diff --git a/day01/src/com/inmind/HelloWorld.java b/day01/src/com/inmind/HelloWorld.java new file mode 100644 index 0000000..809cb80 --- /dev/null +++ b/day01/src/com/inmind/HelloWorld.java @@ -0,0 +1,20 @@ +package com.inmind; + +import java.util.Scanner; + +public class HelloWorld { + public static void main(String[] args) { + System.out.println("Hello World"); + + if (2 > 1) { + + } + + int a = 1; + + int b = 2; + + int c = 3; + + } +} diff --git a/day01/src/com/inmind/MyInterfaceDefault.java b/day01/src/com/inmind/MyInterfaceDefault.java new file mode 100644 index 0000000..aa19144 --- /dev/null +++ b/day01/src/com/inmind/MyInterfaceDefault.java @@ -0,0 +1,9 @@ +package com.inmind; + +public interface MyInterfaceDefault { + public static final int i = 10; + void method(); + default void method2() { + System.out.println("method2"); + } +} diff --git a/day01/src/com/inmind/MyInterfaceImpl.java b/day01/src/com/inmind/MyInterfaceImpl.java new file mode 100644 index 0000000..9f11a7c --- /dev/null +++ b/day01/src/com/inmind/MyInterfaceImpl.java @@ -0,0 +1,14 @@ +package com.inmind; + +public class MyInterfaceImpl implements MyInterfaceDefault{ + @Override + public void method() { + + } + + @Override + public void method2() { + MyInterfaceDefault.super.method2(); + System.out.println("实现类的method2方法"); + } +} diff --git a/day01/src/com/inmind/SystemDemo.java b/day01/src/com/inmind/SystemDemo.java new file mode 100644 index 0000000..992583a --- /dev/null +++ b/day01/src/com/inmind/SystemDemo.java @@ -0,0 +1,27 @@ +package com.inmind; + +import java.util.Date; +import java.util.StringJoiner; + +public class SystemDemo { + public static void main(String[] args) { + // 获取 Java 版本 + String javaVersion = System.getProperty("java.version"); + // 获取操作系统名称 + String osName = System.getProperty("os.name"); + // 获取环境变量 PATH + String path = System.getenv("PATH"); + String ossID = System.getenv("OSS_ACCESS_KEY_ID"); + + System.out.println(javaVersion); + System.out.println(osName); + System.out.println(path); + System.out.println(ossID); + + new Date(); + + new StringJoiner(","); + + System.out.println(System.currentTimeMillis()); + } +} diff --git a/day01/src/com/inmind/TreeSetDemo.java b/day01/src/com/inmind/TreeSetDemo.java new file mode 100644 index 0000000..b08c356 --- /dev/null +++ b/day01/src/com/inmind/TreeSetDemo.java @@ -0,0 +1,86 @@ +package com.inmind; + +import java.util.TreeSet; +import java.util.Comparator; +import java.util.Iterator; + +public class TreeSetDemo { + public static void main(String[] args) { + // 1. 创建 TreeSet(默认自然排序) + TreeSet set1 = new TreeSet<>(); + + // 2. 创建 TreeSet(指定比较器,如降序排序) + TreeSet set2 = new TreeSet<>(Comparator.reverseOrder()); + + // 3. 添加元素(add()) + set1.add(3); + set1.add(1); + set1.add(2); + set1.add(2); // 重复元素,添加失败 + System.out.println(set1); // 输出:[1, 2, 3](自动排序) + + // 4. 删除元素(remove()) + set1.remove(2); + System.out.println(set1); // 输出:[1, 3] + + // 5. 判断元素是否存在(contains()) + boolean has3 = set1.contains(3); + System.out.println(has3); // 输出:true + + // 6. 获取集合大小(size()) + int size = set1.size(); + System.out.println(size); // 输出:2 + + // 7. 清空集合(clear()) + // set1.clear(); + + // 8. 迭代元素(升序) + System.out.print("升序迭代:"); + for (Integer num : set1) { + System.out.print(num + " "); + } + + // 9. 降序迭代(descendingIterator()) + System.out.print("\n降序迭代:"); + Iterator it = set1.descendingIterator(); + while (it.hasNext()) { + System.out.print(it.next() + " "); + } + + // 10. 获取第一个元素(first()) + Integer first = set1.first(); + System.out.println("\n第一个元素:" + first); // 输出:1 + + // 11. 获取最后一个元素(last()) + Integer last = set1.last(); + System.out.println("最后一个元素:" + last); // 输出:3 + + // 12. 获取小于指定元素的最大元素(lower()) + Integer lower = set1.lower(3); + System.out.println("小于3的最大元素:" + lower); // 输出:1 + + // 13. 获取小于等于指定元素的最大元素(floor()) + Integer floor = set1.floor(3); + System.out.println("小于等于3的最大元素:" + floor); // 输出:3 + + // 14. 获取大于指定元素的最小元素(higher()) + Integer higher = set1.higher(1); + System.out.println("大于1的最小元素:" + higher); // 输出:3 + + // 15. 获取大于等于指定元素的最小元素(ceiling()) + Integer ceiling = set1.ceiling(1); + System.out.println("大于等于1的最小元素:" + ceiling); // 输出:1 + + // 16. 截取子集合(headSet():小于指定元素) + TreeSet headSet = (TreeSet) set1.headSet(3); + System.out.println("小于3的子集合:" + headSet); // 输出:[1] + + // 17. 截取子集合(tailSet():大于等于指定元素) + TreeSet tailSet = (TreeSet) set1.tailSet(1); + System.out.println("大于等于1的子集合:" + tailSet); // 输出:[1, 3] + + // 18. 截取子集合(subSet():大于等于fromElement,小于toElement) + TreeSet subSet = (TreeSet) set1.subSet(1, 3); + System.out.println("子集合[1,3):" + subSet); // 输出:[1] + } +} \ No newline at end of file diff --git a/day01/src/com/inmind/TreeSetDemo1.java b/day01/src/com/inmind/TreeSetDemo1.java new file mode 100644 index 0000000..929ad19 --- /dev/null +++ b/day01/src/com/inmind/TreeSetDemo1.java @@ -0,0 +1,42 @@ +package com.inmind; + +import com.inmind.test07.Student; + +import java.util.Comparator; +import java.util.Iterator; +import java.util.TreeMap; +import java.util.TreeSet; + +public class TreeSetDemo1 { + public static void main(String[] args) { + TreeSet treeSet = new TreeSet<>(new Comparator() { + + @Override + public int compare(Student o1, Student o2) { + return o2.getId() - o1.getId(); + } + }); + Student s1 = new Student(); + s1.setId(1); + Student s2 = new Student(); + s2.setId(3); + Student s3 = new Student(); + s3.setId(5); + treeSet.add(s1); + treeSet.add(s2); + treeSet.add(s3); + System.out.println(treeSet); + + TreeMap treeMap = new TreeMap<>(new Comparator() { + @Override + public int compare(Student o1, Student o2) { + return o2.getId() - o1.getId(); + } + }); + treeMap.put(s1, ""); + treeMap.put(s2, ""); + treeMap.put(s3, ""); + + System.out.println(treeMap); + } +} \ No newline at end of file diff --git a/day01/src/com/inmind/logback/LogBackTest.java b/day01/src/com/inmind/logback/LogBackTest.java new file mode 100644 index 0000000..e985c76 --- /dev/null +++ b/day01/src/com/inmind/logback/LogBackTest.java @@ -0,0 +1,33 @@ +package com.inmind.logback; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class LogBackTest { + + //创建一个logger日志对象 + public static final Logger LOGGER = LoggerFactory.getLogger("LogBackTest"); + + public static void main(String[] args) { + while (true) { + try{ + LOGGER.info("chiufa方法开始执行了~~~~"); + chufa(10,0); + LOGGER.info("chiufa方法执行成功了~~~~"); + }catch (Exception e){ + LOGGER.error("chiufa方法执行失败了,出现了异常~~~~"); + // e.printStackTrace(); + } + } + } + + public static void chufa(int a,int b) { + //记录程序方法的执行流程 + LOGGER.debug("参数a:"+a); + LOGGER.debug("参数b:"+b); + int c = a/b; + //System.out.println("结果是:"+c);(下面使用了LOGGER,这里就不用sout了) + //结果比较重要使用info + LOGGER.info("结果是:"+c); + } +} diff --git a/day01/src/com/inmind/s_test055/ExceptionDemo.java b/day01/src/com/inmind/s_test055/ExceptionDemo.java new file mode 100644 index 0000000..ae52e4d --- /dev/null +++ b/day01/src/com/inmind/s_test055/ExceptionDemo.java @@ -0,0 +1,131 @@ +package com.inmind.s_test055; + +// 1. 支付失败异常类,继承自Exception(受检异常) +class PaymentFailedException extends Exception { + // 业务字段:存储异常相关的订单号,用于后续问题定位 + private String orderId; + // 业务字段:存储异常涉及的支付金额,方便业务分析 + private double amount; + // 业务字段:存储业务系统内部定义的错误码(如PAY001、PAY002) + private String errorCode; + + // 构造方法:初始化异常信息和业务上下文数据 + // 参数说明: + // message:异常的描述信息 + // orderId:关联的订单编号 + // amount:涉及的支付金额 + // errorCode:业务错误编码 + public PaymentFailedException(String message, String orderId, + double amount, String errorCode) { + super(message); // 调用父类Exception的构造方法,传递异常描述 + this.orderId = orderId; // 初始化订单号字段 + this.amount = amount; // 初始化支付金额字段 + this.errorCode = errorCode;// 初始化错误码字段 + } + + // 获取订单号的getter方法,供上层代码获取异常关联的订单信息 + public String getOrderId() { + return orderId; + } + + // 获取支付金额的getter方法,供上层代码获取异常涉及的金额 + public double getAmount() { + return amount; + } + + // 获取业务错误码的getter方法,供上层代码根据错误码执行不同逻辑 + public String getErrorCode() { + return errorCode; + } + + // 生成面向业务的异常消息,整合所有上下文信息 + // 格式化为适合业务人员理解的字符串 + public String getBusinessMessage() { + // 使用String.format拼接包含订单号、金额、错误码和原因的完整消息 + return String.format("订单[%s]支付失败(金额:%.2f),错误码:%s,原因:%s", + orderId, amount, errorCode, getMessage()); + } + + // 记录业务异常日志的方法,统一异常日志格式 + public void logToBusinessSystem() { + // 实际项目中会使用日志框架(如Logback),此处简化为控制台输出 + // 输出包含业务标识的日志,便于后续排查问题 + System.out.println("[业务日志] " + getBusinessMessage()); + } +} + +// 2. 订单不存在异常类,继承自Exception +class OrderNotFoundException extends Exception { + // 业务字段:存储不存在的订单号 + private String orderId; + + // 构造方法:接收异常消息和订单号 + public OrderNotFoundException(String message, String orderId) { + super(message); // 调用父类构造方法 + this.orderId = orderId; // 初始化订单号字段 + } + + // 获取订单号的getter方法 + public String getOrderId() { + return orderId; + } + + // 生成业务友好的异常描述 + public String getBusinessInfo() { + return "订单查询异常:订单号[" + orderId + "]不存在," + getMessage(); + } +} + +// 异常使用示例类 +public class ExceptionDemo { + // 主方法:测试异常的抛出和处理 + public static void main(String[] args) { + try { + // 调用支付处理方法,可能抛出自定义异常 + processPayment("ORDER123456", 500.0); + } + // 捕获支付失败异常 + catch (PaymentFailedException e) { + // 1. 获取业务消息并展示给用户 + System.out.println("用户提示:" + e.getBusinessMessage()); + // 2. 记录业务日志 + e.logToBusinessSystem(); + // 3. 根据错误码执行不同的补救逻辑 + if ("PAY001".equals(e.getErrorCode())) { + System.out.println("系统处理:执行余额不足的补救流程..."); + } + } + // 捕获订单不存在异常 + catch (OrderNotFoundException e) { + System.out.println("处理异常:" + e.getBusinessInfo()); + } + // 捕获其他未预料的异常 + catch (Exception e) { + System.out.println("发生未知错误:" + e.getMessage()); + } + } + + // 模拟支付处理方法 + private static void processPayment(String orderId, double amount) + throws PaymentFailedException, OrderNotFoundException { + // 模拟检查订单是否存在 + if (!isOrderExists(orderId)) { + // 订单不存在时抛出对应的异常 + throw new OrderNotFoundException("数据库中未查询到该订单", orderId); + } + + // 模拟支付处理逻辑,此处假设支付失败 + boolean paymentSuccess = false; + if (!paymentSuccess) { + // 支付失败时抛出自定义异常,携带完整业务上下文 + throw new PaymentFailedException("账户余额不足", + orderId, amount, "PAY001"); + } + } + + // 模拟检查订单是否存在的方法 + private static boolean isOrderExists(String orderId) { + // 此处简化逻辑,假设ORDER123是不存在的订单 + return !"ORDER123".equals(orderId); + } +} diff --git a/day01/src/com/inmind/s_test08/FileManager.java b/day01/src/com/inmind/s_test08/FileManager.java new file mode 100644 index 0000000..782ec75 --- /dev/null +++ b/day01/src/com/inmind/s_test08/FileManager.java @@ -0,0 +1,483 @@ +package com.inmind.s_test08; + +import java.io.File; +import java.io.FilenameFilter; +import java.text.SimpleDateFormat; +import java.util.ArrayList; +import java.util.Date; +import java.util.List; +import java.util.Scanner; +import java.util.stream.Collectors; + +public class FileManager { + private static Scanner scanner = new Scanner(System.in); + private static SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); + private static String currentPath; + + public static void main(String[] args) { + // 初始化当前路径为用户主目录 + currentPath = System.getProperty("user.home"); + showMainMenu(); + } + + // 显示主菜单 + private static void showMainMenu() { + while (true) { + System.out.println("\n===== 文件管理工具 ====="); + System.out.println("当前路径: " + currentPath); + System.out.println("1. 浏览当前目录"); + System.out.println("2. 切换目录"); + System.out.println("3. 创建新文件"); + System.out.println("4. 创建新目录"); + System.out.println("5. 删除文件/目录"); + System.out.println("6. 搜索文件"); + System.out.println("7. 文件统计信息"); + System.out.println("8. 批量操作"); + System.out.println("9. 退出"); + System.out.print("请选择操作: "); + + int choice; + try { + choice = Integer.parseInt(scanner.nextLine()); + if (choice < 1 || choice > 9) { + System.out.println("请输入1-9之间的数字!"); + continue; + } + } catch (NumberFormatException e) { + System.out.println("请输入有效的数字!"); + continue; + } + + switch (choice) { + case 1: + browseCurrentDirectory(); + break; + case 2: + changeDirectory(); + break; + case 3: + createNewFile(); + break; + case 4: + createNewDirectory(); + break; + case 5: + deleteFileOrDirectory(); + break; + case 6: + searchFiles(); + break; + case 7: + showFileStatistics(); + break; + case 8: + batchOperations(); + break; + case 9: + System.out.println("谢谢使用,再见!"); + scanner.close(); + return; + } + } + } + + // 浏览当前目录 + private static void browseCurrentDirectory() { + File currentDir = new File(currentPath); + + if (!currentDir.exists() || !currentDir.isDirectory()) { + System.out.println("当前目录不存在或不是一个有效的目录!"); + return; + } + + System.out.println("\n===== 浏览目录: " + currentPath + " ====="); + System.out.println("目录项列表:"); + System.out.println("------------------------------------------------"); + System.out.printf("%-4s %-40s %-12s %-20s%n", "类型", "名称", "大小", "修改时间"); + System.out.println("------------------------------------------------"); + + File[] files = currentDir.listFiles(); + if (files == null || files.length == 0) { + System.out.println("当前目录为空"); + return; + } + + // 先显示目录,再显示文件 + for (File file : files) { + if (file.isDirectory()) { + printFileInfo(file); + } + } + + for (File file : files) { + if (file.isFile()) { + printFileInfo(file); + } + } + System.out.println("------------------------------------------------"); + System.out.println("共 " + files.length + " 个项目"); + } + + // 打印文件信息 + private static void printFileInfo(File file) { + String type = file.isDirectory() ? "目录" : "文件"; + String name = file.getName(); + String size = file.isDirectory() ? "-" : (file.length() + " bytes"); + String modifyTime = dateFormat.format(new Date(file.lastModified())); + + System.out.printf("%-4s %-40s %-12s %-20s%n", type, name, size, modifyTime); + } + + // 切换目录 + private static void changeDirectory() { + System.out.println("\n===== 切换目录 ====="); + System.out.print("请输入目标目录路径(输入..返回上一级): "); + String targetPath = scanner.nextLine().trim(); + + File newDir; + if (targetPath.equals("..")) { + // 返回上一级目录 + newDir = new File(currentPath).getParentFile(); + } else { + // 处理绝对路径和相对路径 + if (new File(targetPath).isAbsolute()) { + newDir = new File(targetPath); + } else { + newDir = new File(currentPath + File.separator + targetPath); + } + } + + if (newDir != null && newDir.exists() && newDir.isDirectory()) { + currentPath = newDir.getAbsolutePath(); + System.out.println("已切换到目录: " + currentPath); + } else { + System.out.println("目录不存在或不是一个有效的目录!"); + } + } + + // 创建新文件 + private static void createNewFile() { + System.out.println("\n===== 创建新文件 ====="); + System.out.print("请输入新文件名称: "); + String fileName = scanner.nextLine().trim(); + + if (fileName.isEmpty()) { + System.out.println("文件名不能为空!"); + return; + } + + File newFile = new File(currentPath + File.separator + fileName); + + if (newFile.exists()) { + System.out.println("文件已存在!"); + return; + } + + try { + boolean created = newFile.createNewFile(); + if (created) { + System.out.println("文件创建成功: " + newFile.getAbsolutePath()); + } else { + System.out.println("文件创建失败!"); + } + } catch (Exception e) { + System.out.println("创建文件时发生错误: " + e.getMessage()); + } + } + + // 创建新目录 + private static void createNewDirectory() { + System.out.println("\n===== 创建新目录 ====="); + System.out.print("请输入新目录名称: "); + String dirName = scanner.nextLine().trim(); + + if (dirName.isEmpty()) { + System.out.println("目录名不能为空!"); + return; + } + + File newDir = new File(currentPath + File.separator + dirName); + + if (newDir.exists()) { + System.out.println("目录已存在!"); + return; + } + + boolean created = newDir.mkdirs(); + if (created) { + System.out.println("目录创建成功: " + newDir.getAbsolutePath()); + } else { + System.out.println("目录创建失败!"); + } + } + + // 删除文件或目录 + private static void deleteFileOrDirectory() { + System.out.println("\n===== 删除文件/目录 ====="); + System.out.print("请输入要删除的文件/目录名称: "); + String name = scanner.nextLine().trim(); + + if (name.isEmpty()) { + System.out.println("名称不能为空!"); + return; + } + + File target = new File(currentPath + File.separator + name); + + if (!target.exists()) { + System.out.println("文件/目录不存在!"); + return; + } + + System.out.print("确定要删除 " + name + " 吗? (y/n): "); + String confirm = scanner.nextLine().trim().toLowerCase(); + + if (!confirm.equals("y")) { + System.out.println("已取消删除操作"); + return; + } + + boolean deleted = deleteRecursively(target); + if (deleted) { + System.out.println("删除成功!"); + } else { + System.out.println("删除失败!"); + } + } + + // 递归删除目录 + private static boolean deleteRecursively(File file) { + if (file.isDirectory()) { + File[] children = file.listFiles(); + if (children != null) { + for (File child : children) { + boolean success = deleteRecursively(child); + if (!success) { + return false; + } + } + } + } + return file.delete(); + } + + // 搜索文件 + private static void searchFiles() { + System.out.println("\n===== 搜索文件 ====="); + System.out.print("请输入搜索关键词: "); + String keyword = scanner.nextLine().trim().toLowerCase(); + + System.out.println("1. 仅搜索当前目录"); + System.out.println("2. 搜索当前目录及子目录"); + System.out.print("请选择搜索范围: "); + + int scope; + try { + scope = Integer.parseInt(scanner.nextLine()); + if (scope < 1 || scope > 2) { + System.out.println("请输入1或2!"); + return; + } + } catch (NumberFormatException e) { + System.out.println("请输入有效的数字!"); + return; + } + + System.out.println("搜索结果:"); + List results = new ArrayList<>(); + + if (scope == 1) { + // 仅搜索当前目录 + File currentDir = new File(currentPath); + File[] files = currentDir.listFiles(); + if (files != null) { + for (File file : files) { + if (file.getName().toLowerCase().contains(keyword)) { + results.add(file); + } + } + } + } else { + // 搜索当前目录及子目录(递归) + searchRecursively(new File(currentPath), keyword, results); + } + + if (results.isEmpty()) { + System.out.println("未找到匹配的文件/目录"); + } else { + System.out.println("找到 " + results.size() + " 个匹配项:"); + results.forEach(file -> { + String type = file.isDirectory() ? "[目录]" : "[文件]"; + System.out.println(type + " " + file.getAbsolutePath()); + }); + } + } + + // 递归搜索文件 + private static void searchRecursively(File dir, String keyword, List results) { + if (!dir.isDirectory()) { + return; + } + + File[] files = dir.listFiles(); + if (files == null) { + return; + } + + for (File file : files) { + if (file.getName().toLowerCase().contains(keyword)) { + results.add(file); + } + if (file.isDirectory()) { + searchRecursively(file, keyword, results); + } + } + } + + // 显示文件统计信息 + private static void showFileStatistics() { + System.out.println("\n===== 文件统计信息 ====="); + System.out.println("1. 按文件类型统计"); + System.out.println("2. 按文件大小统计"); + System.out.print("请选择统计方式: "); + + int choice; + try { + choice = Integer.parseInt(scanner.nextLine()); + if (choice < 1 || choice > 2) { + System.out.println("请输入1或2!"); + return; + } + } catch (NumberFormatException e) { + System.out.println("请输入有效的数字!"); + return; + } + + // 收集当前目录及子目录的所有文件 + List allFiles = new ArrayList<>(); + collectAllFiles(new File(currentPath), allFiles); + + if (allFiles.isEmpty()) { + System.out.println("没有找到任何文件"); + return; + } + + if (choice == 1) { + // 按文件类型统计 + System.out.println("\n按文件类型统计:"); + allFiles.stream() + .filter(file -> file.isFile()) // 只统计文件 + .map(file -> { + String name = file.getName(); + int dotIndex = name.lastIndexOf('.'); + return dotIndex > 0 ? name.substring(dotIndex) : "无扩展名"; + }) + .collect(Collectors.groupingBy(ext -> ext, Collectors.counting())) + .entrySet().stream() + .sorted((e1, e2) -> Long.compare(e2.getValue(), e1.getValue())) // 按数量降序 + .forEach(entry -> System.out.println(" " + entry.getKey() + ": " + entry.getValue() + "个文件")); + } else { + // 按文件大小统计 + System.out.println("\n按文件大小统计:"); + long totalSize = allFiles.stream() + .filter(file -> file.isFile()) + .mapToLong(File::length) + .sum(); + + System.out.println(" 总文件数量: " + allFiles.size() + "个"); + System.out.println(" 总文件大小: " + totalSize + " bytes"); + + // 大文件筛选(大于1MB) + long largeFileCount = allFiles.stream() + .filter(file -> file.isFile() && file.length() > 1024 * 1024) + .count(); + + System.out.println(" 大文件(>1MB)数量: " + largeFileCount + "个"); + } + } + + // 收集所有文件(递归) + private static void collectAllFiles(File dir, List files) { + if (!dir.isDirectory()) { + return; + } + + File[] dirFiles = dir.listFiles(); + if (dirFiles == null) { + return; + } + + for (File file : dirFiles) { + if (file.isFile()) { + files.add(file); + } else if (file.isDirectory()) { + collectAllFiles(file, files); + } + } + } + + // 批量操作 + private static void batchOperations() { + System.out.println("\n===== 批量操作 ====="); + System.out.println("1. 批量列出特定类型文件"); + System.out.println("2. 批量删除特定类型文件"); + System.out.print("请选择操作类型: "); + + int choice; + try { + choice = Integer.parseInt(scanner.nextLine()); + if (choice < 1 || choice > 2) { + System.out.println("请输入1或2!"); + return; + } + } catch (NumberFormatException e) { + System.out.println("请输入有效的数字!"); + return; + } + + System.out.print("请输入文件扩展名(如txt, java,无需输入.): "); + String ext = scanner.nextLine().trim().toLowerCase(); + if (ext.isEmpty()) { + System.out.println("扩展名不能为空!"); + return; + } + final String extension = ext; + + // 使用文件过滤器筛选特定类型文件 + File currentDir = new File(currentPath); + File[] targetFiles = currentDir.listFiles(new FilenameFilter() { + @Override + public boolean accept(File dir, String name) { + File file = new File(dir, name); + return file.isFile() && name.toLowerCase().endsWith("." + extension); + } + }); + + if (targetFiles == null || targetFiles.length == 0) { + System.out.println("未找到." + extension + "类型的文件"); + return; + } + + System.out.println("找到 " + targetFiles.length + " 个." + extension + "类型的文件:"); + for (File file : targetFiles) { + System.out.println(" " + file.getName() + " (" + file.length() + " bytes)"); + } + + if (choice == 2) { + System.out.print("确定要删除这些文件吗? (y/n): "); + String confirm = scanner.nextLine().trim().toLowerCase(); + + if (confirm.equals("y")) { + int deletedCount = 0; + for (File file : targetFiles) { + if (file.delete()) { + deletedCount++; + } + } + System.out.println("已删除 " + deletedCount + " 个文件"); + } else { + System.out.println("已取消删除操作"); + } + } + } +} diff --git a/day01/src/com/inmind/s_test08/ForeachFileDemo01.java b/day01/src/com/inmind/s_test08/ForeachFileDemo01.java new file mode 100644 index 0000000..2c5f056 --- /dev/null +++ b/day01/src/com/inmind/s_test08/ForeachFileDemo01.java @@ -0,0 +1,62 @@ +package com.inmind.s_test08; + + +import java.io.File; + +/* +13.递归遍历文件夹的练习(重点) +需求:将D:\io_test里面的所有的子内容的名称都打印出来. + +在遍历文件夹操作中,文件中不断地创建文件夹所以普通的循环遍历得子内容的代码实现不了 +所以只能使用递归代码 + +遍历文件夹的递归代码: + 1.结束条件:如果是文件就打印结束 + 2.如果是文件夹就继续遍历,如果是文件就打印结束 + */ +public class ForeachFileDemo01 { + public static void main(String[] args) { + File file = new File("d:/io_test"); + //定义出一个方法能够将指定的文件夹的内容都遍历出来 + getFiles(file); + } + + private static void getFiles(File file) { + //先把非法的情况都拦住 + if (file == null||!file.exists()||file.isFile()){ + return; + } + + //io_test的所有的一级子内容对象 + File[] files = file.listFiles(); + if (files!=null||files.length > 0){ + //遍历数组 + for (File f : files) { + if (f.isDirectory()) { + System.out.println(f.getName()); + //继续遍历明星 + getFiles(f); + } else { + System.out.println(f.getName()); + } + } + } + } + + + + + //继续遍历明星 + private static void getMingXingFiles(File file) { + File[] files = file.listFiles(); + for (File f : files) { + if (f.isDirectory()) { + System.out.println(f.getName()); + //继续遍历女明星文件夹 + //getNvMingxingFiles(); + } else { + System.out.println(f.getName()); + } + } + } +} diff --git a/day01/src/com/inmind/s_test12/A.java b/day01/src/com/inmind/s_test12/A.java new file mode 100644 index 0000000..aef94b1 --- /dev/null +++ b/day01/src/com/inmind/s_test12/A.java @@ -0,0 +1,29 @@ +package com.inmind.s_test12; +/* +enum是一种特殊的类 +1.枚举类的第一行只能罗列一些名称,这些名称都是常量,并且每个常量都是枚举类的一个对象 +2.枚举类的构造器都是私有的,因此枚举类对外不能创建对象 +3.枚举是最终类,不能被继承 +4.枚举类中,第二行开始,可以定义类的各种成员 +5.编译器为枚举类新增了几个方法,并且枚举类都是继承java.lang.Enum类的,从enum类会继承一些方法 + */ +public enum A { + X,Y("YYYY"),Z; + private String name; + + A(){ + this(null); + } + + A(String name){ + this.name = name; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } +} diff --git a/day01/src/com/inmind/s_test12/Demo01.java b/day01/src/com/inmind/s_test12/Demo01.java new file mode 100644 index 0000000..ce016e5 --- /dev/null +++ b/day01/src/com/inmind/s_test12/Demo01.java @@ -0,0 +1,26 @@ +package com.inmind.s_test12; + +import java.util.Arrays; + +public class Demo01 { + public static void main(String[] args) { +// A.Z = null; + A a1 = A.X; + A a2 = A.Y; + A a3 = A.Z; + + System.out.println(a2.ordinal()); + System.out.println(a1.ordinal()); + System.out.println(a2.getName()); + System.out.println(Arrays.toString(A.values())); + A a4 = A.valueOf("Y"); + System.out.println(a4.getName()); + + method(A.Y); + } + + + public static void method(A a) { + System.out.println(a.getName()); + } +} diff --git a/day01/src/com/inmind/s_test_02/InventorySystem.java b/day01/src/com/inmind/s_test_02/InventorySystem.java new file mode 100644 index 0000000..0446425 --- /dev/null +++ b/day01/src/com/inmind/s_test_02/InventorySystem.java @@ -0,0 +1,231 @@ +package com.inmind.s_test_02; + +import java.util.ArrayList; +import java.util.List; +import java.util.Optional; + +// 商品接口:定义所有商品的共同属性和行为,作为泛型的边界 +interface Product { + String getId(); // 获取商品ID + String getName(); // 获取商品名称 + double getPrice(); // 获取商品价格 +} + +// 具体商品类:电子设备 +class ElectronicProduct implements Product { + private String id; // 商品ID + private String name; // 商品名称 + private double price; // 商品价格 + private String brand; // 电子设备特有属性:品牌 + + // 构造方法:初始化电子设备信息 + public ElectronicProduct(String id, String name, double price, String brand) { + this.id = id; + this.name = name; + this.price = price; + this.brand = brand; + } + + // 实现Product接口的方法 + public String getId() { return id; } + public String getName() { return name; } + public double getPrice() { return price; } + + // 特有属性的getter方法 + public String getBrand() { return brand; } + + // 重写toString方法,方便打印商品信息 + @Override + public String toString() { + return "电子设备{ID=" + id + ", 名称=" + name + ", 价格=" + price + ", 品牌=" + brand + "}"; + } +} + +// 具体商品类:图书 +class Book implements Product { + private String id; // 商品ID + private String name; // 商品名称 + private double price; // 商品价格 + private String author; // 图书特有属性:作者 + + // 构造方法:初始化图书信息 + public Book(String id, String name, double price, String author) { + this.id = id; + this.name = name; + this.price = price; + this.author = author; + } + + // 实现Product接口的方法 + public String getId() { return id; } + public String getName() { return name; } + public double getPrice() { return price; } + + // 特有属性的getter方法 + public String getAuthor() { return author; } + + // 重写toString方法,方便打印商品信息 + @Override + public String toString() { + return "图书{ID=" + id + ", 名称=" + name + ", 价格=" + price + ", 作者=" + author + "}"; + } +} + +// 库存记录类:关联商品和库存信息,使用泛型限定只能存储Product类型 +class InventoryRecord { + private T product; // 商品对象(泛型类型) + private int quantity; // 库存数量 + private String warehouseLocation; // 仓库位置 + + // 构造方法:初始化库存记录 + public InventoryRecord(T product, int quantity, String warehouseLocation) { + this.product = product; + this.quantity = quantity; + this.warehouseLocation = warehouseLocation; + } + + // getter和setter方法 + public T getProduct() { return product; } + public int getQuantity() { return quantity; } + public void setQuantity(int quantity) { this.quantity = quantity; } + public String getWarehouseLocation() { return warehouseLocation; } +} + +// 泛型库存管理器:核心业务类,T限定为Product的子类 +class InventoryManager { + // 泛型集合:存储特定类型的库存记录,保证类型安全 + private List> inventoryList = new ArrayList<>(); + + /** + * 添加商品到库存 + * 泛型特性确保只能添加指定类型的商品 + */ + public void addProduct(T product, int quantity, String location) { + // 查找是否已存在该商品的库存记录 + Optional> existingRecord = findRecordById(product.getId()); + + if (existingRecord.isPresent()) { + // 已存在则更新库存数量 + existingRecord.get().setQuantity(existingRecord.get().getQuantity() + quantity); + } else { + // 不存在则创建新的库存记录并添加到列表 + inventoryList.add(new InventoryRecord<>(product, quantity, location)); + } + } + + /** + * 从库存中移除商品 + * @param productId 商品ID + * @param quantity 要移除的数量 + * @return 是否移除成功 + */ + public boolean removeProduct(String productId, int quantity) { + // 查找商品库存记录 + Optional> record = findRecordById(productId); + + if (record.isPresent()) { + InventoryRecord inventoryRecord = record.get(); + // 检查库存是否充足 + if (inventoryRecord.getQuantity() >= quantity) { + // 更新库存数量 + inventoryRecord.setQuantity(inventoryRecord.getQuantity() - quantity); + // 如果库存为0,从列表中移除该记录 + if (inventoryRecord.getQuantity() == 0) { + inventoryList.remove(inventoryRecord); + } + return true; + } + } + // 商品不存在或库存不足,返回false + return false; + } + + /** + * 根据商品ID查找库存记录 + * @param productId 商品ID + * @return 包含库存记录的Optional对象 + */ + public Optional> findRecordById(String productId) { + // 遍历库存列表查找匹配的商品 + for (InventoryRecord record : inventoryList) { + if (record.getProduct().getId().equals(productId)) { + return Optional.of(record); // 找到则返回包含该记录的Optional + } + } + return Optional.empty(); // 未找到则返回空Optional + } + + /** + * 计算库存总量 + * @return 所有商品的库存总和 + */ + public int getTotalQuantity() { + int total = 0; + // 遍历库存列表累加数量 + for (InventoryRecord record : inventoryList) { + total += record.getQuantity(); + } + return total; + } + + /** + * 显示所有库存记录 + */ + public void displayAllInventory() { + System.out.println("=== 库存记录 ==="); + // 遍历并打印所有库存信息 + for (InventoryRecord record : inventoryList) { + System.out.println(record.getProduct() + + ", 库存数量: " + record.getQuantity() + + ", 存放位置: " + record.getWarehouseLocation()); + } + } +} + +// 测试类:演示库存管理系统的使用 +public class InventorySystem { + public static void main(String[] args) { + // 1. 创建电子设备库存管理器(泛型类型指定为ElectronicProduct) + InventoryManager electronicManager = new InventoryManager<>(); + + // 向电子设备库存添加商品 + electronicManager.addProduct( + new ElectronicProduct("E001", "智能手机", 5999.99, "华为"), + 50, "A区-101" // 数量50,存放位置A区-101 + ); + electronicManager.addProduct( + new ElectronicProduct("E002", "笔记本电脑", 7999.99, "苹果"), + 30, "A区-102" // 数量30,存放位置A区-102 + ); + + // 显示电子设备库存总量和详细记录 + System.out.println("电子设备库存总量: " + electronicManager.getTotalQuantity()); + electronicManager.displayAllInventory(); + + // 从电子设备库存中移除部分商品 + electronicManager.removeProduct("E001", 10); // 移除10台智能手机 + System.out.println("\n移除10台智能手机后:"); + electronicManager.displayAllInventory(); + + // 2. 创建图书库存管理器(泛型类型指定为Book) + InventoryManager bookManager = new InventoryManager<>(); + + // 向图书库存添加商品 + bookManager.addProduct( + new Book("B001", "Java编程思想", 108.0, "Bruce Eckel"), + 100, "B区-201" // 数量100,存放位置B区-201 + ); + bookManager.addProduct( + new Book("B002", "设计模式", 89.0, "Erich Gamma"), + 80, "B区-202" // 数量80,存放位置B区-202 + ); + + // 显示图书库存总量和详细记录 + System.out.println("\n图书库存总量: " + bookManager.getTotalQuantity()); + bookManager.displayAllInventory(); + + // 演示泛型的类型安全:以下代码会编译错误 + // 因为electronicManager只能处理ElectronicProduct类型,不能添加Book类型 + // electronicManager.addProduct(new Book("B001", "错误的类型", 0, ""), 1, ""); + } +} diff --git a/day01/src/com/inmind/s_test_0202/InventorySystem1.java b/day01/src/com/inmind/s_test_0202/InventorySystem1.java new file mode 100644 index 0000000..803999b --- /dev/null +++ b/day01/src/com/inmind/s_test_0202/InventorySystem1.java @@ -0,0 +1,239 @@ +package com.inmind.s_test_0202; + + +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; +import java.util.Map; + +// 商品接口:定义所有商品的共同属性和行为,作为泛型的边界 +interface Product { + String getId(); // 获取商品ID + String getName(); // 获取商品名称 + double getPrice(); // 获取商品价格 +} + +// 具体商品类:电子设备 +class ElectronicProduct implements Product { + private String id; // 商品ID + private String name; // 商品名称 + private double price; // 商品价格 + private String brand; // 电子设备特有属性:品牌 + + // 构造方法:初始化电子设备信息 + public ElectronicProduct(String id, String name, double price, String brand) { + this.id = id; + this.name = name; + this.price = price; + this.brand = brand; + } + + // 实现Product接口的方法 + public String getId() { return id; } + public String getName() { return name; } + public double getPrice() { return price; } + + // 特有属性的getter方法 + public String getBrand() { return brand; } + + // 重写toString方法,方便打印商品信息 + @Override + public String toString() { + return "电子设备{ID=" + id + ", 名称=" + name + ", 价格=" + price + ", 品牌=" + brand + "}"; + } +} + +// 具体商品类:图书 +class Book implements Product { + private String id; // 商品ID + private String name; // 商品名称 + private double price; // 商品价格 + private String author; // 图书特有属性:作者 + + // 构造方法:初始化图书信息 + public Book(String id, String name, double price, String author) { + this.id = id; + this.name = name; + this.price = price; + this.author = author; + } + + // 实现Product接口的方法 + public String getId() { return id; } + public String getName() { return name; } + public double getPrice() { return price; } + + // 特有属性的getter方法 + public String getAuthor() { return author; } + + // 重写toString方法,方便打印商品信息 + @Override + public String toString() { + return "图书{ID=" + id + ", 名称=" + name + ", 价格=" + price + ", 作者=" + author + "}"; + } +} + +// 库存记录类:关联商品和库存信息,使用泛型限定只能存储Product类型 +class InventoryRecord { + private T product; // 商品对象(泛型类型) + private int quantity; // 库存数量 + private String warehouseLocation; // 仓库位置 + + // 构造方法:初始化库存记录 + public InventoryRecord(T product, int quantity, String warehouseLocation) { + this.product = product; + this.quantity = quantity; + this.warehouseLocation = warehouseLocation; + } + + // getter和setter方法 + public T getProduct() { return product; } + public int getQuantity() { return quantity; } + public void setQuantity(int quantity) { this.quantity = quantity; } + public String getWarehouseLocation() { return warehouseLocation; } +} + +// 泛型库存管理器:核心业务类,T限定为Product的子类 +class InventoryManager { + // 泛型集合:存储特定类型的库存记录,保证类型安全 + private List> inventoryList = new ArrayList<>(); + + + + /** + * 根据商品ID查找库存记录 + * @param productId 商品ID + * @return 找到的库存记录,未找到则返回null + */ + public InventoryRecord findRecordById(String productId) { + // 遍历库存列表查找匹配的商品 + for (InventoryRecord record : inventoryList) { + if (record.getProduct().getId().equals(productId)) { + return record; // 找到则返回该记录 + } + } + return null; // 未找到则返回null + } + + + + /** + * 添加商品到库存 + * 泛型特性确保只能添加指定类型的商品 + */ + public void addProduct(T product, int quantity, String location) { + // 查找是否已存在该商品的库存记录(不使用Optional,直接返回对象或null) + InventoryRecord existingRecord = findRecordById(product.getId()); + + if (existingRecord != null) { + // 已存在则更新库存数量 + existingRecord.setQuantity(existingRecord.getQuantity() + quantity); + } else { + // 不存在则创建新的库存记录并添加到列表 + inventoryList.add(new InventoryRecord<>(product, quantity, location)); + } + } + + /** + * 从库存中移除商品 + * @param productId 商品ID + * @param quantity 要移除的数量 + * @return 是否移除成功 + */ + public boolean removeProduct(String productId, int quantity) { + // 查找商品库存记录(不使用Optional) + InventoryRecord record = findRecordById(productId); + + if (record != null) { + // 检查库存是否充足 + if (record.getQuantity() >= quantity) { + // 更新库存数量 + record.setQuantity(record.getQuantity() - quantity); + // 如果库存为0,从列表中移除该记录 + if (record.getQuantity() == 0) { + inventoryList.remove(record); + } + return true; + } + } + // 商品不存在或库存不足,返回false + return false; + } + + + + /** + * 计算库存总量 + * @return 所有商品的库存总和 + */ + public int getTotalQuantity() { + int total = 0; + // 遍历库存列表累加数量 + for (InventoryRecord record : inventoryList) { + total += record.getQuantity(); + } + return total; + } + + /** + * 显示所有库存记录 + */ + public void displayAllInventory() { + System.out.println("=== 库存记录 ==="); + // 遍历并打印所有库存信息 + for (InventoryRecord record : inventoryList) { + System.out.println(record.getProduct() + + ", 库存数量: " + record.getQuantity() + + ", 存放位置: " + record.getWarehouseLocation()); + } + } +} + +// 测试类:演示库存管理系统的使用 +public class InventorySystem1 { + public static void main(String[] args) { + // 1. 创建电子设备库存管理器(泛型类型指定为ElectronicProduct) + InventoryManager electronicManager = new InventoryManager<>(); + + // 向电子设备库存添加商品 + electronicManager.addProduct( + new ElectronicProduct("E001", "智能手机", 5999.99, "华为"), + 50, "A区-101" // 数量50,存放位置A区-101 + ); + electronicManager.addProduct( + new ElectronicProduct("E002", "笔记本电脑", 7999.99, "苹果"), + 30, "A区-102" // 数量30,存放位置A区-102 + ); + + // 显示电子设备库存总量和详细记录 + System.out.println("电子设备库存总量: " + electronicManager.getTotalQuantity()); + electronicManager.displayAllInventory(); + + // 从电子设备库存中移除部分商品 + electronicManager.removeProduct("E001", 10); // 移除10台智能手机 + System.out.println("\n移除10台智能手机后:"); + electronicManager.displayAllInventory(); + + // 2. 创建图书库存管理器(泛型类型指定为Book) + InventoryManager bookManager = new InventoryManager<>(); + + // 向图书库存添加商品 + bookManager.addProduct( + new Book("B001", "Java编程思想", 108.0, "Bruce Eckel"), + 100, "B区-201" // 数量100,存放位置B区-201 + ); + bookManager.addProduct( + new Book("B002", "设计模式", 89.0, "Erich Gamma"), + 80, "B区-202" // 数量80,存放位置B区-202 + ); + + // 显示图书库存总量和详细记录 + System.out.println("\n图书库存总量: " + bookManager.getTotalQuantity()); + bookManager.displayAllInventory(); + + // 演示泛型的类型安全:以下代码会编译错误 + // 因为electronicManager只能处理ElectronicProduct类型,不能添加Book类型 + // electronicManager.addProduct(new Book("B001", "错误的类型", 0, ""), 1, ""); + } +} + diff --git a/day01/src/com/inmind/s_test_03/Student.java b/day01/src/com/inmind/s_test_03/Student.java new file mode 100644 index 0000000..430f7ee --- /dev/null +++ b/day01/src/com/inmind/s_test_03/Student.java @@ -0,0 +1,131 @@ +package com.inmind.s_test_03; + +import java.util.HashSet; +import java.util.Set; + +/** + * 学生实体类 + * 存储学生基本信息及所选课程 + */ +public class Student { + // 学号 + private String id; + // 姓名 + private String name; + // 年龄 + private int age; + // 成绩 + private double score; + // 所选课程(使用Set确保课程不重复) + private Set courses; + + /** + * 构造方法 + * @param id 学号 + * @param name 姓名 + * @param age 年龄 + */ + public Student(String id, String name, int age) { + this.id = id; + this.name = name; + this.age = age; + this.courses = new HashSet(); // 初始化课程集合 + this.score = 0.0; // 初始成绩为0 + } + + /** + * 添加课程 + * @param course 课程名称 + */ + public void addCourse(String course) { + courses.add(course); // 利用Set特性自动去重 + } + + // getter和setter方法 + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public int getAge() { + return age; + } + + public void setAge(int age) { + this.age = age; + } + + public double getScore() { + return score; + } + + public void setScore(double score) { + this.score = score; + } + + public Set getCourses() { + // 返回一个新的HashSet,避免外部直接修改内部集合 + return new HashSet(courses); + } + + /** + * 重写equals方法,根据学号判断对象是否相等 + * @param obj 比较的对象 + * @return 是否相等 + */ + @Override + public boolean equals(Object obj) { + if (this == obj) { // 引用相同对象 + return true; + } + if (obj == null) { // 比较对象为null + return false; + } + if (getClass() != obj.getClass()) { // 类型不同 + return false; + } + Student other = (Student) obj; // 类型转换 + if (id == null) { // 当前对象学号为null + if (other.id != null) { // 比较对象学号不为null + return false; + } + } else if (!id.equals(other.id)) { // 学号不相等 + return false; + } + return true; + } + + /** + * 重写hashCode方法,与equals保持一致 + * @return 哈希值 + */ + @Override + public int hashCode() { + final int prime = 31; // 质数,用于计算哈希值 + int result = 1; + result = prime * result + ((id == null) ? 0 : id.hashCode()); // 基于学号计算哈希值 + return result; + } + + /** + * 重写toString方法,方便打印学生信息 + * @return 学生信息字符串 + */ + @Override + public String toString() { + return "学号:" + id + ", 姓名:" + name + ", 年龄:" + age + + ", 成绩:" + score + ", 所选课程:" + courses; + } +} + \ No newline at end of file diff --git a/day01/src/com/inmind/s_test_03/StudentComparator.java b/day01/src/com/inmind/s_test_03/StudentComparator.java new file mode 100644 index 0000000..127277f --- /dev/null +++ b/day01/src/com/inmind/s_test_03/StudentComparator.java @@ -0,0 +1,87 @@ +package com.inmind.s_test_03; + +import java.util.Comparator; + +/** + * 学生比较器类 + * 实现不同的比较策略 + */ +public class StudentComparator { + + /** + * 按学号升序排序 + * @return 比较器实例 + */ + public static Comparator byIdAsc() { + // 返回匿名内部类实现的Comparator + return new Comparator() { + @Override + public int compare(Student s1, Student s2) { + // 比较两个学生的学号 + return s1.getId().compareTo(s2.getId()); + } + }; + } + + /** + * 按姓名升序排序 + * @return 比较器实例 + */ + public static Comparator byNameAsc() { + return new Comparator() { + @Override + public int compare(Student s1, Student s2) { + // 比较两个学生的姓名 + return s1.getName().compareTo(s2.getName()); + } + }; + } + + /** + * 按成绩降序排序 + * @return 比较器实例 + */ + public static Comparator byScoreDesc() { + return new Comparator() { + @Override + public int compare(Student s1, Student s2) { + // 成绩高的排在前面(降序) + return Double.compare(s2.getScore(), s1.getScore()); + } + }; + } + + /** + * 先按成绩降序,成绩相同则按姓名升序 + * @return 比较器实例 + */ + public static Comparator byScoreDescAndNameAsc() { + return new Comparator() { + @Override + public int compare(Student s1, Student s2) { + // 先比较成绩 + int scoreCompare = Double.compare(s2.getScore(), s1.getScore()); + if (scoreCompare != 0) { // 成绩不同 + return scoreCompare; + } else { // 成绩相同则比较姓名 + return s1.getName().compareTo(s2.getName()); + } + } + }; + } + + /** + * 按年龄升序排序 + * @return 比较器实例 + */ + public static Comparator byAgeAsc() { + return new Comparator() { + @Override + public int compare(Student s1, Student s2) { + // 比较两个学生的年龄 + return Integer.compare(s1.getAge(), s2.getAge()); + } + }; + } +} + \ No newline at end of file diff --git a/day01/src/com/inmind/s_test_03/StudentManager.java b/day01/src/com/inmind/s_test_03/StudentManager.java new file mode 100644 index 0000000..bcd9d18 --- /dev/null +++ b/day01/src/com/inmind/s_test_03/StudentManager.java @@ -0,0 +1,211 @@ +package com.inmind.s_test_03; + +import java.util.*; + +/** + * 学生管理系统 + * 演示List、Set集合的使用,以及Comparator和Collections工具类的应用 + */ +public class StudentManager { + public static final String COURSE_JAVA = "Java编程"; + // 存储学生列表(使用List允许重复添加检测和有序访问) + private List students; + // 存储所有可选课程(使用Set确保课程不重复) + private Set allCourses; + + /** + * 构造方法,初始化集合 + */ + public StudentManager() { + students = new ArrayList(); // 初始化学生列表 + allCourses = new HashSet(); // 初始化课程集合 + initData(); // 初始化测试数据 + } + + /** + * 初始化测试数据 + */ + private void initData() { + // 添加课程 + allCourses.add(COURSE_JAVA); + allCourses.add("数据结构"); + allCourses.add("计算机网络"); + allCourses.add("数据库原理"); + allCourses.add("操作系统"); + + // 添加学生1 + Student s1 = new Student("2023001", "张三", 20); + s1.addCourse("Java编程"); + s1.addCourse("数据结构"); + s1.setScore(85.5); + students.add(s1); + + // 添加学生2 + Student s2 = new Student("2023002", "李四", 21); + s2.addCourse("Java编程"); + s2.addCourse("数据库原理"); + s2.setScore(92.0); + students.add(s2); + + // 添加学生3 + Student s3 = new Student("2023003", "王五", 19); + s3.addCourse("计算机网络"); + s3.addCourse("操作系统"); + s3.setScore(78.5); + students.add(s3); + + // 添加学生4 + Student s4 = new Student("2023004", "赵六", 20); + s4.addCourse("数据结构"); + s4.addCourse("数据库原理"); + s4.setScore(88.0); + students.add(s4); + } + + /** + * 添加学生 + * @param student 要添加的学生对象 + * @return 添加成功返回true,已存在返回false + */ + public boolean addStudent(Student student) { + // 检查学生是否已存在(依赖Student类重写的equals方法) + if (!students.contains(student)) { + students.add(student); + return true; + } + return false; + } + + /** + * 显示所有学生信息 + */ + public void showAllStudents() { + System.out.println("\n===== 所有学生信息 ====="); + // 使用增强for循环遍历学生列表 + for (Student student : students) { + System.out.println(student); + } + } + + /** + * 按条件排序并显示学生信息 + * @param comparator 比较器,定义排序规则 + * @param sortType 排序类型描述,用于输出显示 + */ + public void sortAndShowStudents(Comparator comparator, String sortType) { + // 创建列表副本进行排序,避免修改原列表顺序 + List sortedList = new ArrayList(students); + // 使用Collections工具类进行排序 + Collections.sort(sortedList, comparator); + + System.out.println("\n===== 按" + sortType + "排序的学生信息 ====="); + // 遍历排序后的列表 + for (Student student : sortedList) { + System.out.println(student); + } + } + + /** + * 根据学号查找学生 + * @param id 要查找的学号 + * @return 找到的学生对象,未找到返回null + */ + public Student findStudentById(String id) { + // 创建列表副本并按学号排序(二分查找需要有序列表) + List sortedById = new ArrayList(students); + Collections.sort(sortedById, StudentComparator.byIdAsc()); + + // 使用Collections的binarySearch进行二分查找 + int index = Collections.binarySearch(sortedById, + new Student(id, "", 0), // 临时创建用于比较的学生对象 + StudentComparator.byIdAsc()); // 使用学号比较器 + + // 索引>=0表示找到,返回对应学生对象 + return index >= 0 ? sortedById.get(index) : null; + } + + /** + * 获取选修某门课程的所有学生 + * @param course 课程名称 + * @return 选修该课程的学生集合 + */ + public Set getStudentsByCourse(String course) { + Set result = new HashSet(); + // 遍历所有学生 + for (Student student : students) { + // 检查学生是否选修了该课程 + if (student.getCourses().contains(course)) { + result.add(student); + } + } + return result; + } + + /** + * 计算学生平均年龄 + * @return 平均年龄 + */ + public double getAverageAge() { + if (students.isEmpty()) { // 学生列表为空时返回0 + return 0; + } + + int totalAge = 0; + // 遍历所有学生,累加年龄 + for (Student student : students) { + totalAge += student.getAge(); + } + // 计算并返回平均年龄 + return (double) totalAge / students.size(); + } + + /** + * 主方法,演示系统功能 + * @param args 命令行参数 + */ + public static void main(String[] args) { + // 创建学生管理系统实例 + StudentManager manager = new StudentManager(); + + // 显示所有学生 + manager.showAllStudents(); + + // 按不同条件排序并显示 + manager.sortAndShowStudents(StudentComparator.byIdAsc(), "学号升序"); + manager.sortAndShowStudents(StudentComparator.byNameAsc(), "姓名升序"); + manager.sortAndShowStudents(StudentComparator.byScoreDesc(), "成绩降序"); + manager.sortAndShowStudents(StudentComparator.byScoreDescAndNameAsc(), "成绩降序+姓名升序"); + manager.sortAndShowStudents(StudentComparator.byAgeAsc(), "年龄升序"); + + // 查找指定学号的学生 + String searchId = "2023002"; + Student found = manager.findStudentById(searchId); + System.out.println("\n查找学号为" + searchId + "的学生: " + + (found != null ? found.getName() : "未找到")); + + // 查找选修特定课程的学生 + String course = "Java编程"; + Set javaStudents = manager.getStudentsByCourse(course); + System.out.println("\n选修" + course + "的学生有" + javaStudents.size() + "人:"); + // 使用迭代器遍历Set集合 + Iterator iterator = javaStudents.iterator(); + while (iterator.hasNext()) { + Student student = iterator.next(); + System.out.println(student.getName()); + } + + // 统计并显示平均年龄 + System.out.println("\n学生平均年龄: " + String.format("%.1f", manager.getAverageAge())); + + // 添加新学生 + Student newStudent = new Student("2023005", "钱七", 22); + newStudent.addCourse("操作系统"); + newStudent.setScore(90.5); + boolean added = manager.addStudent(newStudent); + System.out.println("\n添加新学生" + newStudent.getName() + ": " + (added ? "成功" : "失败(已存在)")); + + // 再次显示所有学生,验证新学生是否添加成功 + manager.showAllStudents(); + } +} + \ No newline at end of file diff --git a/day01/src/com/inmind/s_test_04/CartSystem.java b/day01/src/com/inmind/s_test_04/CartSystem.java new file mode 100644 index 0000000..f7d7d75 --- /dev/null +++ b/day01/src/com/inmind/s_test_04/CartSystem.java @@ -0,0 +1,202 @@ +package com.inmind.s_test_04; +import java.util.*; + +/** + * 极简版购物系统 + * 功能:浏览商品、搜索商品、管理购物车 + */ +public class CartSystem { + // 商品列表(单列集合) + private static List products = new ArrayList<>(); + // 购物车(双列集合:商品-数量) + private static Map cart = new HashMap<>(); + private static Scanner scanner = new Scanner(System.in); + + public static void main(String[] args) { + // 初始化商品数据 + initProducts(); + + System.out.println("===== 简易购物系统 ====="); + showMainMenu(); + } + + // 初始化商品 + private static void initProducts() { + products.add(new Product("P01", "笔记本电脑", 5999.99, "电子产品", 10)); + products.add(new Product("P02", "机械键盘", 299.99, "电脑配件", 20)); + products.add(new Product("P03", "无线鼠标", 129.99, "电脑配件", 30)); + products.add(new Product("P04", "蓝牙耳机", 799.99, "音频设备", 15)); + products.add(new Product("P05", "智能手机", 3999.99, "电子产品", 25)); + } + + // 显示主菜单 + private static void showMainMenu() { + while (true) { + System.out.println("\n===== 主菜单 ====="); + System.out.println("1. 浏览所有商品"); + System.out.println("2. 搜索商品"); + System.out.println("3. 查看购物车"); + System.out.println("4. 添加商品到购物车"); + System.out.println("5. 修改购物车商品数量"); + System.out.println("6. 清空购物车"); + System.out.println("7. 退出"); + System.out.print("请选择: "); + + int choice = getIntInput(); + if (choice < 1 || choice > 7) { + System.out.println("无效选择,请重试"); + continue; + } + + switch (choice) { + case 1: browseProducts(); break; + case 2: searchProducts(); break; + case 3: viewCart(); break; + case 4: addToCart(); break; + case 5: updateCartQuantity(); break; + case 6: cart.clear(); System.out.println("购物车已清空"); break; + case 7: System.out.println("谢谢使用,再见!"); scanner.close(); return; + } + } + } + + // 浏览所有商品 + private static void browseProducts() { + System.out.println("\n===== 所有商品 ====="); + for (int i = 0; i < products.size(); i++) { + System.out.println(products.get(i)); + } + } + + // 搜索商品 + private static void searchProducts() { + System.out.print("请输入商品名称关键字: "); + String keyword = scanner.nextLine().toLowerCase(); + + List result = new ArrayList<>(); + for (int i = 0; i < products.size(); i++) { + Product p = products.get(i); + if (p.getName().toLowerCase().contains(keyword)) { + result.add(p); + } + } + + System.out.println("\n===== 搜索结果 ====="); + if (result.isEmpty()) { + System.out.println("没有找到匹配的商品"); + } else { + for (int i = 0; i < result.size(); i++) { + System.out.println(result.get(i)); + } + } + } + + // 查看购物车 + private static void viewCart() { + System.out.println("\n===== 购物车 ====="); + if (cart.isEmpty()) { + System.out.println("购物车是空的"); + return; + } + + double total = 0; + // 使用迭代器遍历Map + Iterator> iterator = cart.entrySet().iterator(); + while (iterator.hasNext()) { + Map.Entry entry = iterator.next(); + Product p = entry.getKey(); + int qty = entry.getValue(); + double subtotal = p.getPrice() * qty; + total += subtotal; + System.out.printf("%s, 数量: %d, 小计: ¥%.2f%n", + p.getName(), qty, subtotal); + } + + System.out.printf("购物车总计: ¥%.2f%n", total); + } + + // 添加商品到购物车 + private static void addToCart() { + System.out.print("请输入商品ID: "); + String id = scanner.nextLine(); + + // 查找商品 + Product product = null; + for (int i = 0; i < products.size(); i++) { + if (products.get(i).getId().equals(id)) { + product = products.get(i); + break; + } + } + + if (product == null) { + System.out.println("未找到该商品"); + return; + } + + System.out.print("请输入购买数量: "); + int quantity = getIntInput(); + if (quantity <= 0) { + System.out.println("数量必须大于0"); + return; + } + + // 检查库存 + if (quantity > product.getStock()) { + System.out.println("库存不足,当前库存: " + product.getStock()); + return; + } + + // 添加到购物车 + if (cart.containsKey(product)) { + cart.put(product, cart.get(product) + quantity); + } else { + cart.put(product, quantity); + } + System.out.println("已添加到购物车"); + } + + // 修改购物车商品数量 + private static void updateCartQuantity() { + System.out.print("请输入要修改的商品ID: "); + String id = scanner.nextLine(); + + // 查找购物车中的商品 + Product targetProduct = null; + Iterator> iterator = cart.entrySet().iterator(); + while (iterator.hasNext()) { + Product p = iterator.next().getKey(); + if (p.getId().equals(id)) { + targetProduct = p; + break; + } + } + + if (targetProduct == null) { + System.out.println("购物车中没有该商品"); + return; + } + + System.out.print("请输入新的数量: "); + int newQty = getIntInput(); + + if (newQty <= 0) { + cart.remove(targetProduct); + System.out.println("已从购物车移除该商品"); + } else if (newQty > targetProduct.getStock()) { + System.out.println("库存不足,当前库存: " + targetProduct.getStock()); + } else { + cart.put(targetProduct, newQty); + System.out.println("数量已更新"); + } + } + + // 获取整数输入并处理异常 + private static int getIntInput() { + try { + return Integer.parseInt(scanner.nextLine()); + } catch (NumberFormatException e) { + return -1; + } + } +} diff --git a/day01/src/com/inmind/s_test_04/Product.java b/day01/src/com/inmind/s_test_04/Product.java new file mode 100644 index 0000000..3207686 --- /dev/null +++ b/day01/src/com/inmind/s_test_04/Product.java @@ -0,0 +1,62 @@ +package com.inmind.s_test_04; + +/** + * 商品类,存储商品基本信息 + */ +public class Product { + private String id; // 商品ID + private String name; // 商品名称 + private double price; // 商品价格 + private String category; // 商品分类 + private int stock; // 库存数量 + + public Product(String id, String name, double price, String category, int stock) { + this.id = id; + this.name = name; + this.price = price; + this.category = category; + this.stock = stock; + } + + // getter方法 + public String getId() { + return id; + } + + public String getName() { + return name; + } + + public double getPrice() { + return price; + } + + public String getCategory() { + return category; + } + + public int getStock() { + return stock; + } + + @Override + public String toString() { + return "ID: "+this.id+", 名称: "+this.name+", 价格: ¥"+this.price+", 分类: "+this.category+", 库存: "+this.stock; + } + + + + // 重写equals和hashCode,确保在集合中正确比较商品对象 + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + Product product = (Product) o; + return id.equals(product.id); + } + + @Override + public int hashCode() { + return id.hashCode(); + } +} diff --git a/day01/src/com/inmind/s_test_04/ShoppingSystem.java b/day01/src/com/inmind/s_test_04/ShoppingSystem.java new file mode 100644 index 0000000..94ef5b3 --- /dev/null +++ b/day01/src/com/inmind/s_test_04/ShoppingSystem.java @@ -0,0 +1,344 @@ +package com.inmind.s_test_04; + +import java.util.*; + +/** + * 购物系统主类,不使用lambda表达式 + */ +public class ShoppingSystem { + // 使用List存储所有商品,单列集合应用 + private static List products = new ArrayList<>(); + // 使用Map实现购物车,双列集合应用(商品-数量) + private static Map shoppingCart = new HashMap<>(); + private static Scanner scanner = new Scanner(System.in); + + public static void main(String[] args) { + // 初始化商品数据 + initProducts(); + + System.out.println("===== 欢迎使用简易购物车系统 ====="); + + // 显示主菜单 + showMainMenu(); + } + + // 初始化商品数据 + private static void initProducts() { + products.add(new Product("P001", "笔记本电脑", 5999.99, "电子产品", 10)); + products.add(new Product("P002", "机械键盘", 299.99, "电脑配件", 20)); + products.add(new Product("P003", "无线鼠标", 129.99, "电脑配件", 30)); + products.add(new Product("P004", "蓝牙耳机", 799.99, "音频设备", 15)); + products.add(new Product("P005", "智能手机", 3999.99, "电子产品", 25)); + products.add(new Product("P006", "游戏手柄", 349.99, "游戏设备", 18)); + products.add(new Product("P007", "移动硬盘", 499.99, "存储设备", 12)); + } + + // 显示主菜单 + private static void showMainMenu() { + while (true) { + System.out.println("\n===== 主菜单 ====="); + System.out.println("1. 浏览所有商品"); + System.out.println("2. 按分类浏览商品"); + System.out.println("3. 搜索商品"); + System.out.println("4. 查看购物车"); + System.out.println("5. 添加商品到购物车"); + System.out.println("6. 修改购物车商品数量"); + System.out.println("7. 从购物车删除商品"); + System.out.println("8. 清空购物车"); + System.out.println("9. 退出系统"); + System.out.print("请选择操作(1-9): "); + + int choice; + try { + choice = Integer.parseInt(scanner.nextLine()); + } catch (NumberFormatException e) { + System.out.println("输入错误,请输入数字1-9"); + continue; + } + + switch (choice) { + case 1: + browseAllProducts(); + break; + case 2: + browseProductsByCategory(); + break; + case 3: + searchProducts(); + break; + case 4: + viewShoppingCart(); + break; + case 5: + addToCart(); + break; + case 6: + updateCartItemQuantity(); + break; + case 7: + removeFromCart(); + break; + case 8: + clearCart(); + break; + case 9: + System.out.println("感谢使用,再见!"); + scanner.close(); + return; + default: + System.out.println("无效选择,请输入1-9之间的数字"); + } + } + } + + // 浏览所有商品 + private static void browseAllProducts() { + System.out.println("\n===== 所有商品 ====="); + for (Product product : products) { + System.out.println(product); + } + } + + // 按分类浏览商品 + private static void browseProductsByCategory() { + // 使用Map对商品进行分类,键为分类名称,值为该分类下的商品列表 + Map> productsByCategory = new HashMap<>(); + + // 遍历商品列表,将商品按分类分组 + for (Product product : products) { + String category = product.getCategory(); + // 检查该分类是否已在Map中 + if (!productsByCategory.containsKey(category)) { + // 如果不在,则创建新的列表并放入Map + productsByCategory.put(category, new ArrayList()); + } + // 将商品添加到对应分类的列表中 + productsByCategory.get(category).add(product); + } + + // 显示所有分类 + System.out.println("\n===== 商品分类 ====="); + int index = 1; + List categories = new ArrayList<>(); + + // 使用迭代器遍历Map的键集 + Iterator categoryIterator = productsByCategory.keySet().iterator(); + while (categoryIterator.hasNext()) { + String category = categoryIterator.next(); + categories.add(category); + System.out.println(index + ". " + category); + index++; + } + + // 选择分类 + System.out.print("请选择要查看的分类(输入序号): "); + try { + int choice = Integer.parseInt(scanner.nextLine()); + if (choice < 1 || choice > categories.size()) { + System.out.println("无效的分类序号"); + return; + } + + String selectedCategory = categories.get(choice - 1); + System.out.println("\n===== " + selectedCategory + " ====="); + // 显示选中分类下的所有商品 + List categoryProducts = productsByCategory.get(selectedCategory); + for (Product product : categoryProducts) { + System.out.println(product); + } + } catch (NumberFormatException e) { + System.out.println("输入错误,请输入数字"); + } + } + + // 搜索商品 + private static void searchProducts() { + System.out.print("请输入商品名称关键字: "); + String keyword = scanner.nextLine().toLowerCase(); + + List result = new ArrayList<>(); + // 遍历商品列表查找匹配的商品 + for (Product product : products) { + if (product.getName().toLowerCase().contains(keyword)) { + result.add(product); + } + } + + System.out.println("\n===== 搜索结果 ====="); + if (result.isEmpty()) { + System.out.println("没有找到匹配的商品"); + } else { + for (Product product : result) { + System.out.println(product); + } + } + } + + // 查看购物车 + private static void viewShoppingCart() { + System.out.println("\n===== 我的购物车 ====="); + if (shoppingCart.isEmpty()) { + System.out.println("购物车是空的"); + return; + } + + double total = 0; + // 使用迭代器遍历购物车中的商品 + Iterator> iterator = shoppingCart.entrySet().iterator(); + while (iterator.hasNext()) { + Map.Entry entry = iterator.next(); + Product product = entry.getKey(); + int quantity = entry.getValue(); + double subtotal = product.getPrice() * quantity; + total += subtotal; + + System.out.printf("ID: %s, 名称: %s, 单价: ¥%.2f, 数量: %d, 小计: ¥%.2f%n", + product.getId(), product.getName(), product.getPrice(), + quantity, subtotal); + } + + System.out.printf("购物车总金额: ¥%.2f%n", total); + } + + // 添加商品到购物车 + private static void addToCart() { + System.out.print("请输入要添加的商品ID: "); + String productId = scanner.nextLine(); + + // 查找商品 + Product foundProduct = null; + for (Product product : products) { + if (product.getId().equals(productId)) { + foundProduct = product; + break; + } + } + + if (foundProduct == null) { + System.out.println("没有找到该商品"); + return; + } + + System.out.print("请输入购买数量: "); + try { + int quantity = Integer.parseInt(scanner.nextLine()); + if (quantity <= 0) { + System.out.println("数量必须大于0"); + return; + } + + if (quantity > foundProduct.getStock()) { + System.out.println("库存不足,当前库存: " + foundProduct.getStock()); + return; + } + + // 检查商品是否已在购物车中 + if (shoppingCart.containsKey(foundProduct)) { + // 如果已存在,更新数量 + int currentQuantity = shoppingCart.get(foundProduct); + shoppingCart.put(foundProduct, currentQuantity + quantity); + System.out.println("商品数量已更新,当前数量: " + (currentQuantity + quantity)); + } else { + // 如果不存在,添加到购物车 + shoppingCart.put(foundProduct, quantity); + System.out.println("商品已添加到购物车"); + } + } catch (NumberFormatException e) { + System.out.println("输入错误,请输入数字"); + } + } + + // 修改购物车商品数量 + private static void updateCartItemQuantity() { + if (shoppingCart.isEmpty()) { + System.out.println("购物车是空的"); + return; + } + + System.out.print("请输入要修改数量的商品ID: "); + String productId = scanner.nextLine(); + + // 查找购物车中的商品 + Product foundProduct = null; + Iterator iterator = shoppingCart.keySet().iterator(); + while (iterator.hasNext()) { + Product product = iterator.next(); + if (product.getId().equals(productId)) { + foundProduct = product; + break; + } + } + + if (foundProduct == null) { + System.out.println("购物车中没有该商品"); + return; + } + + System.out.print("请输入新的数量: "); + try { + int newQuantity = Integer.parseInt(scanner.nextLine()); + if (newQuantity <= 0) { + System.out.println("数量必须大于0,已从购物车中删除该商品"); + shoppingCart.remove(foundProduct); + return; + } + + if (newQuantity > foundProduct.getStock()) { + System.out.println("库存不足,当前库存: " + foundProduct.getStock()); + return; + } + + shoppingCart.put(foundProduct, newQuantity); + System.out.println("商品数量已更新"); + } catch (NumberFormatException e) { + System.out.println("输入错误,请输入数字"); + } + } + + // 从购物车删除商品 + private static void removeFromCart() { + if (shoppingCart.isEmpty()) { + System.out.println("购物车是空的"); + return; + } + + System.out.print("请输入要删除的商品ID: "); + String productId = scanner.nextLine(); + + // 查找购物车中的商品 + Product foundProduct = null; + Iterator iterator = shoppingCart.keySet().iterator(); + while (iterator.hasNext()) { + Product product = iterator.next(); + if (product.getId().equals(productId)) { + foundProduct = product; + break; + } + } + + if (foundProduct == null) { + System.out.println("购物车中没有该商品"); + return; + } + + shoppingCart.remove(foundProduct); + System.out.println("商品已从购物车中删除"); + } + + // 清空购物车 + private static void clearCart() { + if (shoppingCart.isEmpty()) { + System.out.println("购物车已经是空的"); + return; + } + + System.out.print("确定要清空购物车吗?(y/n): "); + String confirm = scanner.nextLine(); + if (confirm.equalsIgnoreCase("y")) { + shoppingCart.clear(); + System.out.println("购物车已清空"); + } else { + System.out.println("已取消清空操作"); + } + } +} diff --git a/day01/src/com/inmind/s_test_044/Order.java b/day01/src/com/inmind/s_test_044/Order.java new file mode 100644 index 0000000..833942a --- /dev/null +++ b/day01/src/com/inmind/s_test_044/Order.java @@ -0,0 +1,71 @@ +package com.inmind.s_test_044; + +import java.util.ArrayList; +import java.util.Date; +import java.util.List; + +/** + * 订单类,处理订单信息 + */ +public class Order { + private String id; // 订单ID + private User user; // 下单用户 + private List items; // 订单商品列表 + private double totalAmount; // 订单总金额 + private Date createTime; // 创建时间 + + public Order(String id, User user) { + this.id = id; + this.user = user; + this.items = new ArrayList<>(); + this.createTime = new Date(); + this.totalAmount = 0; + } + + // 添加商品到订单 + public void addOrderItem(Product product, int quantity) { + OrderItem item = new OrderItem(product, quantity); + items.add(item); + totalAmount += item.getSubtotal(); + } + + // 显示订单信息 + public void displayOrder() { + System.out.println("\n===== 订单信息 ====="); + System.out.println("订单ID: " + id); + System.out.println("用户: " + user.getUsername()); + System.out.println("创建时间: " + createTime); + System.out.println("商品列表:"); + + for (OrderItem item : items) { + System.out.println(item); + } + + System.out.printf("订单总金额: ¥%.2f%n", totalAmount); + } +} + +/** + * 订单项类,包含单个商品的购买信息 + */ +class OrderItem { + private Product product; // 商品 + private int quantity; // 数量 + private double subtotal; // 小计 + + public OrderItem(Product product, int quantity) { + this.product = product; + this.quantity = quantity; + this.subtotal = product.getPrice() * quantity; + } + + public double getSubtotal() { + return subtotal; + } + + @Override + public String toString() { + return String.format(" - %s: 数量 %d, 单价 ¥%.2f, 小计 ¥%.2f", + product.getName(), quantity, product.getPrice(), subtotal); + } +} diff --git a/day01/src/com/inmind/s_test_044/Product.java b/day01/src/com/inmind/s_test_044/Product.java new file mode 100644 index 0000000..61c51c2 --- /dev/null +++ b/day01/src/com/inmind/s_test_044/Product.java @@ -0,0 +1,67 @@ +package com.inmind.s_test_044; + +/** + * 商品类,存储商品信息 + */ +public class Product { + private String id; // 商品ID + private String name; // 商品名称 + private double price; // 商品价格 + private String category; // 商品类别 + private int stock; // 库存数量 + + public Product(String id, String name, double price, String category, int stock) { + this.id = id; + this.name = name; + this.price = price; + this.category = category; + this.stock = stock; + } + + // 减少库存 + public void reduceStock(int quantity) { + if (quantity <= stock) { + stock -= quantity; + } + } + + // getter方法 + public String getId() { + return id; + } + + public String getName() { + return name; + } + + public double getPrice() { + return price; + } + + public String getCategory() { + return category; + } + + public int getStock() { + return stock; + } + + @Override + public String toString() { + return String.format("ID: %s, 名称: %s, 价格: ¥%.2f, 库存: %d", + id, name, price, stock); + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + Product product = (Product) o; + return id.equals(product.id); + } + + @Override + public int hashCode() { + return id.hashCode(); + } +} diff --git a/day01/src/com/inmind/s_test_044/ShoppingSystem.java b/day01/src/com/inmind/s_test_044/ShoppingSystem.java new file mode 100644 index 0000000..914aa33 --- /dev/null +++ b/day01/src/com/inmind/s_test_044/ShoppingSystem.java @@ -0,0 +1,323 @@ +package com.inmind.s_test_044; + +import java.util.*; + +/** + * 购物系统主类,将购物车功能整合到主菜单 + */ +public class ShoppingSystem { + // 使用List存储所有商品,展示单列集合的应用 + private static List products = new ArrayList<>(); + // 使用Set存储所有用户,确保用户唯一性 + private static Set users = new HashSet<>(); + private static Scanner scanner = new Scanner(System.in); + private static User currentUser = null; + // 购物车,使用Map存储商品和数量,展示双列集合应用 + private static Map shoppingCart = new HashMap<>(); + + public static void main(String[] args) { + // 初始化数据 + initData(); + + System.out.println("===== 欢迎使用在线购物系统 ====="); + + // 用户登录 + login(); + + if (currentUser != null) { + System.out.println("登录成功!欢迎您," + currentUser.getUsername() + "!"); + // 显示主菜单(包含购物车功能) + showMainMenu(); + } + } + + // 初始化商品和用户数据 + private static void initData() { + // 添加商品 + products.add(new Product("P001", "笔记本电脑", 5999.99, "电子产品", 10)); + products.add(new Product("P002", "机械键盘", 299.99, "电脑配件", 20)); + products.add(new Product("P003", "无线鼠标", 129.99, "电脑配件", 30)); + products.add(new Product("P004", "蓝牙耳机", 799.99, "音频设备", 15)); + products.add(new Product("P005", "智能手机", 3999.99, "电子产品", 25)); + + // 添加用户 + users.add(new User("U001", "张三", "zhangsan@example.com")); + users.add(new User("U002", "李四", "lisi@example.com")); + users.add(new User("U003", "王五", "wangwu@example.com")); + } + + // 用户登录 + private static void login() { + System.out.print("请输入用户名: "); + String username = scanner.nextLine(); + + // 在Set集合中查找用户 + for (User user : users) { + if (user.getUsername().equals(username)) { + currentUser = user; + return; + } + } + + System.out.println("用户不存在,登录失败!"); + } + + // 显示主菜单(包含购物车功能) + private static void showMainMenu() { + while (true) { + System.out.println("\n===== 主菜单 ====="); + System.out.println("1. 浏览商品"); + System.out.println("2. 搜索商品"); + System.out.println("3. 查看购物车"); + System.out.println("4. 添加商品到购物车"); + System.out.println("5. 修改购物车商品数量"); + System.out.println("6. 从购物车删除商品"); + System.out.println("7. 清空购物车"); + System.out.println("8. 生成订单"); + System.out.println("9. 退出系统"); + System.out.print("请选择操作: "); + + int choice; + try { + choice = Integer.parseInt(scanner.nextLine()); + } catch (NumberFormatException e) { + System.out.println("请输入有效的数字"); + continue; + } + + switch (choice) { + case 1: + browseProducts(); + break; + case 2: + searchProducts(); + break; + case 3: + viewShoppingCart(); + break; + case 4: + addToCart(); + break; + case 5: + updateCartItemQuantity(); + break; + case 6: + removeFromCart(); + break; + case 7: + clearCart(); + break; + case 8: + createOrder(); + break; + case 9: + System.out.println("感谢使用,再见!"); + scanner.close(); + return; + default: + System.out.println("无效的选择,请重试"); + } + } + } + + // 浏览商品 + private static void browseProducts() { + System.out.println("\n===== 所有商品 ====="); + + // 使用Map对商品进行分类展示 + Map> productsByCategory = new HashMap<>(); + + for (Product product : products) { + String category = product.getCategory(); + // 如果分类不存在,则创建新的列表 + if (!productsByCategory.containsKey(category)) { + productsByCategory.put(category, new ArrayList<>()); + } + productsByCategory.get(category).add(product); + } + + // 遍历分类并显示商品 + for (Map.Entry> entry : productsByCategory.entrySet()) { + System.out.println("\n【" + entry.getKey() + "】"); + for (Product product : entry.getValue()) { + System.out.println(product); + } + } + } + + // 搜索商品 + private static void searchProducts() { + System.out.print("请输入商品名称关键字: "); + String keyword = scanner.nextLine(); + + List result = new ArrayList<>(); + for (Product product : products) { + if (product.getName().contains(keyword)) { + result.add(product); + } + } + + System.out.println("\n===== 搜索结果 ====="); + if (result.isEmpty()) { + System.out.println("没有找到匹配的商品"); + } else { + for (Product product : result) { + System.out.println(product); + } + } + } + + // 查看购物车 + private static void viewShoppingCart() { + System.out.println("\n===== 我的购物车 ====="); + if (shoppingCart.isEmpty()) { + System.out.println("购物车是空的"); + return; + } + + double total = 0; + for (Map.Entry entry : shoppingCart.entrySet()) { + Product product = entry.getKey(); + int quantity = entry.getValue(); + double subtotal = product.getPrice() * quantity; + total += subtotal; + System.out.printf("%s - 数量: %d, 单价: ¥%.2f, 小计: ¥%.2f%n", + product.getName(), quantity, product.getPrice(), subtotal); + } + + System.out.printf("\n购物车总计: ¥%.2f%n", total); + } + + // 添加商品到购物车 + private static void addToCart() { + System.out.print("请输入要添加的商品ID: "); + String productId = scanner.nextLine(); + + for (Product product : products) { + if (product.getId().equals(productId)) { + System.out.print("请输入购买数量: "); + try { + int quantity = Integer.parseInt(scanner.nextLine()); + if (quantity <= 0) { + System.out.println("数量必须大于0"); + return; + } + + // 检查库存 + if (quantity > product.getStock()) { + System.out.println("库存不足,当前库存: " + product.getStock()); + return; + } + + // 添加到购物车 + if (shoppingCart.containsKey(product)) { + shoppingCart.put(product, shoppingCart.get(product) + quantity); + } else { + shoppingCart.put(product, quantity); + } + + System.out.println("已添加到购物车: " + product.getName() + ", 数量: " + quantity); + return; + } catch (NumberFormatException e) { + System.out.println("数量输入无效"); + return; + } + } + } + + System.out.println("未找到该商品ID"); + } + + // 更新购物车中商品的数量 + private static void updateCartItemQuantity() { + System.out.print("请输入要修改数量的商品ID: "); + String productId = scanner.nextLine(); + + for (Product product : products) { + if (product.getId().equals(productId)) { + if (!shoppingCart.containsKey(product)) { + System.out.println("购物车中没有该商品"); + return; + } + + System.out.print("请输入新的数量: "); + try { + int quantity = Integer.parseInt(scanner.nextLine()); + if (quantity <= 0) { + System.out.println("数量必须大于0"); + return; + } + + // 检查库存 + if (quantity > product.getStock()) { + System.out.println("库存不足,当前库存: " + product.getStock()); + return; + } + + shoppingCart.put(product, quantity); + System.out.println("已更新数量: " + product.getName() + ", 新数量: " + quantity); + return; + } catch (NumberFormatException e) { + System.out.println("数量输入无效"); + return; + } + } + } + + System.out.println("未找到该商品ID"); + } + + // 从购物车中删除商品 + private static void removeFromCart() { + System.out.print("请输入要删除的商品ID: "); + String productId = scanner.nextLine(); + + for (Product product : products) { + if (product.getId().equals(productId)) { + if (shoppingCart.containsKey(product)) { + shoppingCart.remove(product); + System.out.println("已从购物车中删除: " + product.getName()); + } else { + System.out.println("购物车中没有该商品"); + } + return; + } + } + + System.out.println("未找到该商品ID"); + } + + // 清空购物车 + private static void clearCart() { + shoppingCart.clear(); + System.out.println("购物车已清空"); + } + + // 创建订单 + private static void createOrder() { + if (shoppingCart.isEmpty()) { + System.out.println("购物车是空的,无法创建订单"); + return; + } + + System.out.println("正在创建订单..."); + String orderId = "O" + System.currentTimeMillis(); + Order order = new Order(orderId, currentUser); + + // 将购物车中的商品添加到订单 + for (Map.Entry entry : shoppingCart.entrySet()) { + Product product = entry.getKey(); + int quantity = entry.getValue(); + order.addOrderItem(product, quantity); + // 减少库存 + product.reduceStock(quantity); + } + + // 显示订单信息 + order.displayOrder(); + System.out.println("订单创建成功!"); + + // 清空购物车 + shoppingCart.clear(); + } +} diff --git a/day01/src/com/inmind/s_test_044/User.java b/day01/src/com/inmind/s_test_044/User.java new file mode 100644 index 0000000..cf6340c --- /dev/null +++ b/day01/src/com/inmind/s_test_044/User.java @@ -0,0 +1,42 @@ +package com.inmind.s_test_044; + +/** + * 用户类,存储用户信息 + */ +public class User { + private String id; // 用户ID + private String username; // 用户名 + private String email; // 邮箱 + + public User(String id, String username, String email) { + this.id = id; + this.username = username; + this.email = email; + } + + // getter方法 + public String getId() { + return id; + } + + public String getUsername() { + return username; + } + + public String getEmail() { + return email; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + User user = (User) o; + return username.equals(user.username); + } + + @Override + public int hashCode() { + return username.hashCode(); + } +} diff --git a/day01/src/com/inmind/s_test_05/Account.java b/day01/src/com/inmind/s_test_05/Account.java new file mode 100644 index 0000000..3e59b91 --- /dev/null +++ b/day01/src/com/inmind/s_test_05/Account.java @@ -0,0 +1,48 @@ +package com.inmind.s_test_05; + +// 账户类 +class Account { + String id; // 账户ID + String name; // 账户名 + double balance; // 余额 + int pwdErrors; // 密码错误次数 + boolean locked; // 是否锁定 + static final int MAX_PWD_ERROR = 3; // 最大密码错误次数 + static final String PWD = "123456"; // 默认密码 + + // 构造方法 + public Account(String id, String name, double balance) { + this.id = id; + this.name = name; + this.balance = balance; + this.pwdErrors = 0; + this.locked = false; + } + + // 存款 + public void saveMoney(double amount) throws InvalidAmountException, AccountLockedException { + if (locked) throw new AccountLockedException("账户" + id + "已锁定"); + if (amount <= 0) throw new InvalidAmountException("存款金额必须大于0"); + balance += amount; + System.out.println(name + "存款" + amount + "元,当前余额:" + balance); + } + + // 取款 + public void getMoney(double amount, String pwd) throws Exception { + if (locked) throw new AccountLockedException("账户" + id + "已锁定"); + // 密码验证 + if (!PWD.equals(pwd)) { + pwdErrors++; + System.out.println("pwdErrors的值" + pwdErrors); + if (pwdErrors >= MAX_PWD_ERROR) { + locked = true; + throw new AccountLockedException("密码错误3次,账户" + id + "已锁定"); + } + throw new Exception("密码错误,剩余次数:" + (MAX_PWD_ERROR - pwdErrors)); + } + if (amount <= 0) throw new InvalidAmountException("取款金额必须大于0"); + if (amount > balance) throw new InsufficientFundsException("余额不足,当前余额:" + balance); + balance -= amount; + System.out.println(name + "取款" + amount + "元,当前余额:" + balance); + } +} \ No newline at end of file diff --git a/day01/src/com/inmind/s_test_05/AccountLockedException.java b/day01/src/com/inmind/s_test_05/AccountLockedException.java new file mode 100644 index 0000000..69bfcd0 --- /dev/null +++ b/day01/src/com/inmind/s_test_05/AccountLockedException.java @@ -0,0 +1,8 @@ +package com.inmind.s_test_05; + +// 自定义异常3:账户锁定异常 +class AccountLockedException extends Exception { + public AccountLockedException(String msg) { + super(msg); + } +} \ No newline at end of file diff --git a/day01/src/com/inmind/s_test_05/Bank.java b/day01/src/com/inmind/s_test_05/Bank.java new file mode 100644 index 0000000..1dc818b --- /dev/null +++ b/day01/src/com/inmind/s_test_05/Bank.java @@ -0,0 +1,45 @@ +package com.inmind.s_test_05; + +// 银行类 +class Bank { + private Account[] accounts; // 账户数组 + private int count; // 账户数量 + private static final double MAX_TRANSFER = 50000; // 单笔最大转账额 + + // 构造方法 + public Bank(int size) { + accounts = new Account[size]; + count = 0; + } + + // 创建账户 + public void addAccount(Account acc) { + if (count < accounts.length) { + accounts[count++] = acc; + System.out.println("创建账户成功:" + acc.id + "(" + acc.name + ")"); + } + } + + // 查找账户 + public Account findAccount(String id) throws Exception { + for (int i = 0; i < count; i++) { + if (accounts[i].id.equals(id)) { + return accounts[i]; + } + } + throw new Exception("账户" + id + "不存在"); + } + + // 转账 + public void transferMoney(String fromId, String toId, double amount, String pwd) throws Exception { + Account from = findAccount(fromId); + Account to = findAccount(toId); + + if (amount <= 0) throw new InvalidAmountException("转账金额必须大于0"); + if (amount > MAX_TRANSFER) throw new TransferLimitException("超过最大转账额" + MAX_TRANSFER); + + from.getMoney(amount, pwd); // 先取款 + to.saveMoney(amount); // 再存款 + System.out.println("从" + from.name + "向" + to.name + "转账" + amount + "元成功"); + } +} \ No newline at end of file diff --git a/day01/src/com/inmind/s_test_05/InsufficientFundsException.java b/day01/src/com/inmind/s_test_05/InsufficientFundsException.java new file mode 100644 index 0000000..71826bf --- /dev/null +++ b/day01/src/com/inmind/s_test_05/InsufficientFundsException.java @@ -0,0 +1,8 @@ +package com.inmind.s_test_05; + +// 自定义异常1:余额不足异常 +class InsufficientFundsException extends Exception { + public InsufficientFundsException(String msg) { + super(msg); + } +} \ No newline at end of file diff --git a/day01/src/com/inmind/s_test_05/InvalidAmountException.java b/day01/src/com/inmind/s_test_05/InvalidAmountException.java new file mode 100644 index 0000000..e1145a9 --- /dev/null +++ b/day01/src/com/inmind/s_test_05/InvalidAmountException.java @@ -0,0 +1,8 @@ +package com.inmind.s_test_05; + +// 自定义异常2:无效金额异常 +class InvalidAmountException extends Exception { + public InvalidAmountException(String msg) { + super(msg); + } +} \ No newline at end of file diff --git a/day01/src/com/inmind/s_test_05/Test.java b/day01/src/com/inmind/s_test_05/Test.java new file mode 100644 index 0000000..f419a7e --- /dev/null +++ b/day01/src/com/inmind/s_test_05/Test.java @@ -0,0 +1,65 @@ +package com.inmind.s_test_05; + +import java.util.Objects; + +// 主程序 +public class Test { + public static void main(String[] args) { + Bank bank = new Bank(10); + try { + // 创建账户 + bank.addAccount(new Account("1001", "张三", 10000)); + bank.addAccount(new Account("1002", "李四", 5000)); + + Account zhang = bank.findAccount("1001"); + // 正常操作 + zhang.saveMoney(2000); + zhang.getMoney(3000, "123456"); + + // 测试异常场景 + try { + zhang.getMoney(20000, "123456"); + } // 余额不足 + catch (InsufficientFundsException e) { + System.out.println("异常:" + e.getMessage()); + } + + try { + bank.transferMoney("1001", "1002", 60000, "123456"); + } // 转账超限 + catch (TransferLimitException e) { + System.out.println("异常:" + e.getMessage()); + } + + try { + zhang.getMoney(1000, "111"); + } // 密码错误 + catch (Exception e) { + System.out.println("异常:" + e.getMessage()); + } + + try { + zhang.getMoney(1000, "111"); + } // 锁定账户 + catch (Exception e) { + System.out.println("异常:" + e.getMessage()); + } + try { + zhang.getMoney(1000, "111"); + } // 锁定账户 + catch (AccountLockedException e) { + System.out.println("异常:" + e.getMessage()); + } + + try { + zhang.getMoney(1000, "111"); + } // 锁定账户 + catch (AccountLockedException e) { + System.out.println("异常:" + e.getMessage()); + } + + } catch (Exception e) { + System.out.println("系统错误:" + e.getMessage()); + } + } +} diff --git a/day01/src/com/inmind/s_test_05/TransferLimitException.java b/day01/src/com/inmind/s_test_05/TransferLimitException.java new file mode 100644 index 0000000..048a230 --- /dev/null +++ b/day01/src/com/inmind/s_test_05/TransferLimitException.java @@ -0,0 +1,8 @@ +package com.inmind.s_test_05; + +// 自定义异常4:转账超限异常 +class TransferLimitException extends Exception { + public TransferLimitException(String msg) { + super(msg); + } +} \ No newline at end of file diff --git a/day01/src/com/inmind/s_test_06/MyCallable.java b/day01/src/com/inmind/s_test_06/MyCallable.java new file mode 100644 index 0000000..0b1793f --- /dev/null +++ b/day01/src/com/inmind/s_test_06/MyCallable.java @@ -0,0 +1,10 @@ +package com.inmind.s_test_06; + +import java.util.concurrent.Callable; + +public class MyCallable implements Callable { + @Override + public String call() throws Exception { + return ""; + } +} diff --git a/day01/src/com/inmind/s_test_06/MyRunnable.java b/day01/src/com/inmind/s_test_06/MyRunnable.java new file mode 100644 index 0000000..e78f8fd --- /dev/null +++ b/day01/src/com/inmind/s_test_06/MyRunnable.java @@ -0,0 +1,14 @@ +package com.inmind.s_test_06; + +public class MyRunnable implements Runnable{ + @Override + public void run() { + System.out.println(Thread.currentThread().getName()+"执行了任务"); + + try { + Thread.sleep(14000); + } catch (InterruptedException e) { + throw new RuntimeException(e); + } + } +} diff --git a/day01/src/com/inmind/s_test_06/Test.java b/day01/src/com/inmind/s_test_06/Test.java new file mode 100644 index 0000000..b862d43 --- /dev/null +++ b/day01/src/com/inmind/s_test_06/Test.java @@ -0,0 +1,160 @@ +import java.util.concurrent.locks.Lock; +import java.util.concurrent.locks.ReentrantLock; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; + +// 银行账户类,包含两种同步方式的操作方法 +class BankAccount { + private int balance; // 账户余额 + private Lock lock; // 显式锁对象,用于同步控制 + + // 构造方法:初始化账户余额和锁对象 + public BankAccount(int initialBalance) { + this.balance = initialBalance; // 设置初始余额 + this.lock = new ReentrantLock(); // 初始化可重入锁 + } + + // 1. 使用synchronized关键字实现存款操作(自动同步) + public synchronized void depositWithSync(int amount) { + // 只处理正数存款 + if (amount > 0) { + // 计算新余额 + int newBalance = balance + amount; + + // 模拟银行处理时间(100毫秒) + try { + Thread.sleep(100); + } catch (InterruptedException e) { + e.printStackTrace(); // 处理中断异常 + } + + // 更新余额 + balance = newBalance; + + // 打印操作信息:当前线程名、存款金额、最新余额 + System.out.println(Thread.currentThread().getName() + + " 存款 " + amount + ",余额: " + balance); + } + } + + // 2. 使用Lock实现取款操作(手动同步) + public void withdrawWithLock(int amount) { + lock.lock(); // 手动获取锁,确保操作安全 + + try { + // 检查取款金额是否有效(正数且不超过余额) + if (amount > 0 && amount <= balance) { + // 计算新余额 + int newBalance = balance - amount; + + // 模拟银行处理时间(100毫秒) + try { + Thread.sleep(100); + } catch (InterruptedException e) { + e.printStackTrace(); // 处理中断异常 + } + + // 更新余额 + balance = newBalance; + + // 打印操作信息 + System.out.println(Thread.currentThread().getName() + + " 取款 " + amount + ",余额: " + balance); + } else { + // 取款失败提示 + System.out.println(Thread.currentThread().getName() + + " 取款失败,余额不足"); + } + } finally { + lock.unlock(); // 确保锁一定会被释放,避免死锁 + } + } + + // 获取当前账户余额 + public int getBalance() { + return balance; + } +} + +// 存款任务类:实现Runnable接口,封装存款操作 +class DepositTask implements Runnable { + private BankAccount account; // 目标银行账户 + private int amount; // 存款金额 + + // 构造方法:指定操作的账户和金额 + public DepositTask(BankAccount account, int amount) { + this.account = account; + this.amount = amount; + } + + // 线程执行的任务:调用同步存款方法 + @Override + public void run() { + account.depositWithSync(amount); + } +} + +// 取款任务类:实现Runnable接口,封装取款操作 +class WithdrawTask implements Runnable { + private BankAccount account; // 目标银行账户 + private int amount; // 取款金额 + + // 构造方法:指定操作的账户和金额 + public WithdrawTask(BankAccount account, int amount) { + this.account = account; + this.amount = amount; + } + + // 线程执行的任务:调用Lock取款方法 + @Override + public void run() { + account.withdrawWithLock(amount); + } +} + +// 主类:演示多线程操作银行账户 +public class Test { + public static void main(String[] args) { + // 创建一个初始余额为1000的银行账户 + BankAccount account = new BankAccount(1000); + + // 第一部分:演示Thread和Runnable的基本使用 + System.out.println("=== 演示Thread和Runnable ==="); + + // 创建存款线程:线程名"存款人A",存款500 + Thread depositThread1 = new Thread( + new DepositTask(account, 500), "存款人A"); + + // 创建取款线程:线程名"取款人X",取款300 + Thread withdrawThread1 = new Thread( + new WithdrawTask(account, 300), "取款人X"); + + // 启动两个线程 + depositThread1.start(); + withdrawThread1.start(); + + // 等待两个线程执行完成后再继续 + try { + depositThread1.join(); // 主线程等待存款线程完成 + withdrawThread1.join(); // 主线程等待取款线程完成 + } catch (InterruptedException e) { + e.printStackTrace(); + } + + // 第二部分:演示线程池Executors的使用 + System.out.println("\n=== 演示线程池Executors ==="); + + // 创建固定大小为3的线程池 + ExecutorService executor = Executors.newFixedThreadPool(3); + + // 向线程池提交多个任务 + executor.submit(new DepositTask(account, 200)); // 存款人B存200 + executor.submit(new WithdrawTask(account, 400)); // 取款人Y取400 + executor.submit(new DepositTask(account, 1000)); // 存款人C存1000 + executor.submit(new WithdrawTask(account, 600)); // 取款人Z取600 + + // 关闭线程池(不再接受新任务,等待现有任务完成) + executor.shutdown(); + } +} + \ No newline at end of file diff --git a/day01/src/com/inmind/s_test_06/ThreadPoolTest1.java b/day01/src/com/inmind/s_test_06/ThreadPoolTest1.java new file mode 100644 index 0000000..9658958 --- /dev/null +++ b/day01/src/com/inmind/s_test_06/ThreadPoolTest1.java @@ -0,0 +1,44 @@ +package com.inmind.s_test_06; + +import java.util.concurrent.ArrayBlockingQueue; +import java.util.concurrent.Executors; +import java.util.concurrent.ThreadPoolExecutor; +import java.util.concurrent.TimeUnit; + +public class ThreadPoolTest1 { + public static void main(String[] args) { + /* + public ThreadPoolExecutor(int corePoolSize, + int maximumPoolSize, + long keepAliveTime, + TimeUnit unit, + BlockingQueue workQueue, + ThreadFactory threadFactory, + RejectedExecutionHandler handler) + */ + + //AbortPolicy就是一个拒绝策略,新任务来了,无法处理就抛出异常 + ThreadPoolExecutor poolExecutor = new ThreadPoolExecutor(3, 5, 8, + TimeUnit.SECONDS, new ArrayBlockingQueue<>(4), Executors.defaultThreadFactory(), new ThreadPoolExecutor.AbortPolicy()); + + //如何将任务交给线程池 + MyRunnable task = new MyRunnable(); + poolExecutor.execute(task);//线程池会自动创建一个新线程,自动处理这个任务 + poolExecutor.execute(task);//线程池会自动创建一个新线程,自动处理这个任务 + poolExecutor.execute(task);//线程池会自动创建一个新线程,自动处理这个任务 + //线程任务时间加长之后,3个线程占用,4个任务队列排满,就开始创建新的临时线程 + poolExecutor.execute(task);//复用前面核心线程 + poolExecutor.execute(task);//复用前面核心线程 + poolExecutor.execute(task); + poolExecutor.execute(task); + //到了临时线程创建时机 + poolExecutor.execute(task); + poolExecutor.execute(task); + //再来新的任务,就到了拒绝新任务的处理 + poolExecutor.execute(task); + + + poolExecutor.shutdown();//等待线程池任务结束后才关闭线程池 + poolExecutor.shutdownNow();//不等待线程池任务结束,立即关闭线程池 + } +} diff --git a/day01/src/com/inmind/s_test_06/ThreadPoolTest2.java b/day01/src/com/inmind/s_test_06/ThreadPoolTest2.java new file mode 100644 index 0000000..8c69a92 --- /dev/null +++ b/day01/src/com/inmind/s_test_06/ThreadPoolTest2.java @@ -0,0 +1,14 @@ +package com.inmind.s_test_06; + +import java.util.concurrent.*; + +public class ThreadPoolTest2 { + public static void main(String[] args) { + + ExecutorService poolExecutor = new ThreadPoolExecutor(3, 5, 8, + TimeUnit.SECONDS, new ArrayBlockingQueue<>(4), Executors.defaultThreadFactory(), new ThreadPoolExecutor.AbortPolicy()); + + //如何将任务交给线程池 + + } +} diff --git a/day01/src/com/inmind/s_test_07/StudentScorePractice.java b/day01/src/com/inmind/s_test_07/StudentScorePractice.java new file mode 100644 index 0000000..2dd2e45 --- /dev/null +++ b/day01/src/com/inmind/s_test_07/StudentScorePractice.java @@ -0,0 +1,142 @@ +package com.inmind.s_test_07; +/* +需求说明 +本案例模拟学生成绩管理系统,需要实现以下业务功能: + +生成测试学生数据(包含姓名、年龄、成绩) +打印所有学生的完整信息 +筛选并打印成绩及格(≥60 分)的学生 +统计 18 岁以上且成绩及格的学生数量 +提取并打印所有学生的姓名 +将学生成绩转换为等级(A/B/C/D)并展示 +获取并展示第 3-5 名学生信息(按原始顺序) +合并 "及格学生" 和 "前 2 名学生" 两个数据集并展示 +技术点说明 +Supplier 接口:用于提供学生数据列表,体现 "供给型" 功能 +Consumer 接口:用于消费学生对象(打印信息),体现 "消费型" 功能 +Predicate 接口:用于定义筛选条件(成绩及格、成年),体现 "判断型" 功能,包含条件组合(and) +Function 接口:用于数据转换(学生→姓名、成绩→等级),体现 "功能型" 功能 +Stream 方法: +forEach:遍历元素 +filter:按条件筛选 +count:统计元素数量 +map:元素转换 +skip:跳过指定数量元素 +limit:限制获取元素数量 +concat:合并两个流 + +通过这个案例可以清晰看到 lambda 表达式如何与四大核心函数式接口配合,以及 Stream API 的各种方法在实际业务中的应用,所有操作都围绕真实业务场景设计,便于理解 lambda 表达式的实用价值 + */ +import java.util.ArrayList; +import java.util.List; +import java.util.function.Consumer; +import java.util.function.Function; +import java.util.function.Predicate; +import java.util.function.Supplier; +import java.util.stream.Stream; + +// 学生类 +class Student { + private String name; + private int age; + private double score; + + public Student(String name, int age, double score) { + this.name = name; + this.age = age; + this.score = score; + } + + // getter方法 + public String getName() { return name; } + public int getAge() { return age; } + public double getScore() { return score; } + + @Override + public String toString() { + return "姓名: " + name + ", 年龄: " + age + ", 成绩: " + score; + } +} + +public class StudentScorePractice { + public static void main(String[] args) { + // 1. 使用Supplier接口生成测试数据(提供学生列表) + Supplier> studentSupplier = () -> { + List students = new ArrayList<>(); + students.add(new Student("张三", 18, 85.5)); + students.add(new Student("李四", 17, 92.0)); + students.add(new Student("王五", 19, 68.5)); + students.add(new Student("赵六", 16, 59.0)); + students.add(new Student("钱七", 20, 76.5)); + students.add(new Student("孙八", 18, 95.0)); + students.add(new Student("周九", 17, 45.5)); + students.add(new Student("吴十", 19, 88.0)); + return students; + }; + + // 获取学生列表 + List students = studentSupplier.get(); + + // 2. 使用Consumer接口打印学生信息(消费学生数据) + Consumer printStudent = (s) -> System.out.println(s); + + // 3. 使用Consumer遍历所有学生 + System.out.println("=== 所有学生信息 ==="); + students.stream().forEach(printStudent); + + // 4. 使用Predicate定义筛选条件:成绩及格(>=60) + Predicate isPass = (s) -> s.getScore() >= 60; + + // 5. 使用filter+Predicate筛选及格学生并打印 + System.out.println("\n=== 及格学生信息 ==="); + students.stream() + .filter(isPass) + .forEach(printStudent); + + // 6. 统计18岁以上及格学生数量(count用法) + Predicate isAdult = (s) -> s.getAge() >= 18; + long adultPassCount = students.stream() + .filter(isPass.and(isAdult)) // Predicate组合 + .count(); + System.out.println("\n18岁以上及格学生数量: " + adultPassCount); + + // 7. 使用Function将学生转换为姓名(数据转换) + Function toName = (s) -> s.getName(); + + // 8. 使用map+Function获取所有学生姓名并打印 + System.out.println("\n=== 所有学生姓名 ==="); + students.stream() + .map(toName) + .forEach(name -> System.out.println(name)); + + // 9. 使用Function将学生成绩转换为等级(A:90+, B:80-89, C:60-79, D:60-) + Function scoreToLevel = (s) -> { + double score = s.getScore(); + if (score >= 90) return "A"; + else if (score >= 80) return "B"; + else if (score >= 60) return "C"; + else return "D"; + }; + + // 10. 转换并打印学生成绩等级 + System.out.println("\n=== 学生成绩等级 ==="); + students.stream() + .map(scoreToLevel) + .forEach(level -> System.out.println(level)); + + // 11. 使用skip和limit获取中间范围数据(跳过前2个,取3个) + System.out.println("\n=== 第3-5名学生(按原始顺序) ==="); + students.stream() + .skip(2) // 跳过前2个 + .limit(3) // 取3个 + .forEach(printStudent); + + // 12. 使用concat合并两个流(及格学生流 + 前2名学生流) + Stream passStream = students.stream().filter(isPass); + Stream top2Stream = students.stream().limit(2); + + System.out.println("\n=== 合并流(及格学生 + 前2名学生) ==="); + Stream.concat(passStream, top2Stream) + .forEach(printStudent); + } +} diff --git a/day01/src/com/inmind/s_test_08/CompactFileManager.java b/day01/src/com/inmind/s_test_08/CompactFileManager.java new file mode 100644 index 0000000..c7b40f0 --- /dev/null +++ b/day01/src/com/inmind/s_test_08/CompactFileManager.java @@ -0,0 +1,236 @@ +package com.inmind.s_test_08; + +import java.io.File; +import java.io.FilenameFilter; +import java.text.SimpleDateFormat; +import java.util.ArrayList; +import java.util.Date; +import java.util.List; +import java.util.Scanner; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +public class CompactFileManager { + private static Scanner scanner = new Scanner(System.in); + private static SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm"); + private static String currentPath = System.getProperty("user.home"); + + public static void main(String[] args) { + while (true) { + System.out.println("\n===== 文件管理工具 ====="); + System.out.println("当前路径: " + currentPath); + System.out.println("1. 浏览目录 2. 切换目录 3. 创建文件/目录"); + System.out.println("4. 删除项目 5. 搜索文件 6. 批量操作 7. 退出"); + System.out.print("请选择: "); + + int choice; + try { + choice = Integer.parseInt(scanner.nextLine()); + if (choice < 1 || choice > 7) { + System.out.println("请输入1-7之间的数字!"); + continue; + } + } catch (NumberFormatException e) { + System.out.println("请输入有效数字!"); + continue; + } + + switch (choice) { + case 1: browseDirectory(); break; + case 2: changeDirectory(); break; + case 3: createItem(); break; + case 4: deleteItem(); break; + case 5: searchFiles(); break; + case 6: batchOperations(); break; + case 7: + System.out.println("再见!"); + scanner.close(); + return; + } + } + } + + // 浏览当前目录 + private static void browseDirectory() { + File dir = new File(currentPath); + if (!dir.exists() || !dir.isDirectory()) { + System.out.println("无效目录!"); + return; + } + + File[] items = dir.listFiles(); + if (items == null || items.length == 0) { + System.out.println("目录为空"); + return; + } + + System.out.println("\n目录内容:"); + System.out.printf("%-5s %-30s %-15s %s%n", "类型", "名称", "大小", "修改时间"); + System.out.println("------------------------------------------------"); + + // 先显示目录,再显示文件 + for (File item : items) { + if (item.isDirectory()) { + printItemInfo(item); + } + } + for (File item : items) { + if (item.isFile()) { + printItemInfo(item); + } + } + } + + // 打印项目信息 + private static void printItemInfo(File item) { + String type = item.isDirectory() ? "目录" : "文件"; + String size = item.isDirectory() ? "-" : item.length() + "B"; + String time = sdf.format(new Date(item.lastModified())); + System.out.printf("%-5s %-30s %-15s %s%n", type, item.getName(), size, time); + } + + // 切换目录 + private static void changeDirectory() { + System.out.print("输入目标路径(..返回上一级): "); + String path = scanner.nextLine().trim(); + File newDir = path.equals("..") ? new File(currentPath).getParentFile() : + new File(path).isAbsolute() ? new File(path) : + new File(currentPath + File.separator + path); + + if (newDir != null && newDir.exists() && newDir.isDirectory()) { + currentPath = newDir.getAbsolutePath(); + System.out.println("已切换到: " + currentPath); + } else { + System.out.println("目录不存在!"); + } + } + + // 创建文件或目录 + private static void createItem() { + System.out.print("1.创建文件 2.创建目录,请选择: "); + String type = scanner.nextLine().trim(); + System.out.print("请输入名称: "); + String name = scanner.nextLine().trim(); + + if (name.isEmpty()) { + System.out.println("名称不能为空!"); + return; + } + + File item = new File(currentPath + File.separator + name); + if (item.exists()) { + System.out.println("已存在同名项目!"); + return; + } + + try { + boolean success = "1".equals(type) ? item.createNewFile() : item.mkdirs(); + System.out.println(success ? "创建成功!" : "创建失败!"); + } catch (Exception e) { + System.out.println("创建失败: " + e.getMessage()); + } + } + + // 删除项目 + private static void deleteItem() { + System.out.print("输入要删除的名称: "); + String name = scanner.nextLine().trim(); + File item = new File(currentPath + File.separator + name); + + if (!item.exists()) { + System.out.println("项目不存在!"); + return; + } + + System.out.print("确定删除? (y/n): "); + if ("y".equals(scanner.nextLine().trim().toLowerCase())) { + boolean success = deleteRecursive(item); + System.out.println(success ? "删除成功!" : "删除失败!"); + } else { + System.out.println("已取消"); + } + } + + // 递归删除 + private static boolean deleteRecursive(File item) { + if (item.isDirectory()) { + File[] children = item.listFiles(); + if (children != null) { + for (File child : children) { + if (!deleteRecursive(child)) return false; + } + } + } + return item.delete(); + } + + // 搜索文件 + private static void searchFiles() { + System.out.print("输入搜索关键词: "); + String keyword = scanner.nextLine().trim().toLowerCase(); + System.out.print("1.当前目录 2.包含子目录,请选择: "); + int scope = Integer.parseInt(scanner.nextLine().trim()); + + List results = new ArrayList<>(); + if (scope == 1) { + File[] items = new File(currentPath).listFiles(); + if (items != null) { + for (File item : items) { + if (item.getName().toLowerCase().contains(keyword)) { + results.add(item); + } + } + } + } else { + searchRecursive(new File(currentPath), keyword, results); + } + + System.out.println("找到 " + results.size() + " 个匹配项:"); + results.forEach(f -> System.out.println((f.isDirectory() ? "[目录] " : "[文件] ") + f.getAbsolutePath())); + } + + // 递归搜索 + private static void searchRecursive(File dir, String keyword, List results) { + if (!dir.isDirectory()) return; + File[] items = dir.listFiles(); + if (items == null) return; + + for (File item : items) { + if (item.getName().toLowerCase().contains(keyword)) results.add(item); + if (item.isDirectory()) searchRecursive(item, keyword, results); + } + } + + // 批量操作 + private static void batchOperations() { + System.out.print("输入文件扩展名(如txt): "); + String ext = scanner.nextLine().trim().toLowerCase(); + if (ext.isEmpty()) { + System.out.println("扩展名不能为空!"); + return; + } + + // 使用过滤器筛选特定类型文件 + File dir = new File(currentPath); + File[] files = dir.listFiles(new FilenameFilter() { + @Override + public boolean accept(File d, String name) { + return new File(d, name).isFile() && name.toLowerCase().endsWith("." + ext); + } + }); + + if (files == null || files.length == 0) { + System.out.println("未找到." + ext + "文件"); + return; + } + + System.out.println("找到 " + files.length + " 个文件:"); + Stream.of(files).forEach(f -> System.out.println(" " + f.getName())); + + System.out.print("是否删除这些文件? (y/n): "); + if ("y".equals(scanner.nextLine().trim().toLowerCase())) { + long count = java.util.Arrays.stream(files).filter(f -> f.delete()).count(); + System.out.println("已删除 " + count + " 个文件"); + } + } +} diff --git a/day01/src/com/inmind/s_test_08/FileManagerWithComments.java b/day01/src/com/inmind/s_test_08/FileManagerWithComments.java new file mode 100644 index 0000000..a368e0d --- /dev/null +++ b/day01/src/com/inmind/s_test_08/FileManagerWithComments.java @@ -0,0 +1,302 @@ +package com.inmind.s_test_08; +import java.io.File; +import java.io.FilenameFilter; +import java.text.SimpleDateFormat; +import java.util.*; + +// 文件管理工具类,实现基本的文件和目录操作 +public class FileManagerWithComments { + // 用于接收用户输入的扫描器 + private static Scanner scanner = new Scanner(System.in); + // 用于格式化文件修改时间的日期格式化器 + private static SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm"); + // 当前工作目录,初始化为用户主目录 + private static String currentPath = System.getProperty("user.home"); + + // 主方法,程序入口 + public static void main(String[] args) { + // 循环显示主菜单,直到用户选择退出 + while (true) { + System.out.println("\n===== 文件管理工具 ====="); + System.out.println("当前路径: " + currentPath); + System.out.println("1. 浏览目录 2. 切换目录 3. 创建文件/目录"); + System.out.println("4. 删除项目 5. 搜索文件 6. 批量操作 7. 退出"); + System.out.print("请选择: "); + + int choice; + try { + // 读取用户选择 + choice = Integer.parseInt(scanner.nextLine()); + // 验证选择是否在有效范围内 + if (choice < 1 || choice > 7) { + System.out.println("请输入1-7之间的数字!"); + continue; + } + } catch (NumberFormatException e) { + // 处理非数字输入的异常 + System.out.println("请输入有效数字!"); + continue; + } + + // 根据用户选择执行相应操作 + switch (choice) { + case 1: browseDirectory(); break; + case 2: changeDirectory(); break; + case 3: createItem(); break; + case 4: deleteItem(); break; + case 5: searchFiles(); break; + case 6: batchOperations(); break; + case 7: + System.out.println("再见!"); + scanner.close(); + return; + } + } + } + + // 浏览当前目录内容 + private static void browseDirectory() { + // 创建当前目录的File对象 + File dir = new File(currentPath); + // 检查目录是否有效 + if (!dir.exists() || !dir.isDirectory()) { + System.out.println("无效目录!"); + return; + } + + // 获取目录下的所有文件和子目录 + File[] items = dir.listFiles(); + // 检查目录是否为空 + if (items == null || items.length == 0) { + System.out.println("目录为空"); + return; + } + + // 显示目录内容标题 + System.out.println("\n目录内容:"); + System.out.println("类型 名称 大小 修改时间"); + System.out.println("------------------------------------------------"); + + // 先显示所有子目录 + for (File item : items) { + if (item.isDirectory()) { + printItemInfo(item); + } + } + // 再显示所有文件 + for (File item : items) { + if (item.isFile()) { + printItemInfo(item); + } + } + } + + // 打印文件或目录的详细信息 + private static void printItemInfo(File item) { + // 确定项目类型(目录或文件) + String type = item.isDirectory() ? "目录" : "文件"; + // 确定大小信息(目录无大小,文件显示字节数) + String size = item.isDirectory() ? "-" : item.length() + "B"; + // 格式化修改时间 + String time = sdf.format(new Date(item.lastModified())); + + // 拼接并打印信息,保持列对齐 + String line = padRight(type, 6) + padRight(item.getName(), 30) + + padRight(size, 15) + time; + System.out.println(line); + } + + // 辅助方法:将字符串右对齐并填充空格至指定长度 + private static String padRight(String str, int length) { + // 如果字符串过长,截断并加空格 + if (str.length() >= length) { + return str.substring(0, length - 1) + " "; + } + // 否则补空格至指定长度 + StringBuilder sb = new StringBuilder(str); + while (sb.length() < length) { + sb.append(" "); + } + return sb.toString(); + } + + // 切换当前工作目录 + private static void changeDirectory() { + System.out.print("输入目标路径(..返回上一级): "); + String path = scanner.nextLine().trim(); + // 处理返回上一级、绝对路径和相对路径三种情况 + File newDir = path.equals("..") ? new File(currentPath).getParentFile() : + new File(path).isAbsolute() ? new File(path) : + new File(currentPath + File.separator + path); + + // 验证目录是否有效并切换 + if (newDir != null && newDir.exists() && newDir.isDirectory()) { + currentPath = newDir.getAbsolutePath(); + System.out.println("已切换到: " + currentPath); + } else { + System.out.println("目录不存在!"); + } + } + + // 创建文件或目录 + private static void createItem() { + System.out.print("1.创建文件 2.创建目录,请选择: "); + String type = scanner.nextLine().trim(); + System.out.print("请输入名称: "); + String name = scanner.nextLine().trim(); + + // 验证名称不为空 + if (name.isEmpty()) { + System.out.println("名称不能为空!"); + return; + } + + // 创建对应的File对象 + File item = new File(currentPath + File.separator + name); + // 检查是否已存在同名项目 + if (item.exists()) { + System.out.println("已存在同名项目!"); + return; + } + + try { + // 根据选择创建文件或目录 + boolean success = "1".equals(type) ? item.createNewFile() : item.mkdirs(); + System.out.println(success ? "创建成功!" : "创建失败!"); + } catch (Exception e) { + System.out.println("创建失败: " + e.getMessage()); + } + } + + // 删除文件或目录 + private static void deleteItem() { + System.out.print("输入要删除的名称: "); + String name = scanner.nextLine().trim(); + // 创建对应的File对象 + File item = new File(currentPath + File.separator + name); + + // 检查项目是否存在 + if (!item.exists()) { + System.out.println("项目不存在!"); + return; + } + + // 确认删除操作 + System.out.print("确定删除? (y/n): "); + if ("y".equals(scanner.nextLine().trim().toLowerCase())) { + // 执行删除操作 + boolean success = deleteRecursive(item); + System.out.println(success ? "删除成功!" : "删除失败!"); + } else { + System.out.println("已取消"); + } + } + + // 递归删除目录(先删除子内容,再删除自身) + private static boolean deleteRecursive(File item) { + // 如果是目录,先删除所有子文件和子目录 + if (item.isDirectory()) { + File[] children = item.listFiles(); + if (children != null) { + for (File child : children) { + // 递归删除子项,若有一项失败则整体失败 + if (!deleteRecursive(child)) return false; + } + } + } + // 删除当前项目(文件或空目录) + return item.delete(); + } + + // 搜索文件或目录 + private static void searchFiles() { + System.out.print("输入搜索关键词: "); + String keyword = scanner.nextLine().trim().toLowerCase(); + System.out.print("1.当前目录 2.包含子目录,请选择: "); + int scope = Integer.parseInt(scanner.nextLine().trim()); + + // 存储搜索结果的列表 + List results = new ArrayList<>(); + // 仅在当前目录搜索 + if (scope == 1) { + File[] items = new File(currentPath).listFiles(); + if (items != null) { + for (File item : items) { + // 检查名称是否包含关键词 + if (item.getName().toLowerCase().contains(keyword)) { + results.add(item); + } + } + } + } else { + // 递归搜索所有子目录 + searchRecursive(new File(currentPath), keyword, results); + } + + // 显示搜索结果 + System.out.println("找到 " + results.size() + " 个匹配项:"); + results.forEach(f -> { + System.out.println((f.isDirectory() ? "[目录] " : "[文件] ") + f.getAbsolutePath()); + }); + } + + // 递归搜索文件 + private static void searchRecursive(File dir, String keyword, List results) { + // 如果不是目录,直接返回 + if (!dir.isDirectory()) return; + // 获取目录下的所有项目 + File[] items = dir.listFiles(); + if (items == null) return; + + // 遍历所有项目 + for (File item : items) { + // 如果名称包含关键词,加入结果列表 + if (item.getName().toLowerCase().contains(keyword)) results.add(item); + // 如果是目录,递归搜索其子目录 + if (item.isDirectory()) searchRecursive(item, keyword, results); + } + } + + // 批量操作(筛选并删除特定类型文件) + private static void batchOperations() { + System.out.print("输入文件扩展名(如txt): "); + String ext = scanner.nextLine().trim().toLowerCase(); + // 验证扩展名不为空 + if (ext.isEmpty()) { + System.out.println("扩展名不能为空!"); + return; + } + + // 使用文件过滤器筛选特定类型的文件 + File dir = new File(currentPath); + File[] files = dir.listFiles(new FilenameFilter() { + @Override + public boolean accept(File d, String name) { + // 筛选条件:是文件且扩展名匹配 + return new File(d, name).isFile() && name.toLowerCase().endsWith("." + ext); + } + }); + + // 检查是否找到匹配文件 + if (files == null || files.length == 0) { + System.out.println("未找到." + ext + "文件"); + return; + } + + // 显示找到的文件 + System.out.println("找到 " + files.length + " 个文件:"); + for (File f : files) { + System.out.println(" " + f.getName()); + } + + // 确认并执行批量删除 + System.out.print("是否删除这些文件? (y/n): "); + if ("y".equals(scanner.nextLine().trim().toLowerCase())) { + int count = 0; + for (File f : files) { + if (f.delete()) count++; + } + System.out.println("已删除 " + count + " 个文件"); + } + } +} diff --git a/day01/src/com/inmind/s_test_08/PropertiesDemo.java b/day01/src/com/inmind/s_test_08/PropertiesDemo.java new file mode 100644 index 0000000..741b03a --- /dev/null +++ b/day01/src/com/inmind/s_test_08/PropertiesDemo.java @@ -0,0 +1,18 @@ +package com.inmind.s_test_08; + +import java.io.*; +import java.nio.charset.Charset; +import java.util.Properties; + +public class PropertiesDemo { + public static void main(String[] args) throws IOException { + Properties prop = new Properties(); + InputStream fis = new FileInputStream("demo.properties"); + InputStreamReader isr = new InputStreamReader(fis,"UTF-8"); + FileReader fr = new FileReader("demo.properties", Charset.forName("UTF-8")); + prop.load(fr); + fis.close(); + isr.close(); + System.out.println(prop); + } +} diff --git a/day01/src/com/inmind/s_test_11/UdpDemo.java b/day01/src/com/inmind/s_test_11/UdpDemo.java new file mode 100644 index 0000000..ec7ed14 --- /dev/null +++ b/day01/src/com/inmind/s_test_11/UdpDemo.java @@ -0,0 +1,41 @@ +package com.inmind.s_test_11; + +import java.net.*; +import java.util.Scanner; + +/* +目标:完成UDP通信快速入门,实现1发1收 + */ +public class UdpDemo { + public static void main(String[] args) throws Exception { + //1.创建客户端对象(发韭菜出去的人) + DatagramSocket socket = new DatagramSocket(); + //2.创建数据包对象封装要发出去的数据(创建一个韭菜盘子) + /* + public DatagramPacket(byte buf[], int offset, int length, + InetAddress address, int port) + 参数一:封装要发出去的数据 + 参数二:发送出去的数据大小(字节个数) + 参数三:服务端的IP地址(找到服务器主机) + 参数四:服务端程序的端口号 + */ + Scanner sc = new Scanner(System.in); + + while (true) { + System.out.println("请输入:"); + String msg = sc.nextLine(); + if ("exit".equals(msg)) { + System.out.println("谢谢使用,退出成功!!"); + socket.close(); + break; + } + + byte[] bytes = msg.getBytes(); + + DatagramPacket packet = new DatagramPacket(bytes, bytes.length, InetAddress.getLocalHost(),10022); + + //3.开始正式发送这个数据包的数据出去 + socket.send(packet); + } + } +} diff --git a/day01/src/com/inmind/s_test_11/UpdServerDemo.java b/day01/src/com/inmind/s_test_11/UpdServerDemo.java new file mode 100644 index 0000000..e6d1139 --- /dev/null +++ b/day01/src/com/inmind/s_test_11/UpdServerDemo.java @@ -0,0 +1,30 @@ +package com.inmind.s_test_11; + +import java.net.DatagramPacket; +import java.net.DatagramSocket; +import java.net.SocketException; + +public class UpdServerDemo { + public static void main(String[] args) throws Exception { + System.out.println("-------服务端启动了------"); + //1.创建服务端对象 + DatagramSocket socket = new DatagramSocket(10022); + byte[] buffer = new byte[1024 * 64]; + while (true) { + //2.创建一个数据包对象,用于接收数据的(创建韭菜盘子) + DatagramPacket packet = new DatagramPacket(buffer, buffer.length); + + //3.开始正式使用数据包来接收客户端发来的数据 + socket.receive(packet); + + //4.从字节数组中,把接收到的数据直接打印出来 + //接收多少就打印多少 + int length = packet.getLength(); + String result = new String(buffer, 0, length); + System.out.println(result); + System.out.println(packet.getAddress().getHostAddress()); + System.out.println(packet.getPort()); + } +// socket.close(); + } +} diff --git a/day01/src/com/inmind/s_test_11/WebServerDemo.java b/day01/src/com/inmind/s_test_11/WebServerDemo.java new file mode 100644 index 0000000..5353b9a --- /dev/null +++ b/day01/src/com/inmind/s_test_11/WebServerDemo.java @@ -0,0 +1,35 @@ +package com.inmind.s_test_11; + +import java.io.FileInputStream; +import java.io.IOException; +import java.io.OutputStream; +import java.net.ServerSocket; +import java.net.Socket; + +public class WebServerDemo { + public static void main(String[] args) throws IOException { + ServerSocket serverSocket = new ServerSocket(10088); + while (true) { + Socket socket = serverSocket.accept(); + System.out.println("接收到一个请求"); + //将工程中已有的index.html文件的数据响应给浏览器 + OutputStream out = socket.getOutputStream(); + + // 因为请求是一个浏览器,使用到了http协议,所以要遵循http协议的规范。 + //写回去的前三行固定, 前两行是一些字符, 第三行必须是空行 + out.write("HTTP/1.1 200 OK\r\n".getBytes());// 第一行 + out.write("Content-Type:text/html\r\n\r\n".getBytes());//第二行 第三行(空行) + //边读边输出网页字节数据 + FileInputStream fis = new FileInputStream("index.html"); + byte[] bytes = new byte[1024]; + int len; + while ((len = fis.read(bytes))!=-1) { + out.write(bytes,0,len); + } + + fis.close(); + socket.close(); + } + // serverSocket.close(); + } +} diff --git a/day01/src/com/inmind/s_test_11/chatroom/client/Client.java b/day01/src/com/inmind/s_test_11/chatroom/client/Client.java new file mode 100644 index 0000000..981a4a7 --- /dev/null +++ b/day01/src/com/inmind/s_test_11/chatroom/client/Client.java @@ -0,0 +1,87 @@ +package com.inmind.s_test_11.chatroom.client; + +import java.io.*; +import java.net.Socket; +import java.util.Scanner; + +public class Client { + public static void main(String[] args) throws IOException { + Socket socket = new Socket("127.0.0.1", 10001); + System.out.println("服务器已经连接成功"); + + + while (true) { + System.out.println("==============欢迎来到黑马聊天室================"); + System.out.println("1登录"); + System.out.println("2注册"); + System.out.println("请输入您的选择:"); + Scanner sc = new Scanner(System.in); + String choose = sc.nextLine(); + switch (choose) { + case "1" : login(socket); break; + case "2" : System.out.println("用户选择了注册"); break; + default : System.out.println("没有这个选项"); + } + } + } + + public static void login(Socket socket) throws IOException { + //获取输出流 + BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream())); + //键盘录入 + Scanner sc = new Scanner(System.in); + System.out.println("请输入用户名"); + String username = sc.nextLine(); + System.out.println("请输入密码"); + String password = sc.nextLine(); + + //拼接 + StringBuilder sb = new StringBuilder(); + //username=zhangsan&password=123 + sb.append("username=").append(username).append("&password=").append(password); + + //第一次写的是执行登录操作 + bw.write("login"); + bw.newLine(); + bw.flush(); + + //第二次写的是用户名和密码的信息 + //往服务器写出用户名和密码 + bw.write(sb.toString()); + bw.newLine(); + bw.flush(); + + //接收数据 + //获取输入流 + BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream())); + String message = br.readLine(); + System.out.println(message); + //1:登录成功 2 密码有误 3 用户名不存在 + if ("1".equals(message)) { + System.out.println("登录成功,开始聊天"); + //开一条单独的线程,专门用来接收服务端发送过来的聊天记录 + new Thread(new ClientMyRunnable(socket)).start(); + //开始聊天 + talk2All(bw); + } else if ("2".equals(message)) { + System.out.println("密码输入错误"); + } else if ("3".equals(message)) { + System.out.println("用户名不存在"); + } + + } + + //往服务器写出消息 + private static void talk2All(BufferedWriter bw) throws IOException { + Scanner sc = new Scanner(System.in); + while (true) { + System.out.println("请输入您要说的话"); + String str = sc.nextLine(); + //把聊天内容写给服务器 + bw.write(str); + bw.newLine(); + bw.flush(); + } + } +} + diff --git a/day01/src/com/inmind/s_test_11/chatroom/client/ClientMyRunnable.java b/day01/src/com/inmind/s_test_11/chatroom/client/ClientMyRunnable.java new file mode 100644 index 0000000..67667d3 --- /dev/null +++ b/day01/src/com/inmind/s_test_11/chatroom/client/ClientMyRunnable.java @@ -0,0 +1,29 @@ +package com.inmind.s_test_11.chatroom.client; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStreamReader; +import java.net.Socket; + +class ClientMyRunnable implements Runnable{ + Socket socket; + public ClientMyRunnable(Socket socket) { + this.socket = socket; + } + + @Override + public void run() { + + //循环,重复的接受 + while (true) { + try { + //接收服务器发送过来的聊天记录 + BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream())); + String msg = br.readLine(); + System.out.println(msg); + } catch (IOException e) { + e.printStackTrace(); + } + } + } +} diff --git a/day01/src/com/inmind/s_test_11/chatroom/server/MyRunnable.java b/day01/src/com/inmind/s_test_11/chatroom/server/MyRunnable.java new file mode 100644 index 0000000..64bbbb4 --- /dev/null +++ b/day01/src/com/inmind/s_test_11/chatroom/server/MyRunnable.java @@ -0,0 +1,94 @@ +package com.inmind.s_test_11.chatroom.server; + +import java.io.*; +import java.net.Socket; +import java.util.Properties; + +class MyRunnable implements Runnable { + Socket socket; + Properties prop; + + public MyRunnable(Socket socket, Properties prop) { + this.prop = prop; + this.socket = socket; + } + + @Override + public void run() { + try { + BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream())); + + while (true) { + String choose = br.readLine(); + switch (choose) { + case "login" : login(br);break; + case "register" : System.out.println("用户选择了注册操作");break; + } + } + } catch (IOException e) { + e.printStackTrace(); + } + } + + //获取用户登录时,传递过来的信息。 + //并进行判断 + public void login(BufferedReader br) throws IOException { + System.out.println("用户选择了登录操作"); + String userinfo = br.readLine(); + //username=zhangsan&password=123 + String[] userInfoArr = userinfo.split("&"); + String usernameInput = userInfoArr[0].split("=")[1]; + String passwordInput = userInfoArr[1].split("=")[1]; + System.out.println("用户输入的用户名为:" + usernameInput); + System.out.println("用户输入的密码为:" + passwordInput); + + if (prop.containsKey(usernameInput)) { + //如果用户名存在,继续判断密码 + String rightPassword = prop.get(usernameInput) + ""; + if (rightPassword.equals(passwordInput)) { + //提示用户登录成功,可以开始聊天 + writeMessage2Client("1"); + //登录成功的时候,就需要把客户端的连接对象Socket保存起来 + Server.list.add(socket); + //写一个while(){}表示正在聊天 + //接收客户端发送过来的消息,并打印在控制台 + talk2All(br, usernameInput); + } else { + //密码输入有误 + writeMessage2Client("2"); + } + } else { + //如果用户名不存在,直接回写 + writeMessage2Client("3"); + } + } + + private void talk2All(BufferedReader br, String username) throws IOException { + while (true) { + String message = br.readLine(); + System.out.println(username + "发送过来消息:" + message); + + //群发 + for (Socket s : Server.list) { + //s依次表示每一个客户端的连接对象 + writeMessage2Client(s, username + "发送过来消息:" + message); + } + } + } + + public void writeMessage2Client(String message) throws IOException { + //获取输出流 + BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream())); + bw.write(message); + bw.newLine(); + bw.flush(); + } + + public void writeMessage2Client(Socket s, String message) throws IOException { + //获取输出流 + BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(s.getOutputStream())); + bw.write(message); + bw.newLine(); + bw.flush(); + } +} \ No newline at end of file diff --git a/day01/src/com/inmind/s_test_11/chatroom/server/Server.java b/day01/src/com/inmind/s_test_11/chatroom/server/Server.java new file mode 100644 index 0000000..bb9f132 --- /dev/null +++ b/day01/src/com/inmind/s_test_11/chatroom/server/Server.java @@ -0,0 +1,32 @@ +package com.inmind.s_test_11.chatroom.server; + +import java.io.*; +import java.net.ServerSocket; +import java.net.Socket; +import java.util.ArrayList; +import java.util.Properties; + +public class Server { + + static ArrayList list = new ArrayList<>(); + + public static void main(String[] args) throws IOException { + ServerSocket ss = new ServerSocket(10001); + + //1.把本地文件中正确的用户名和密码获取到 + Properties prop = new Properties(); +// FileInputStream fis = new FileInputStream("sockethomework\\servicedir\\userinfo.txt"); + FileInputStream fis = new FileInputStream("day01\\src\\com\\inmind\\s_test_11\\chatroom\\userinfo.txt"); + prop.load(fis); + fis.close(); + + //2.只要来了一个客户端,就开一条线程处理 + while (true) { + Socket socket = ss.accept(); + System.out.println("有客户端来链接"); + new Thread(new MyRunnable(socket, prop)).start(); + } + } +} + + diff --git a/day01/src/com/inmind/s_test_11/chatroom/userinfo.txt b/day01/src/com/inmind/s_test_11/chatroom/userinfo.txt new file mode 100644 index 0000000..d2ad642 --- /dev/null +++ b/day01/src/com/inmind/s_test_11/chatroom/userinfo.txt @@ -0,0 +1,3 @@ +zhangsan=123 +lisi=1234 +wangwu=12345 \ No newline at end of file diff --git a/day01/src/com/inmind/s_test_11/chatroom1/ChatClient.java b/day01/src/com/inmind/s_test_11/chatroom1/ChatClient.java new file mode 100644 index 0000000..d671877 --- /dev/null +++ b/day01/src/com/inmind/s_test_11/chatroom1/ChatClient.java @@ -0,0 +1,101 @@ +package com.inmind.s_test_11.chatroom1; + +import java.io.*; +import java.net.*; + +public class ChatClient { + private String serverAddress; // 服务器地址 + private int serverPort; // 服务器端口 + private String username; // 客户端用户名 + + // 构造方法,初始化服务器地址、端口和用户名 + public ChatClient(String serverAddress, int serverPort, String username) { + this.serverAddress = serverAddress; + this.serverPort = serverPort; + this.username = username; + } + + // 启动客户端 + public void start() { + try (Socket socket = new Socket(serverAddress, serverPort)) { + // 初始化输入流,用于读取服务器发送的消息 + BufferedReader in = new BufferedReader( + new InputStreamReader(socket.getInputStream())); + // 初始化输出流,用于向服务器发送消息,autoFlush设为true + PrintWriter out = new PrintWriter( + socket.getOutputStream(), true); + + // 发送用户名到服务器 + out.println(username); + + // 启动接收消息的线程 + new Thread(new ReceiveHandler(in)).start(); + + // 读取控制台输入的流 + BufferedReader consoleIn = new BufferedReader( + new InputStreamReader(System.in)); + + String input; + // 循环读取控制台输入并发送给服务器 + while ((input = consoleIn.readLine()) != null) { + out.println(input); + + // 如果输入"exit",则退出聊天 + if (input.equalsIgnoreCase("exit")) { + break; + } + } + } catch (IOException e) { + System.err.println("客户端错误: " + e.getMessage()); + } + } + + // 接收消息的线程类,负责读取服务器发送的消息 + private class ReceiveHandler implements Runnable { + private BufferedReader in; // 从服务器读取消息的输入流 + + public ReceiveHandler(BufferedReader in) { + this.in = in; + } + + public void run() { + try { + String message; + // 循环读取服务器发送的消息并打印到控制台 + while ((message = in.readLine()) != null) { + System.out.println(message); + } + } catch (IOException e) { + System.err.println("接收消息错误: " + e.getMessage()); + } + } + } + + // 客户端主方法 + public static void main(String[] args) { + // 默认连接本地服务器 + String serverAddress = "localhost"; + int serverPort = 12345; + + // 获取用户输入的用户名 + BufferedReader consoleIn = new BufferedReader( + new InputStreamReader(System.in)); + System.out.print("请输入您的用户名: "); + + try { + String username = consoleIn.readLine(); + // 如果用户未输入用户名,使用默认匿名用户 + if (username == null || username.trim().isEmpty()) { + username = "匿名用户"; + } + + System.out.println("连接到服务器..."); + // 创建并启动客户端 + ChatClient client = new ChatClient(serverAddress, serverPort, username); + System.out.println("连接成功!输入消息开始聊天,输入exit退出。"); + client.start(); + } catch (IOException e) { + System.err.println("无法获取用户名: " + e.getMessage()); + } + } +} diff --git a/day01/src/com/inmind/s_test_11/chatroom1/ChatServer.java b/day01/src/com/inmind/s_test_11/chatroom1/ChatServer.java new file mode 100644 index 0000000..8755070 --- /dev/null +++ b/day01/src/com/inmind/s_test_11/chatroom1/ChatServer.java @@ -0,0 +1,111 @@ +package com.inmind.s_test_11.chatroom1; + +import java.io.*; +import java.net.*; +import java.util.*; +import java.io.*; +import java.net.*; +import java.util.*; + +public class ChatServer { + // 服务器监听的端口号 + private static final int PORT = 12345; + // 存储所有客户端输出流的集合,用于广播消息 + private static Set clientWriters = new HashSet<>(); + + public static void main(String[] args) { + System.out.println("多人聊天服务器启动,监听端口: " + PORT); + + try (ServerSocket serverSocket = new ServerSocket(PORT)) { + // 循环接受客户端连接 + while (true) { + // 阻塞等待客户端连接 + Socket clientSocket = serverSocket.accept(); + System.out.println("新客户端连接: " + clientSocket); + + // 创建PrintWriter用于向客户端发送消息 + PrintWriter out = new PrintWriter(clientSocket.getOutputStream(), true); + + // 将新客户端的输出流添加到集合中,使用同步块确保线程安全 + synchronized (clientWriters) { + clientWriters.add(out); + } + + // 为每个客户端创建并启动一个新的处理线程 + new Thread(new ClientHandler(clientSocket, out)).start(); + } + } catch (IOException e) { + System.err.println("服务器错误: " + e.getMessage()); + } + } + + // 客户端处理线程类,负责接收客户端消息并广播 + private static class ClientHandler implements Runnable { + private Socket clientSocket; // 客户端Socket + private PrintWriter out; // 向客户端输出的流 + private String username; // 客户端用户名 + + public ClientHandler(Socket socket, PrintWriter out) { + this.clientSocket = socket; + this.out = out; + } + + public void run() { + try { + // 读取客户端发送的数据 + BufferedReader in = new BufferedReader( + new InputStreamReader(clientSocket.getInputStream())); + + // 读取客户端发送的用户名 + username = in.readLine(); + System.out.println("用户 " + username + " 加入聊天"); + + // 广播新用户加入的消息 + broadcast(username + " 加入了聊天!"); + + // 循环读取客户端发送的消息 + String input; + while ((input = in.readLine()) != null) { + // 如果用户输入exit,退出循环 + if (input.equalsIgnoreCase("exit")) { + break; + } + + // 广播用户发送的消息 + broadcast(username + ": " + input); + } + + // 用户退出时的处理 + System.out.println("用户 " + username + " 离开聊天"); + broadcast(username + " 离开了聊天!"); + + } catch (IOException e) { + System.err.println("与客户端通信错误: " + e.getMessage()); + } finally { + // 清理资源 + if (out != null) { + // 从客户端集合中移除当前客户端的输出流 + synchronized (clientWriters) { + clientWriters.remove(out); + } + } + try { + // 关闭客户端连接 + clientSocket.close(); + } catch (IOException e) { + System.err.println("关闭客户端连接错误: " + e.getMessage()); + } + } + } + + // 广播消息给所有连接的客户端 + private void broadcast(String message) { + // 同步遍历客户端输出流集合,确保线程安全 + synchronized (clientWriters) { + for (PrintWriter writer : clientWriters) { + writer.println(message); + } + } + } + } +} diff --git a/day01/src/com/inmind/s_test_12/JunitDemo.java b/day01/src/com/inmind/s_test_12/JunitDemo.java new file mode 100644 index 0000000..667ad10 --- /dev/null +++ b/day01/src/com/inmind/s_test_12/JunitDemo.java @@ -0,0 +1,23 @@ +package com.inmind.s_test_12; + +//import org.junit.Test; + +public class JunitDemo { + + +// @Test + public void method1() throws Exception { + int i = 1/1; + + Class clazz = Class.forName("com.itheima.reflect_02.Student"); + //clazz.newInstance():底层调用指定类的无参构造方式 + Object o = clazz.newInstance(); + System.out.println(o); + } + +// @Test + public void method2(){ + int[] arr = {1,2,3 }; + System.out.println(arr); + } +} diff --git a/day01/src/com/inmind/s_test_12/ValidationDemo.java b/day01/src/com/inmind/s_test_12/ValidationDemo.java new file mode 100644 index 0000000..f5ad474 --- /dev/null +++ b/day01/src/com/inmind/s_test_12/ValidationDemo.java @@ -0,0 +1,225 @@ +package com.inmind.s_test_12; + +import java.lang.annotation.*; +import java.lang.reflect.Field; +import java.util.ArrayList; +import java.util.List; + +/* +业务说明 +这个案例实现了一个通用对象验证框架,核心业务是对 Java 对象的字段进行自动化验证,适用于需要数据校验的场景(如表单提交、接口参数校验等)。 +业务流程 +定义验证规则:通过自定义注解(@NotNull、@Range、@Email)标记需要验证的字段,并设置验证条件(如非空、数值范围、邮箱格式)。 +标记待验证类:在需要验证的类上添加@Validatable注解,声明该类需要进行字段验证。 +执行验证:调用Validator.validate()方法,传入待验证对象,框架会通过反射自动检查所有字段的注解并执行验证逻辑。 +返回验证结果:验证结果包含 “是否通过” 和具体错误信息,方便后续处理(如提示用户修正数据)。 + */ + + +// 枚举:定义验证错误的类型,用于分类错误信息 +enum ValidationErrorType { + NOT_NULL, // 非空错误:字段值为null时触发 + MIN_VALUE, // 最小值错误:数值小于允许的最小值时触发 + MAX_VALUE, // 最大值错误:数值大于允许的最大值时触发 + INVALID_EMAIL // 邮箱格式错误:邮箱地址格式不正确时触发 +} + +// 枚举:定义验证器的类型,用于标识不同的验证规则 +enum ValidatorType { + NOT_NULL, // 非空验证器 + RANGE, // 范围验证器 + EMAIL // 邮箱验证器 +} + +// 注解:类级注解,标记该类需要进行字段验证 +@Target(ElementType.TYPE) // 注解适用范围:类、接口等 +@Retention(RetentionPolicy.RUNTIME) // 注解保留策略:运行时可通过反射获取 +@interface Validatable { +} + +// 注解:字段级注解,标记字段不允许为null +@Target(ElementType.FIELD) // 注解适用范围:成员变量 +@Retention(RetentionPolicy.RUNTIME) // 运行时可访问 +@interface NotNull { + String message() default "字段不能为null"; // 错误提示信息,有默认值 +} + +// 注解:字段级注解,标记字段值需要在指定范围内(适用于数值类型) +@Target(ElementType.FIELD) +@Retention(RetentionPolicy.RUNTIME) +@interface Range { + int min() default 0; // 最小值,默认0 + int max() default Integer.MAX_VALUE; // 最大值,默认整数最大值 + String message() default "字段值超出范围"; // 错误提示信息 +} + +// 注解:字段级注解,标记字段需要验证邮箱格式 +@Target(ElementType.FIELD) +@Retention(RetentionPolicy.RUNTIME) +@interface Email { + String message() default "邮箱格式不正确"; // 错误提示信息 +} + +// 验证结果类:封装验证的结果信息 +class ValidationResult { + private boolean valid; // 验证是否通过 + private List errorMessages = new ArrayList<>(); // 错误信息列表 + + // 获取验证是否通过的状态 + public boolean isValid() { + return valid; + } + + // 设置验证状态 + public void setValid(boolean valid) { + this.valid = valid; + } + + // 获取错误信息列表 + public List getErrorMessages() { + return errorMessages; + } + + // 添加错误信息 + public void addErrorMessage(String message) { + errorMessages.add(message); + } +} + +// 验证器工具类:核心类,使用反射执行验证逻辑 +class Validator { + // 验证对象的公共方法,返回验证结果 + public static ValidationResult validate(Object obj) { + ValidationResult result = new ValidationResult(); + result.setValid(true); // 默认验证通过 + + // 检查对象所属的类是否标记了@Validatable注解,未标记则直接返回 + if (!obj.getClass().isAnnotationPresent(Validatable.class)) { + return result; + } + + try { + // 通过反射获取类的所有字段(包括私有字段) + Field[] fields = obj.getClass().getDeclaredFields(); + + // 遍历每个字段进行验证 + for (Field field : fields) { + // 设置私有字段可访问(否则无法获取值) + field.setAccessible(true); + String fieldName = field.getName(); // 获取字段名 + Object value = field.get(obj); // 获取字段的值 + + // 验证@NotNull注解:如果字段标记了该注解且值为null,则添加错误 + if (field.isAnnotationPresent(NotNull.class) && value == null) { + NotNull annotation = field.getAnnotation(NotNull.class); // 获取注解实例 + result.addErrorMessage(fieldName + ": " + annotation.message()); // 添加错误信息 + result.setValid(false); // 标记验证失败 + } + + // 验证@Range注解:仅对数值类型且值不为null的字段生效 + if (field.isAnnotationPresent(Range.class) && value != null) { + // 检查字段值是否为数字类型 + if (value instanceof Number) { + Range annotation = field.getAnnotation(Range.class); // 获取注解实例 + Number number = (Number) value; // 转换为数字类型 + + // 检查是否小于最小值 + if (number.intValue() < annotation.min()) { + result.addErrorMessage(fieldName + ": " + annotation.message() + + "(最小值: " + annotation.min() + ")"); + result.setValid(false); + } + + // 检查是否大于最大值 + if (number.intValue() > annotation.max()) { + result.addErrorMessage(fieldName + ": " + annotation.message() + + "(最大值: " + annotation.max() + ")"); + result.setValid(false); + } + } + } + + // 验证@Email注解:仅对字符串类型且值不为null的字段生效 + if (field.isAnnotationPresent(Email.class) && value != null) { + // 检查字段值是否为字符串类型 + if (value instanceof String) { + Email annotation = field.getAnnotation(Email.class); // 获取注解实例 + String email = (String) value; // 转换为字符串 + + // 简单验证邮箱格式(包含@符号) + if (!email.contains("@")) { + result.addErrorMessage(fieldName + ": " + annotation.message()); + result.setValid(false); + } + } + } + } + } catch (IllegalAccessException e) { + // 处理反射访问异常 + e.printStackTrace(); + result.setValid(false); + result.addErrorMessage("验证过程中发生错误: " + e.getMessage()); + } + + return result; + } +} + +// 示例实体类:用户信息类,标记了@Validatable表示需要验证 +@Validatable +class User { + @NotNull(message = "用户名不能为空") // 用户名不允许为null + private String username; + + @Range(min = 18, max = 120, message = "年龄必须在18到120之间") // 年龄范围限制 + private int age; + + @Email(message = "请输入有效的邮箱地址") // 邮箱格式验证 + private String email; + + // 构造方法:初始化用户信息 + public User(String username, int age, String email) { + this.username = username; + this.age = age; + this.email = email; + } + + // getter和setter方法(用于访问和修改字段值) + public String getUsername() { return username; } + public void setUsername(String username) { this.username = username; } + public int getAge() { return age; } + public void setAge(int age) { this.age = age; } + public String getEmail() { return email; } + public void setEmail(String email) { this.email = email; } +} + +// 主类:程序入口,演示验证功能 +public class ValidationDemo { + public static void main(String[] args) { + // 创建两个测试用户对象 + User validUser = new User("张三", 25, "zhangsan@example.com"); // 符合所有验证规则 + User invalidUser = new User(null, 15, "invalid-email"); // 不符合验证规则 + + // 验证有效用户 + System.out.println("验证有效用户:"); + ValidationResult validResult = Validator.validate(validUser); + printValidationResult(validResult); + + // 验证无效用户 + System.out.println("\n验证无效用户:"); + ValidationResult invalidResult = Validator.validate(invalidUser); + printValidationResult(invalidResult); + } + + // 打印验证结果的工具方法 + private static void printValidationResult(ValidationResult result) { + if (result.isValid()) { + System.out.println("验证通过!"); + } else { + System.out.println("验证失败,错误信息:"); + for (String message : result.getErrorMessages()) { + System.out.println("- " + message); + } + } + } +} diff --git a/day01/src/com/inmind/s_test_12_2/ValidationDemo1.java b/day01/src/com/inmind/s_test_12_2/ValidationDemo1.java new file mode 100644 index 0000000..bca7623 --- /dev/null +++ b/day01/src/com/inmind/s_test_12_2/ValidationDemo1.java @@ -0,0 +1,300 @@ +package com.inmind.s_test_12_2; + +import java.lang.annotation.*; +import java.lang.reflect.Field; +import java.util.ArrayList; +import java.util.List; + + +/* +业务说明 +这个案例实现了一个通用对象验证框架,核心业务是对 Java 对象的字段进行自动化验证,适用于需要数据校验的场景(如表单提交、接口参数校验等)。 +业务流程 +定义验证规则:通过自定义注解(@NotNull、@Range、@Email)标记需要验证的字段,并设置验证条件(如非空、数值范围、邮箱格式)。 +标记待验证类:在需要验证的类上添加@Validatable注解,声明该类需要进行字段验证。 +执行验证:调用Validator.validate()方法,传入待验证对象,框架会通过反射自动检查所有字段的注解并执行验证逻辑。 +返回验证结果:验证结果包含 “是否通过” 和具体错误信息,方便后续处理(如提示用户修正数据)。 +错误类型:使用枚举定义错误类型 + */ + + +// 枚举:定义验证错误的类型,用于分类错误信息 +enum ValidationErrorType { + NOT_NULL, // 非空错误:字段值为null时触发 + MIN_VALUE, // 最小值错误:数值小于允许的最小值时触发 + MAX_VALUE, // 最大值错误:数值大于允许的最大值时触发 + INVALID_EMAIL // 邮箱格式错误:邮箱地址格式不正确时触发 +} + +// 枚举:定义验证器的类型,用于标识不同的验证规则 +enum ValidatorType { + NOT_NULL, // 非空验证器 + RANGE, // 范围验证器 + EMAIL // 邮箱验证器 +} + +// 验证错误信息类:包含错误类型和错误描述 +class ValidationError { + private ValidationErrorType errorType; // 错误类型 + private String message; // 错误描述 + + public ValidationError(ValidationErrorType errorType, String message) { + this.errorType = errorType; + this.message = message; + } + + public ValidationErrorType getErrorType() { + return errorType; + } + + public String getMessage() { + return message; + } + + @Override + public String toString() { + return "[" + errorType + "] " + message; + } +} + +// 注解:类级注解,标记该类需要进行字段验证 +@Target(ElementType.TYPE) // 注解适用范围:类、接口等 +@Retention(RetentionPolicy.RUNTIME) // 注解保留策略:运行时可通过反射获取 +@interface Validatable { +} + +// 注解:字段级注解,标记字段不允许为null +@Target(ElementType.FIELD) // 注解适用范围:成员变量 +@Retention(RetentionPolicy.RUNTIME) // 运行时可访问 +@interface NotNull { + String message() default "字段不能为null"; // 错误提示信息,有默认值 + ValidatorType type() default ValidatorType.NOT_NULL; // 关联的验证器类型 +} + +// 注解:字段级注解,标记字段值需要在指定范围内(适用于数值类型) +@Target(ElementType.FIELD) +@Retention(RetentionPolicy.RUNTIME) +@interface Range { + int min() default 0; // 最小值,默认0 + int max() default Integer.MAX_VALUE; // 最大值,默认整数最大值 + String message() default "字段值超出范围"; // 错误提示信息 + ValidatorType type() default ValidatorType.RANGE; // 关联的验证器类型 +} + +// 注解:字段级注解,标记字段需要验证邮箱格式 +@Target(ElementType.FIELD) +@Retention(RetentionPolicy.RUNTIME) +@interface Email { + String message() default "邮箱格式不正确"; // 错误提示信息 + ValidatorType type() default ValidatorType.EMAIL; // 关联的验证器类型 +} + +// 验证结果类:封装验证的结果信息 +class ValidationResult { + private boolean valid; // 验证是否通过 + private List errors = new ArrayList<>(); // 错误列表 + + // 获取验证是否通过的状态 + public boolean isValid() { + return valid; + } + + // 设置验证状态 + public void setValid(boolean valid) { + this.valid = valid; + } + + // 获取错误列表 + public List getErrors() { + return errors; + } + + // 添加错误信息 + public void addError(ValidationError error) { + errors.add(error); + } + + // 根据错误类型筛选错误 + public List getErrorsByType(ValidationErrorType type) { + List result = new ArrayList<>(); + for (ValidationError error : errors) { + if (error.getErrorType() == type) { + result.add(error); + } + } + return result; + } +} + +// 验证器工具类:核心类,使用反射执行验证逻辑 +class Validator { + // 验证对象的公共方法,返回验证结果 + public static ValidationResult validate(Object obj) { + ValidationResult result = new ValidationResult(); + result.setValid(true); // 默认验证通过 + + // 检查对象所属的类是否标记了@Validatable注解,未标记则直接返回 + if (!obj.getClass().isAnnotationPresent(Validatable.class)) { + return result; + } + + try { + // 通过反射获取类的所有字段(包括私有字段) + Field[] fields = obj.getClass().getDeclaredFields(); + + // 遍历每个字段进行验证 + for (Field field : fields) { + // 设置私有字段可访问(否则无法获取值) + field.setAccessible(true); + String fieldName = field.getName(); // 获取字段名 + Object value = field.get(obj); // 获取字段的值 + + // 验证@NotNull注解:如果字段标记了该注解且值为null,则添加错误 + if (field.isAnnotationPresent(NotNull.class)) { + // 演示ValidatorType的使用:获取注解关联的验证器类型 + ValidatorType validatorType = field.getAnnotation(NotNull.class).type(); + System.out.println("对字段[" + fieldName + "]使用" + validatorType + "进行验证"); + + if (value == null) { + NotNull annotation = field.getAnnotation(NotNull.class); + // 使用ValidationErrorType创建错误信息 + result.addError(new ValidationError( + ValidationErrorType.NOT_NULL, + fieldName + ": " + annotation.message() + )); + result.setValid(false); + } + } + + // 验证@Range注解:仅对数值类型且值不为null的字段生效 + if (field.isAnnotationPresent(Range.class) && value != null) { + // 演示ValidatorType的使用 + ValidatorType validatorType = field.getAnnotation(Range.class).type(); + System.out.println("对字段[" + fieldName + "]使用" + validatorType + "进行验证"); + + // 检查字段值是否为数字类型 + if (value instanceof Number) { + Range annotation = field.getAnnotation(Range.class); + Number number = (Number) value; + + // 检查是否小于最小值 + if (number.intValue() < annotation.min()) { + result.addError(new ValidationError( + ValidationErrorType.MIN_VALUE, + fieldName + ": " + annotation.message() + "(最小值: " + annotation.min() + ")" + )); + result.setValid(false); + } + + // 检查是否大于最大值 + if (number.intValue() > annotation.max()) { + result.addError(new ValidationError( + ValidationErrorType.MAX_VALUE, + fieldName + ": " + annotation.message() + "(最大值: " + annotation.max() + ")" + )); + result.setValid(false); + } + } + } + + // 验证@Email注解:仅对字符串类型且值不为null的字段生效 + if (field.isAnnotationPresent(Email.class) && value != null) { + // 演示ValidatorType的使用 + ValidatorType validatorType = field.getAnnotation(Email.class).type(); + System.out.println("对字段[" + fieldName + "]使用" + validatorType + "进行验证"); + + // 检查字段值是否为字符串类型 + if (value instanceof String) { + Email annotation = field.getAnnotation(Email.class); + String email = (String) value; + + // 简单验证邮箱格式(包含@符号) + if (!email.contains("@")) { + result.addError(new ValidationError( + ValidationErrorType.INVALID_EMAIL, + fieldName + ": " + annotation.message() + )); + result.setValid(false); + } + } + } + } + } catch (IllegalAccessException e) { + // 处理反射访问异常 + e.printStackTrace(); + result.setValid(false); + result.addError(new ValidationError( + null, "验证过程中发生错误: " + e.getMessage() + )); + } + + return result; + } +} + +// 示例实体类:用户信息类,标记了@Validatable表示需要验证 +@Validatable +class User { + @NotNull(message = "用户名不能为空") // 用户名不允许为null + private String username; + + @Range(min = 18, max = 120, message = "年龄必须在18到120之间") // 年龄范围限制 + private int age; + + @Email(message = "请输入有效的邮箱地址") // 邮箱格式验证 + private String email; + + // 构造方法:初始化用户信息 + public User(String username, int age, String email) { + this.username = username; + this.age = age; + this.email = email; + } + + // getter和setter方法 + public String getUsername() { return username; } + public void setUsername(String username) { this.username = username; } + public int getAge() { return age; } + public void setAge(int age) { this.age = age; } + public String getEmail() { return email; } + public void setEmail(String email) { this.email = email; } +} + +// 主类:程序入口,演示验证功能 +public class ValidationDemo1 { + public static void main(String[] args) { + // 创建两个测试用户对象 + User validUser = new User("张三", 25, "zhangsan@example.com"); // 符合所有验证规则 + User invalidUser = new User(null, 15, "invalid-email"); // 不符合验证规则 + + // 验证有效用户 + System.out.println("=== 验证有效用户 ==="); + ValidationResult validResult = Validator.validate(validUser); + printValidationResult(validResult); + + // 验证无效用户 + System.out.println("\n=== 验证无效用户 ==="); + ValidationResult invalidResult = Validator.validate(invalidUser); + printValidationResult(invalidResult); + + // 演示根据错误类型筛选错误 + System.out.println("\n=== 按错误类型筛选结果 ==="); + List notNullErrors = invalidResult.getErrorsByType(ValidationErrorType.NOT_NULL); + System.out.println("非空错误数量: " + notNullErrors.size()); + for (ValidationError error : notNullErrors) { + System.out.println(error); + } + } + + // 打印验证结果的工具方法 + private static void printValidationResult(ValidationResult result) { + if (result.isValid()) { + System.out.println("验证通过!"); + } else { + System.out.println("验证失败,错误信息:"); + for (ValidationError error : result.getErrors()) { + System.out.println("- " + error); + } + } + } +} diff --git a/day01/src/com/inmind/s_test_13/Log.java b/day01/src/com/inmind/s_test_13/Log.java new file mode 100644 index 0000000..6a70a72 --- /dev/null +++ b/day01/src/com/inmind/s_test_13/Log.java @@ -0,0 +1,42 @@ +package com.inmind.s_test_13; + + +import java.io.Serializable; + +public class Log implements Serializable { + + private static final long serialVersionUID = 2330914830532482231L; + private long timestamp; + private String level; + private String module; + private String content; + + public Log(long timestamp, String level, String module, String content) { + this.timestamp = timestamp; + this.level = level; + this.module = module; + this.content = content; + } + + // getter方法 + public long getTimestamp() { + return timestamp; + } + + public String getLevel() { + return level; + } + + public String getModule() { + return module; + } + + public String getContent() { + return content; + } + + @Override + public String toString() { + return "[" + timestamp + "] " + level + " " + module + ": " + content; + } +} diff --git a/day01/src/com/inmind/s_test_13/LogAnalyzer.java b/day01/src/com/inmind/s_test_13/LogAnalyzer.java new file mode 100644 index 0000000..dc02c9f --- /dev/null +++ b/day01/src/com/inmind/s_test_13/LogAnalyzer.java @@ -0,0 +1,235 @@ +package com.inmind.s_test_13; + +import java.io.*; +import java.net.ConnectException; +import java.net.Socket; +import java.util.*; +import java.util.stream.Collectors; + +/** + * 日志分析器主类(不使用Stream分组统计,改用Map手动统计) + */ +public class LogAnalyzer { + // 日志文件目录 + private static final String LOG_DIR = "D:\\io_test"; + // 服务器地址和端口 + private static final String SERVER_HOST = "localhost"; + private static final int SERVER_PORT = 8080; + + // 日志列表(非线程安全全集合,通过synchronized保证安全) + private List logs = new ArrayList<>(); + + public static void main(String[] args) { + LogAnalyzer analyzer = new LogAnalyzer(); + try { + // 1. 多线程读取和解析日志文件 + analyzer.readAndParseLogs(); + + // 2. 分析统计日志(使用Map手动统计) + Map levelCountMap = analyzer.countByLevel(); + Map errorModuleMap = analyzer.countErrorByModule(); + List earliestLogs = analyzer.getEarliestLogs(3); + + // 3. 上报统计结果 + analyzer.reportToServer(levelCountMap, errorModuleMap, earliestLogs); + + System.out.println("日志分析和上报完成"); + } catch (Exception e) { + System.err.println("日志分析过程中发生错误: " + e.getMessage()); + e.printStackTrace(); + } + } + + /** + * 多线程读取和解析日志文件(使用普通线程) + */ + public void readAndParseLogs() throws IOException, InterruptedException { + // 检查日志目录是否存在 + File logDir = new File(LOG_DIR); + if (!logDir.exists() || !logDir.isDirectory()) { + throw new FileNotFoundException("日志目录不存在: " + LOG_DIR); + } + + // 获取所有.log文件 + File[] logFiles = logDir.listFiles((dir, name) -> name.endsWith(".log")); + if (logFiles == null || logFiles.length == 0) { + System.out.println("没有找到日志文件"); + return; + } + + System.out.println("找到 " + logFiles.length + " 个日志文件,开始解析..."); + + // 创建线程列表 + List threads = new ArrayList<>(); + + // 为每个文件创建一个线程 + for (File file : logFiles) { + Thread thread = new Thread(() -> parseLogFile(file)); + threads.add(thread); + thread.start(); + } + + // 等待所有线程完成 + for (Thread thread : threads) { + thread.join(); + } + + System.out.println("日志解析完成,共解析 " + logs.size() + " 条日志"); + } + + /** + * 解析单个日志文件 + */ + private void parseLogFile(File file) { + try (BufferedReader reader = new BufferedReader(new FileReader(file))) { + String line; + int lineNumber = 0; + + while ((line = reader.readLine()) != null) { + lineNumber++; + try { + Log log = parseLogLine(line); + if (log != null) { + // 使用synchronized保证线程安全 + synchronized (this) { + logs.add(log); + } + } + } catch (Exception e) { + System.err.println("解析文件 " + file.getName() + " 的第 " + lineNumber + " 行失败: " + e.getMessage()); + System.err.println("错误行内容: " + line); + } + } + + System.out.println("解析完成: " + file.getName() + ",共 " + (lineNumber - 1) + " 行"); + } catch (IOException e) { + System.err.println("读取日志文件 " + file.getName() + " 失败: " + e.getMessage()); + } + } + + /** + * 解析单条日志(使用逗号分隔格式) + * 日志格式:时间戳,级别,模块,内容 + * 例如:1696123456789,ERROR,Payment,支付失败,订单号:ORDER123 + */ + private Log parseLogLine(String line) { + // 去除首尾可能存在的空格 + line = line.trim(); + + // 按逗号分割,限制分割次数为4(确保内容部分的逗号不被分割) + String[] parts = line.split(",", 4); + + // 验证格式是否正确 + if (parts.length != 4) { + throw new IllegalArgumentException("日志格式错误,需要4个字段,实际得到" + parts.length + "个"); + } + + // 提取各个字段 + String timestampStr = parts[0]; + String level = parts[1]; + String module = parts[2]; + String content = parts[3]; + + // 验证时间戳格式 + try { + long timestamp = Long.parseLong(timestampStr); + return new Log(timestamp, level, module, content); + } catch (NumberFormatException e) { + throw new IllegalArgumentException("时间戳格式错误: " + timestampStr); + } + } + + /** + * 按级别统计日志数量(使用Map手动统计) + */ + public Map countByLevel() { + Map levelCountMap = new HashMap<>(); + + // 同步读取日志列表 + synchronized (this) { + for (Log log : logs) { + String level = log.getLevel(); + // 存在则加1,不存在则设为1 + if (levelCountMap.containsKey(level)) { + levelCountMap.put(level, levelCountMap.get(level) + 1); + } else { + levelCountMap.put(level, 1); + } + } + } + + return levelCountMap; + } + + /** + * 按模块统计错误日志数量(使用Map手动统计) + */ + public Map countErrorByModule() { + Map errorModuleMap = new HashMap<>(); + + // 同步读取日志列表 + synchronized (this) { + for (Log log : logs) { + // 只统计ERROR级别的日志 + if ("ERROR".equals(log.getLevel())) { + String module = log.getModule(); + // 存在则加1,不存在则设为1 + if (errorModuleMap.containsKey(module)) { + errorModuleMap.put(module, errorModuleMap.get(module) + 1); + } else { + errorModuleMap.put(module, 1); + } + } + } + } + + return errorModuleMap; + } + + /** + * 获取最早的N条日志(使用普通排序) + */ + public List getEarliestLogs(int n) { + // 先创建副本再排序,避免影响原始列表 + List sortedLogs; + synchronized (this) { + sortedLogs = new ArrayList<>(logs); + } + + // 手动排序(不使用Stream) + sortedLogs.sort(new Comparator() { + @Override + public int compare(Log log1, Log log2) { + return Long.compare(log1.getTimestamp(), log2.getTimestamp()); + } + }); + + // 取前N条 + + return sortedLogs.stream().limit(n).collect(Collectors.toList()); + } + + /** + * 向服务器上报统计结果 + */ + public void reportToServer(Map levelCountMap, + Map errorModuleMap, + List earliestLogs) throws IOException, ClassNotFoundException { + try (Socket socket = new Socket(SERVER_HOST, SERVER_PORT); + ObjectOutputStream out = new ObjectOutputStream(socket.getOutputStream()); + ObjectInputStream in = new ObjectInputStream(socket.getInputStream())) { + + // 发送统计结果 + out.writeObject(levelCountMap); + out.writeObject(errorModuleMap); + out.writeObject(earliestLogs); + out.flush(); + + // 接收响应 + String response = (String) in.readObject(); + System.out.println("服务器响应: " + response); + } catch (ConnectException e) { + throw new ConnectException("无法连接到服务器 " + SERVER_HOST + ":" + SERVER_PORT + ",请确保服务器已启动"); + } + } +} \ No newline at end of file diff --git a/day01/src/com/inmind/s_test_13/LogServer.java b/day01/src/com/inmind/s_test_13/LogServer.java new file mode 100644 index 0000000..8c727d2 --- /dev/null +++ b/day01/src/com/inmind/s_test_13/LogServer.java @@ -0,0 +1,63 @@ +package com.inmind.s_test_13; + +import java.io.*; +import java.net.ServerSocket; +import java.net.Socket; +import java.util.List; +import java.util.Map; + +/** + * 日志分析服务器,接收客户端上报的统计结果 + */ +public class LogServer { + private static final int PORT = 8080; + + public static void main(String[] args) { + System.out.println("日志分析服务器启动,监听端口: " + PORT); + + try (ServerSocket serverSocket = new ServerSocket(PORT)) { + while (true) { + // 等待客户端连接 + try (Socket clientSocket = serverSocket.accept(); + ObjectInputStream in = new ObjectInputStream(clientSocket.getInputStream()); + ObjectOutputStream out = new ObjectOutputStream(clientSocket.getOutputStream())) { + + System.out.println("客户端连接成功: " + clientSocket.getInetAddress()); + + // 接收统计结果 + Map levelCountMap = (Map) in.readObject(); + Map errorModuleMap = (Map) in.readObject(); + List earliestLogs = (List) in.readObject(); + + // 打印统计结果 + System.out.println("\n===== 日志统计结果 ====="); + + System.out.println("\n1. 按级别统计:"); + for (Map.Entry entry : levelCountMap.entrySet()) { + System.out.println(entry.getKey() + ": " + entry.getValue() + "条"); + } + + System.out.println("\n2. 按模块错误统计:"); + for (Map.Entry entry : errorModuleMap.entrySet()) { + System.out.println(entry.getKey() + ": " + entry.getValue() + "条错误"); + } + + System.out.println("\n3. 最早的3条日志:"); + for (Log log : earliestLogs) { + System.out.println(log); + } + + // 发送响应 + out.writeObject("上报成功"); + out.flush(); + } catch (Exception e) { + System.err.println("处理客户端请求出错: " + e.getMessage()); + e.printStackTrace(); + } + } + } catch (IOException e) { + System.err.println("服务器启动失败: " + e.getMessage()); + e.printStackTrace(); + } + } +} \ No newline at end of file diff --git a/day01/src/com/inmind/s_test_13/proxy/CaiXuKun.java b/day01/src/com/inmind/s_test_13/proxy/CaiXuKun.java new file mode 100644 index 0000000..ebe244e --- /dev/null +++ b/day01/src/com/inmind/s_test_13/proxy/CaiXuKun.java @@ -0,0 +1,19 @@ +package com.inmind.s_test_13.proxy; + +//歌手类 +public class CaiXuKun implements Singer { + @Override + public void sing(int money) { + System.out.println("蔡徐坤收到了"+money+"钱,唱了鸡你太美"); + } + + @Override + public void dance(int money) { + System.out.println("蔡徐坤收到了"+money+"钱,跳了篮球舞"); + } + + @Override + public void eat() { + System.out.println("蔡徐坤吃了大盘鸡"); + } +} \ No newline at end of file diff --git a/day01/src/com/inmind/s_test_13/proxy/ProxyDemo.java b/day01/src/com/inmind/s_test_13/proxy/ProxyDemo.java new file mode 100644 index 0000000..f58d5e3 --- /dev/null +++ b/day01/src/com/inmind/s_test_13/proxy/ProxyDemo.java @@ -0,0 +1,70 @@ +package com.inmind.s_test_13.proxy; + +import java.lang.reflect.InvocationHandler; +import java.lang.reflect.Method; +import java.lang.reflect.Proxy; + +public class ProxyDemo { + public static void main(String[] args) { + CaiXuKun caiXuKun = new CaiXuKun(); + + //动态地创建出代理对象,谈唱跳功能的价格 + //参数一:类加载器对象 + ClassLoader loader = caiXuKun.getClass().getClassLoader(); + //参数二:代理对象要与被代理对象拥有相同的功能,Singer + Class[] interfaces = caiXuKun.getClass().getInterfaces(); + //参数三:处理器对象,用来处理代理对象中的业务逻辑 + InvocationHandler h = new InvocationHandler() { + /* + 注意:动态代理对象singerProxy调用任意的方法,都会引起,invoke方法执行一次 + invoke方法的三个参数: + 参数一proxy:动态代理对象singerProxy(不要使用,它引起递归,导致栈内存溢出错误) + 参数二method:反射中Method类,就是当前动态代理调用的方法sing,dance... + 参数三args:当前动态代理调用的方法传入的实参 + */ + @Override + public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { + //System.out.println("inovke方法执行了"); + /* + 动态代理增强的代码 + 1.如果是sing,那么要100万才让蔡徐坤唱 + 2.如果是dance,那么要200万才让蔡徐坤跳 + */ + // if (method.getName().equals("sing")) { + if ("sing".equals(method.getName())) { + int money = (int) args[0]; + if (money > 100) { + // caiXuKun.sing(money); + return method.invoke(caiXuKun, args); + } else { + System.out.println("钱不够,一边玩去"); + } + return null; + } + + if ("dance".equals(method.getName())) { + int money = (int) args[0]; + if (money > 200) { + // caiXuKun.dance(money); + return method.invoke(caiXuKun, args); + } else { + System.out.println("钱不够,一边玩去"); + } + return null; + } + + //注意:我们此时针对sing,dance,进行了拦截,但是它还有其他的功能,如果不要拦截,那就得执行它原本的功能 + + return method.invoke(caiXuKun,args); + } + }; + /* + 创建了一个动态代理对象 + 注意:为了调用要拦截的sing,dance,此时的o对象必须强转成对应singer接口类型 + */ + Singer singerProxy = (Singer) Proxy.newProxyInstance(loader, interfaces, h); + singerProxy.sing(150); + singerProxy.dance(150); + singerProxy.eat(); + } +} diff --git a/day01/src/com/inmind/s_test_13/proxy/Singer.java b/day01/src/com/inmind/s_test_13/proxy/Singer.java new file mode 100644 index 0000000..db10cae --- /dev/null +++ b/day01/src/com/inmind/s_test_13/proxy/Singer.java @@ -0,0 +1,8 @@ +package com.inmind.s_test_13.proxy; + +//定义出一个歌手的规范,只要拥有该接口的方法,那么对应的类就算是一个歌手类 +public interface Singer { + void sing(int money); + void dance(int money); + void eat(); +} \ No newline at end of file diff --git a/day01/src/com/inmind/test07/Main.java b/day01/src/com/inmind/test07/Main.java new file mode 100644 index 0000000..c5d2ebf --- /dev/null +++ b/day01/src/com/inmind/test07/Main.java @@ -0,0 +1,89 @@ +package com.inmind.test07; + +import java.util.Scanner; + +public class Main { + public static void main(String[] args) { + StudentManager manager = new StudentManager(); + Scanner scanner = new Scanner(System.in); + + while (true) { + System.out.println("===== 学生管理系统 ====="); + System.out.println("1. 添加学生"); + System.out.println("2. 删除学生"); + System.out.println("3. 修改学生信息"); + System.out.println("4. 查找学生"); + System.out.println("5. 显示所有学生"); + System.out.println("6. 退出系统"); + System.out.print("请输入你的选择:"); + + int choice = scanner.nextInt(); + scanner.nextLine(); // 消耗换行符 + + switch (choice) { + case 1: + addStudent(scanner, manager); + break; + case 2: + deleteStudent(scanner, manager); + break; + case 3: + updateStudent(scanner, manager); + break; + case 4: + findStudent(scanner, manager); + break; + case 5: + manager.displayAllStudents(); + break; + case 6: + System.out.println("感谢使用学生管理系统,再见!"); + scanner.close(); + return; + default: + System.out.println("无效的选择,请重新输入!"); + } + } + } + + private static void addStudent(Scanner scanner, StudentManager manager) { + System.out.println("=== 添加学生 ==="); + System.out.print("请输入学生ID:"); + int id = scanner.nextInt(); + scanner.nextLine(); // 消耗换行符 + System.out.print("请输入学生姓名:"); + String name = scanner.nextLine(); + System.out.print("请输入学生年龄:"); + int age = scanner.nextInt(); + scanner.nextLine(); // 消耗换行符 + System.out.print("请输入学生地址:"); + String address = scanner.nextLine(); + + Student student = new Student(id, name, age, address); + manager.addStudent(student); + } + + private static void deleteStudent(Scanner scanner, StudentManager manager) { + System.out.println("=== 删除学生 ==="); + System.out.print("请输入要删除的学生ID:"); + int id = scanner.nextInt(); + scanner.nextLine(); // 消耗换行符 + manager.deleteStudent(id); + } + + private static void updateStudent(Scanner scanner, StudentManager manager) { + System.out.println("=== 修改学生信息 ==="); + System.out.print("请输入要修改的学生ID:"); + int id = scanner.nextInt(); + scanner.nextLine(); // 消耗换行符 + manager.updateStudent(id); + } + + private static void findStudent(Scanner scanner, StudentManager manager) { + System.out.println("=== 查找学生 ==="); + System.out.print("请输入要查找的学生ID:"); + int id = scanner.nextInt(); + scanner.nextLine(); // 消耗换行符 + manager.findStudent(id); + } +} \ No newline at end of file diff --git a/day01/src/com/inmind/test07/RandomTest01.java b/day01/src/com/inmind/test07/RandomTest01.java new file mode 100644 index 0000000..f9bace5 --- /dev/null +++ b/day01/src/com/inmind/test07/RandomTest01.java @@ -0,0 +1,110 @@ +package com.inmind.test07; + +import java.util.Arrays; +import java.util.Random; +import java.util.Scanner; +/* +数组 随机 scanner的抽奖案例 +1.动态定义出参与获奖的人数和姓名 +2.动态定义奖品内容 +3.随机对奖品进行抽奖,并输出对应奖品的获奖者,以及未获奖的名单 + */ +public class RandomTest01 { + + public static void main(String[] args) { + // 创建Scanner对象用于读取用户输入 + Scanner scanner = new Scanner(System.in); + // 创建Random对象用于生成随机数 + Random random = new Random(); + + // 1. 输入参与者信息 + // 提示用户输入参与抽奖的人数 + System.out.print("请输入参与抽奖的人数: "); + // 读取用户输入的人数 + int canjiaYhCount = scanner.nextInt(); + /* + 当使用scanner.nextInt()读取整数后,输入缓冲区中会留下用户按下的换行符(Enter 键)。 + 例如,用户输入5并按 Enter,nextInt()会读取5,但换行符\n仍留在缓冲区中。 + */ + scanner.nextLine(); // 消耗换行符,避免影响后续输入 + + // 创建存储参与者姓名的数组 + String[] canjiaYhArr = new String[canjiaYhCount]; + // 循环读取每个参与者的姓名 + for (int i = 0; i < canjiaYhCount; i++) { + // 提示输入参与者姓名 + System.out.print("请输入第 " + (i + 1) + " 位参与者姓名: "); + // 读取并存储参与者姓名 + canjiaYhArr[i] = scanner.nextLine(); + } + + // 2. 设置奖项 + // 提示用户输入奖项数量 + System.out.print("请输入奖项数量: "); + // 读取用户输入的奖项数量 + int prizeCount = scanner.nextInt(); + // 消耗换行符 + scanner.nextLine(); + // 创建存储奖项名称的数组 + String[] prizeArr = new String[prizeCount]; + // 循环读取每个奖项的名称 + for (int i = 0; i < prizeCount; i++) { + // 提示输入奖项名称 + System.out.print("请输入第 " + (i + 1) + " 个奖项名称: "); + // 读取并存储奖项名称 + prizeArr[i] = scanner.nextLine(); + } + + // 3. 开始抽奖 + System.out.println("=== 开始抽奖 ==="); + // 标记数组,记录每个参与者是否已中奖 + boolean[] isWinnerArr = new boolean[canjiaYhCount]; + // 存储获奖者的数组 + String[] winners = new String[prizeCount]; + + // 循环抽取每个奖项的获得者 + for (int i = 0; i < prizeCount; i++) { + // 如果参与者人数少于奖项数,提前结束抽奖 + if (i >= canjiaYhCount) { + System.out.println("奖项数量超过参与者人数,抽奖结束。"); + break; + } + + //记录获奖者的索引 + int winnerIndex; + // 生成未中奖的随机索(获奖者可能重复获奖,并且要优先获取获奖索引后再判断是否获奖,所以用do-while) + do { + // 生成0到canjiaYhCount-1之间的随机整数 + winnerIndex = random.nextInt(canjiaYhCount); + // 如果该索引的参与者已中奖,则重新生成 + } while (isWinnerArr[winnerIndex]); + + // 标记该参与者已中奖 + isWinnerArr[winnerIndex] = true; + winners[i] = canjiaYhArr[winnerIndex]; // 记录获奖者姓名 + System.out.println("恭喜 " + winners[i] + " 获得 " + prizeArr[i] + "!"); // 输出中奖信息 + } + + // 4. 查看中奖名单 + System.out.println("\n=== 中奖名单 ==="); + // 遍历并输出所有奖项的中奖者 + for (int i = 0; i < Math.min(prizeCount, canjiaYhCount); i++) { + System.out.println(prizeArr[i] + ": " + winners[i]); // 输出奖项和对应的获奖者 + } + + // 5. 查看未中奖者 + System.out.println("\n=== 未中奖者名单 ==="); + // 遍历所有参与者,输出未中奖者 + for (int i = 0; i < canjiaYhCount; i++) { + // 如果该参与者未中奖 + if (!isWinnerArr[i]) { + // 输出未中奖者姓名 + System.out.println(canjiaYhArr[i]); + } + } + + // 关闭Scanner,释放资源 + scanner.close(); + } +} + diff --git a/day01/src/com/inmind/test07/Student.java b/day01/src/com/inmind/test07/Student.java new file mode 100644 index 0000000..5913627 --- /dev/null +++ b/day01/src/com/inmind/test07/Student.java @@ -0,0 +1,71 @@ +package com.inmind.test07; + +public class Student implements Comparable{ + @Override + public int compareTo(Student o) { + return this.id - o.id; + } + + private int id; + private String name; + private int age; + private String address; + + public Student() {} + + public Student(int id, String name, int age, String address) { + this.id = id; + this.name = name; + this.age = age; + this.address = address; + } + + // Getters and setters + public int getId() { + return id; + } + + public void setId(int id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public int getAge() { + return age; + } + + public void setAge(int age) { + this.age = age; + } + + public String getAddress() { + return address; + } + + public void setAddress(String address) { + this.address = address; + } + + public String showMsg() { + return "Student{" + + "id='" + id + '\'' + + ", name='" + name + '\'' + + ", age=" + age + + ", address='" + address + '\'' + + '}'; + } + + @Override + public String toString() { + return "Student{" + + "id=" + id + + '}'; + } +} \ No newline at end of file diff --git a/day01/src/com/inmind/test07/StudentManager.java b/day01/src/com/inmind/test07/StudentManager.java new file mode 100644 index 0000000..e11575d --- /dev/null +++ b/day01/src/com/inmind/test07/StudentManager.java @@ -0,0 +1,122 @@ +package com.inmind.test07; + +import java.util.ArrayList; +import java.util.List; +import java.util.Scanner; + +public class StudentManager { + private List students; + + public StudentManager() { + this.students = new ArrayList<>(); + } + + // 添加学生 + public void addStudent(Student student) { + //判断学号是否存在 + for (int i = 0; i < students.size(); i++) { + Student s = students.get(i); + if(s.getId() == student.getId()) { + System.out.println("该学生已存在!"); + return; + } + } + + students.add(student); + System.out.println("学生添加成功!"); + } + + // 删除学生 + public void deleteStudent(int id) { + Student studentToRemove = null; + for (Student student : students) { + if (student.getId()== (id)) { + studentToRemove = student; + break; + } + } + + if (studentToRemove != null) { + students.remove(studentToRemove); + System.out.println("学生删除成功!"); + } else { + System.out.println("未找到该学生!"); + } + } + + // 修改学生信息 + public void updateStudent(int id) { + Student studentToUpdate = null; + for (Student student : students) { + if (student.getId()== (id)) { + studentToUpdate = student; + break; + } + } + + if (studentToUpdate != null) { + Scanner scanner = new Scanner(System.in); + + System.out.print("请输入新姓名(不修改请直接回车):"); + String name = scanner.nextLine(); + if (!name.isEmpty()) { + studentToUpdate.setName(name); + } + + System.out.print("请输入新年龄(不修改请直接回车):"); + String ageStr = scanner.nextLine(); + if (!ageStr.isEmpty()) { + try { + int age = Integer.parseInt(ageStr); + studentToUpdate.setAge(age); + } catch (NumberFormatException e) { + System.out.println("年龄输入无效,未修改!"); + } + } + + System.out.print("请输入新地址(不修改请直接回车):"); + String address = scanner.nextLine(); + if (!address.isEmpty()) { + studentToUpdate.setAddress(address); + } + + System.out.println("学生信息修改成功!"); + } else { + System.out.println("未找到该学生!"); + } + } + + // 查找学生 + public void findStudent(int id) { + boolean found = false; + for (Student student : students) { + if (student.getId() == (id)) { + System.out.println("找到学生:" + student); + found = true; + break; + } + } + + if (!found) { + System.out.println("未找到该学生!"); + } + } + + // 显示所有学生 + public void displayAllStudents() { + if (students.isEmpty()) { + System.out.println("暂无学生信息!"); + return; + } + + System.out.println("所有学生信息如下:"); + for (Student student : students) { + System.out.println(student.showMsg()); + } + } + + // 获取学生列表 + public List getStudents() { + return students; + } +} \ No newline at end of file diff --git a/day01/src/com/inmind/test07/Test6.java b/day01/src/com/inmind/test07/Test6.java new file mode 100644 index 0000000..58c605c --- /dev/null +++ b/day01/src/com/inmind/test07/Test6.java @@ -0,0 +1,80 @@ +package com.inmind.test07; + +import java.util.ArrayList; +import java.util.Random; + +public class Test6 { + public static void main(String[] args) { + int n = 15; + ArrayList cards = randomCard(n); + + if (cards != null) { + System.out.println("随机"+ n +"张牌:" ); + for (int i = 0; i < cards.size(); i++) { + Card card = cards.get(i); + card.showCard(); + } + }else { + System.out.println(n+"超越范围,无法获取牌" ); + } + + /*System.out.println(); + System.out.println(); + int n2 = 55; + ArrayList cards2 = randomCard(n2); + + if (cards2 != null) { + System.out.println("随机"+ n2 +"张牌:" ); + for (int i = 0; i < cards.size(); i++) { + Card card = cards.get(i); + card.showCard(); + } + }else { + System.out.println("随机"+ n2 +"张牌:\r\n超越范围,无法获取" ); + }*/ + } + public static ArrayList randomCard(int n) { + if (n > 54 || n < 0) + return null; + + ArrayList rList = new ArrayList<>(); + ArrayList cards = allCard(); + + Random r = new Random(); + for (int i = 0; i < n; i++) { + int index = r.nextInt(cards.size()); + Card rCard = cards.remove(index); + rList.add(rCard); + } + return rList; + } + + public static ArrayList allCard() { + ArrayList allList = new ArrayList<>(); + // 花色数组 + String[] hs = {"黑桃", "红桃", "梅花", "方片"}; + // 点数数组 + String[] ds = {"A", "2", "3", "4", "5", "6", "7", "8", "9", "10", "J", "Q", "K"}; + + for (int H = 0; H < hs.length; H++) { + for (int d = 0; d < ds.length; d++) { + Card card = new Card(hs[H], ds[d]); + // 添加到集合 + allList.add(card); + } + } + return allList; + } +} + +class Card { + private String ds; // 点数 + private String hs; // 花色 + public Card(String ds, String hs) { + this.ds = ds; + this.hs = hs; + } + public void showCard() { + System.out.print(ds + hs+" "); + } +} \ No newline at end of file diff --git a/day01/src/com/inmind/test07/Test8.java b/day01/src/com/inmind/test07/Test8.java new file mode 100644 index 0000000..4b8c703 --- /dev/null +++ b/day01/src/com/inmind/test07/Test8.java @@ -0,0 +1,65 @@ +package com.inmind.test07; + +import java.util.ArrayList; +import java.util.Random; +import java.util.Scanner; + +public class Test8 { + public static void main(String[] args) { + ArrayList lotNumList = lotNum(); + System.out.println("乐透号码已经生成,游戏开始:"); + ArrayList inputList = inputNum(); + System.out.println("您输入的号码为:"+inputList); + int count = countNum(inputList , lotNumList); + System.out.println("乐透号码为:"+lotNumList); + System.out.println("猜中了:"+count+"个数字"); + } + + private static int countNum(ArrayList inputList, ArrayList lotNumList) { + int count = 0; + for (int i = 0; i < inputList.size(); i++) { + Integer num = inputList.get(i); + if (lotNumList.contains(num)){ + count++; + } + } + return count ; + } + public static ArrayList inputNum(){ + ArrayList list = new ArrayList<>(); + Scanner sc = new Scanner(System.in); + for (int i = 0; i < 10; i++) { + System.out.println("请输入数字:"); + int num = sc.nextInt(); + + if (num <= 0 || num > 50) { + i--; + System.out.println("输入无效数字,请重新输入"); + continue; + } + + if (!list.contains(num)){ + list.add(num); + }else{ + System.out.println(num+"重复录入数字无效,请重新输入"); + i--; + } + } + return list; + } + + public static ArrayList lotNum(){ + ArrayList list = new ArrayList<>(); + Random r = new Random(); + for (int i = 0; i < 10; i++) { + int num = r.nextInt(50) + 1; + + if (!list.contains(num)){ + list.add(num); + }else{ + i--; + } + } + return list; + } +} \ No newline at end of file diff --git a/day01/src/com/inmind/test08/Student.java b/day01/src/com/inmind/test08/Student.java new file mode 100644 index 0000000..1c40cf0 --- /dev/null +++ b/day01/src/com/inmind/test08/Student.java @@ -0,0 +1,53 @@ +package com.inmind.test08; + +class Student { + private String name; // 学生姓名 + private double grade; // 学生成绩 + + // 静态变量:学生总人数 + public static int totalStudents = 0; + // 静态变量:所有学生的总成绩 + public static double totalGrades = 0; + + // 静态代码块,用于初始化类加载时的操作 + static { + System.out.println("学生成绩管理系统初始化中..."); + } + + // 构造方法 + public Student(String name, double grade) { + this.name = name; + this.grade = grade; + totalStudents++; // 每创建一个学生对象,总人数加1 + totalGrades += grade; // 累加总成绩 + } + + // 获取学生姓名 + public String getName() { + return name; + } + + // 获取学生成绩 + public double getGrade() { + return grade; + } + + // 设置学生成绩 + public void setGrade(double grade) { + // 更新总成绩:减去旧成绩,加上新成绩 + totalGrades = totalGrades - this.grade + grade; + this.grade = grade; + } + + // 静态方法:计算平均分 + public static double calculateAverageGrade() { + if (totalStudents == 0) return 0; + return totalGrades / totalStudents; + } + + // 静态方法:重置学生统计信息 + public static void resetStatistics() { + totalStudents = 0; + totalGrades = 0; + } +} \ No newline at end of file diff --git a/day01/src/com/inmind/test08/StudentGradeSystem.java b/day01/src/com/inmind/test08/StudentGradeSystem.java new file mode 100644 index 0000000..4d8ff9d --- /dev/null +++ b/day01/src/com/inmind/test08/StudentGradeSystem.java @@ -0,0 +1,117 @@ +package com.inmind.test08; + +import java.util.Arrays; +import java.util.Scanner; + +public class StudentGradeSystem { + // 定义最大学生数量的常量 + private static final int MAX_STUDENTS = 20; + // 存储学生姓名的数组 + private static String[] names = new String[MAX_STUDENTS]; + // 存储学生成绩的数组 + private static double[] grades = new double[MAX_STUDENTS]; + // 当前学生数量计数器 + private static int count = 0; + + public static void main(String[] args) { + // 创建Scanner对象用于用户输入 + Scanner scanner = new Scanner(System.in); + + // 主循环,持续显示菜单直到用户选择退出 + while (true) { + System.out.println("1. 添加学生 2. 查看列表 3. 统计分析 4. 退出"); + System.out.println("请选择: "); + int choice = scanner.nextInt(); + scanner.nextLine(); // 消耗换行符,避免影响后续输入 + + // 根据用户选择执行相应操作 + switch (choice) { + case 1: + addStudent(scanner); + break; + case 2: + printStudents(); + break; + case 3: + analyzeGrades(); + break; + case 4: + System.out.println("退出系统"); + return; // 结束程序 + } + } + } + + // 添加学生信息的方法 + private static void addStudent(Scanner scanner) { + // 检查是否达到最大学生数量 + if (count >= MAX_STUDENTS) { + System.out.println("学生数量已满"); + return; + } + + // 获取用户输入的姓名 + System.out.print("输入姓名: "); + String name = scanner.nextLine(); + + // 获取用户输入的成绩 + System.out.print("输入成绩: "); + double grade = scanner.nextDouble(); + scanner.nextLine(); // 消耗换行符 + + // 将学生信息添加到数组中 + names[count] = name; + grades[count] = grade; + count++; // 学生数量加1 + + System.out.println("添加成功"); + } + + // 打印所有学生信息的方法 + private static void printStudents() { + // 检查是否有学生数据 + if (count == 0) { + System.out.println("暂无学生数据"); + return; + } + + System.out.println("\n学生列表:"); + // 遍历学生数组并格式化输出 + for (int i = 0; i < count; i++) { +// System.out.printf("%d. %-8s %.1f\n", i + 1, names[i], grades[i]); + System.out.println((i+1)+". "+names[i]+" "+grades[i]); + } + } + + // 分析学生成绩的方法 + private static void analyzeGrades() { + // 检查是否有学生数据 + if (count == 0) { + System.out.println("暂无学生数据"); + return; + } + + double sum = 0; // 成绩总和 + double max = grades[0]; // 最高分,初始化为第一个学生成绩 + double min = grades[0]; // 最低分,初始化为第一个学生成绩 + + // 计算总分、最高分和最低分 + for (double grade : grades) { + sum += grade; + if (grade > max) max = grade; + if (grade < min) min = grade; + } + + double avg = sum / count; // 计算平均分 + avg = Math.round(avg * 100) / 100.0; + // 复制成绩数组并排序 + double[] sortedGrades = Arrays.copyOf(grades, count); + Arrays.sort(sortedGrades); + + // 输出统计结果 + System.out.println("平均分: "+avg); + System.out.println("最高分: "+ max); + System.out.println("最低分: "+ min); + System.out.println("成绩排序: " + Arrays.toString(sortedGrades)); + } +} diff --git a/day01/src/com/inmind/test08/StudentGradeSystem2.java b/day01/src/com/inmind/test08/StudentGradeSystem2.java new file mode 100644 index 0000000..84f101f --- /dev/null +++ b/day01/src/com/inmind/test08/StudentGradeSystem2.java @@ -0,0 +1,126 @@ +package com.inmind.test08; + +import java.util.Arrays; +import java.util.Scanner; + +public class StudentGradeSystem2 { + private static final int MAX_STUDENTS = 20; + private static Student[] students = new Student[MAX_STUDENTS]; + private static int count = 0; + + public static void main(String[] args) { + + Scanner scanner = new Scanner(System.in); + + while (true) { + System.out.println("\n1. 添加学生 2. 查看列表 3. 统计分析 4. 修改成绩 5. 退出"); + System.out.print("请选择: "); + int choice = scanner.nextInt(); + scanner.nextLine(); // 消耗换行符 + + switch (choice) { + case 1: + addStudent(scanner); + break; + case 2: + printStudents(); + break; + case 3: + analyzeGrades(); + break; + case 4: + modifyGrade(scanner); + break; + case 5: + System.out.println("退出系统"); + return; + } + } + } + + private static void addStudent(Scanner scanner) { + if (count >= MAX_STUDENTS) { + System.out.println("学生数量已满"); + return; + } + + System.out.print("输入姓名: "); + String name = scanner.nextLine(); + + System.out.print("输入成绩: "); + double grade = scanner.nextDouble(); + scanner.nextLine(); + + students[count] = new Student(name, grade); + count++; + + System.out.println("添加成功"); + } + + private static void printStudents() { + if (count == 0) { + System.out.println("暂无学生数据"); + return; + } + + System.out.println("\n学生列表:"); + for (int i = 0; i < count; i++) { + Student student = students[i]; + System.out.printf("%d. %-8s %.1f\n", i + 1, student.getName(), student.getGrade()); + } + } + + private static void analyzeGrades() { + if (count == 0) { + System.out.println("暂无学生数据"); + return; + } + + // 使用Student类的静态方法获取平均分 + double avg = Student.calculateAverageGrade(); + + // 计算最高分和最低分 + double max = students[0].getGrade(); + double min = students[0].getGrade(); + + for (int i = 1; i < count; i++) { + double grade = students[i].getGrade(); + if (grade > max) max = grade; + if (grade < min) min = grade; + } + + // 复制成绩数组并排序 + double[] sortedGrades = new double[count]; + for (int i = 0; i < count; i++) { + sortedGrades[i] = students[i].getGrade(); + } + Arrays.sort(sortedGrades); + + // 输出统计结果 + System.out.printf("\n平均分: %.2f\n", avg); + System.out.printf("最高分: %.2f\n", max); + System.out.printf("最低分: %.2f\n", min); + System.out.println("成绩排序: " + Arrays.toString(sortedGrades)); + System.out.printf("学生总数: %d\n", Student.totalStudents); + } + + private static void modifyGrade(Scanner scanner) { + System.out.print("请输入要修改成绩的学生姓名: "); + String name = scanner.nextLine(); + + for (int i = 0; i < count; i++) { + if (students[i].getName().equalsIgnoreCase(name)) { + System.out.printf("当前成绩: %.1f\n", students[i].getGrade()); + System.out.print("输入新成绩: "); + double newGrade = scanner.nextDouble(); + scanner.nextLine(); + + students[i].setGrade(newGrade); + System.out.println("成绩修改成功"); + return; + } + } + + System.out.println("未找到该学生"); + } +} \ No newline at end of file diff --git a/day01/src/com/inmind/test09/Test.java b/day01/src/com/inmind/test09/Test.java new file mode 100644 index 0000000..f1f3927 --- /dev/null +++ b/day01/src/com/inmind/test09/Test.java @@ -0,0 +1,242 @@ +package com.inmind.test09; + +public class Test { + public static void main(String[] args) { + // 创建员工管理系统实例 + EmployeeManager manager = new EmployeeManager(); + + // 添加不同类型的员工到系统中 + manager.addEmployee(new Developer("张三", "D001", "Java")); + manager.addEmployee(new Designer("李四", "D002", "UI/UX")); + manager.addEmployee(new Tester("王五", "T001", "自动化测试")); + + // 显示公司所有员工的详细信息 + System.out.println("公司员工列表:"); + manager.displayAllEmployees(); + + // 计算并显示公司本月的工资总支出 + System.out.println("\n本月公司工资总支出:" + manager.calculateTotalSalary() + "元"); + + // 创建一个新项目并安排员工任务 + System.out.println("\n项目任务安排:"); + Project project = new Project("企业管理系统", "2025-07-20", "2025-12-31"); + manager.assignProjectTasks(project); + } +} + +/** + * 员工抽象类 - 定义所有员工的通用属性和行为 + * 不能直接实例化,必须由具体子类实现 + */ +abstract class Employee { + private String name; // 员工姓名 + private String employeeId; // 员工工号 + private double baseSalary; // 基本工资 + + // 构造函数,初始化员工基本信息 + public Employee(String name, String employeeId, double baseSalary) { + this.name = name; + this.employeeId = employeeId; + this.baseSalary = baseSalary; + } + + // 抽象方法:计算员工工资(由子类根据具体职位实现) + public abstract double calculateSalary(); + + // 抽象方法:执行工作(由子类根据具体职责实现) + public abstract void performWork(); + + // 获取员工姓名 + public String getName() { + return name; + } + + // 获取员工工号 + public String getEmployeeId() { + return employeeId; + } + + // 获取员工基本工资 + public double getBaseSalary() { + return baseSalary; + } + + // 重写toString方法,返回员工信息的字符串表示 + @Override + public String toString() { + return "姓名:" + name + + ",工号:" + employeeId + + ",职位:" + this.getClass().getSimpleName() + + ",月薪:" + calculateSalary() + "元"; + } +} + +/** + * 开发人员类 - 继承自Employee + * 具体实现开发人员的工资计算和工作内容 + */ +class Developer extends Employee { + private String programmingLanguage; // 开发使用的编程语言 + + // 构造函数,初始化开发人员信息 + public Developer(String name, String employeeId, String programmingLanguage) { + super(name, employeeId, 15000); // 调用父类构造函数设置基本工资 + this.programmingLanguage = programmingLanguage; + } + + // 实现父类的抽象方法:计算开发人员工资(基本工资 + 技术津贴) + @Override + public double calculateSalary() { + return getBaseSalary() + (programmingLanguage.equals("Java") ? 2000 : 1500); + } + + // 实现父类的抽象方法:描述开发人员的工作内容 + @Override + public void performWork() { + System.out.println(getName() + "正在使用" + programmingLanguage + "编写代码"); + } + + // 获取开发人员使用的编程语言 + public String getProgrammingLanguage() { + return programmingLanguage; + } +} + +/** + * 设计人员类 - 继承自Employee + * 具体实现设计人员的工资计算和工作内容 + */ +class Designer extends Employee { + private String designTool; // 设计使用的工具 + + // 构造函数,初始化设计人员信息 + public Designer(String name, String employeeId, String designTool) { + super(name, employeeId, 13000); // 调用父类构造函数设置基本工资 + this.designTool = designTool; + } + + // 实现父类的抽象方法:计算设计人员工资(基本工资 + 设计津贴) + @Override + public double calculateSalary() { + return getBaseSalary() + (designTool.equals("UI/UX") ? 1800 : 1200); + } + + // 实现父类的抽象方法:描述设计人员的工作内容 + @Override + public void performWork() { + System.out.println(getName() + "正在使用" + designTool + "进行设计工作"); + } + + // 获取设计人员使用的设计工具 + public String getDesignTool() { + return designTool; + } +} + +/** + * 测试人员类 - 继承自Employee + * 具体实现测试人员的工资计算和工作内容 + */ +class Tester extends Employee { + private String testingMethod; // 测试方法 + + // 构造函数,初始化测试人员信息 + public Tester(String name, String employeeId, String testingMethod) { + super(name, employeeId, 12000); // 调用父类构造函数设置基本工资 + this.testingMethod = testingMethod; + } + + // 实现父类的抽象方法:计算测试人员工资(基本工资 + 测试津贴) + @Override + public double calculateSalary() { + return getBaseSalary() + (testingMethod.equals("自动化测试") ? 2500 : 1500); + } + + // 实现父类的抽象方法:描述测试人员的工作内容 + @Override + public void performWork() { + System.out.println(getName() + "正在进行" + testingMethod + "工作"); + } + + // 获取测试人员使用的测试方法 + public String getTestingMethod() { + return testingMethod; + } +} + +/** + * 员工管理类 - 负责管理公司员工信息和项目任务分配 + */ +class EmployeeManager { + private Employee[] employees = new Employee[10]; // 员工数组,最多容纳10名员工 + private int employeeCount = 0; // 当前员工数量 + + // 添加员工到系统中 + public void addEmployee(Employee employee) { + if (employeeCount < employees.length) { + employees[employeeCount++] = employee; + } else { + System.out.println("员工列表已满,无法添加更多员工"); + } + } + + // 显示所有员工信息 + public void displayAllEmployees() { + for (int i = 0; i < employeeCount; i++) { + System.out.println(employees[i]); + } + } + + // 计算所有员工的总工资 + public double calculateTotalSalary() { + double total = 0; + for (int i = 0; i < employeeCount; i++) { + total += employees[i].calculateSalary(); + } + return total; + } + + // 为项目分配任务给员工 + public void assignProjectTasks(Project project) { + System.out.println("项目名称:" + project.getProjectName()); + System.out.println("开始日期:" + project.getStartDate()); + System.out.println("结束日期:" + project.getEndDate()); + System.out.println("任务分配:"); + + // 遍历所有员工,分配各自的任务 + for (int i = 0; i < employeeCount; i++) { + employees[i].performWork(); + } + } +} + +/** + * 项目类 - 定义项目的基本信息 + */ +class Project { + private String projectName; // 项目名称 + private String startDate; // 开始日期 + private String endDate; // 结束日期 + + // 构造函数,初始化项目信息 + public Project(String projectName, String startDate, String endDate) { + this.projectName = projectName; + this.startDate = startDate; + this.endDate = endDate; + } + + // 获取项目名称 + public String getProjectName() { + return projectName; + } + + // 获取项目开始日期 + public String getStartDate() { + return startDate; + } + + // 获取项目结束日期 + public String getEndDate() { + return endDate; + } +} \ No newline at end of file diff --git a/day01/src/com/inmind/test10/Chargeable.java b/day01/src/com/inmind/test10/Chargeable.java new file mode 100644 index 0000000..99b22d5 --- /dev/null +++ b/day01/src/com/inmind/test10/Chargeable.java @@ -0,0 +1,26 @@ +package com.inmind.test10; + +// 可充电接口 +public interface Chargeable { + // 抽象方法:充电 + void charge(int minutes); + + // 抽象方法:获取剩余电量 + int getBatteryPercentage(); + + // 私有静态方法:电量检查工具方法 + private static boolean isBatteryValid(int percentage) { + return percentage >= 0 && percentage <= 100; + } + + // 默认方法:显示电量 + default void showBatteryStatus() { + int battery = getBatteryPercentage(); + if (isBatteryValid(battery)) { + System.out.println("当前电量: " + battery + "%"); + } else { + System.out.println("电量数据异常"); + } + } +} + \ No newline at end of file diff --git a/day01/src/com/inmind/test10/Device.java b/day01/src/com/inmind/test10/Device.java new file mode 100644 index 0000000..4968598 --- /dev/null +++ b/day01/src/com/inmind/test10/Device.java @@ -0,0 +1,77 @@ +package com.inmind.test10; + +// 设备抽象基类 +public abstract class Device { + // 成员变量 + protected String brand; + protected String model; + protected double price; + protected boolean isPowerOn; + + // 静态变量:统计设备总数 + public static int totalDevices = 0; + + // 构造方法 + public Device(String brand, String model, double price) { + this.brand = brand; + this.model = model; + this.price = price; + this.isPowerOn = false; + totalDevices++; + } + + // 抽象方法:设备功能介绍 + public abstract void introduce(); + + // 开机方法 + public void powerOn() { + if (!isPowerOn) { + isPowerOn = true; + System.out.println(brand + " " + model + " 已开机"); + } else { + System.out.println(brand + " " + model + " 已经是开机状态"); + } + } + + // 关机方法 + public void powerOff() { + if (isPowerOn) { + isPowerOn = false; + System.out.println(brand + " " + model + " 已关机"); + } else { + System.out.println(brand + " " + model + " 已经是关机状态"); + } + } + + // 静态方法:获取设备总数 + public static int getTotalDevices() { + return totalDevices; + } + + // 静态方法:计算折扣价格 + /*public static double calculateDiscountPrice(Device device, double discountRate) { + if (discountRate < 0.1 || discountRate > 1.0) { + System.out.println("折扣率无效,必须在0.1-1.0之间"); + return device.price; + } + return device.price * discountRate; + }*/ + + // getter方法 + public String getBrand() { + return brand; + } + + public String getModel() { + return model; + } + + public double getPrice() { + return price; + } + + public boolean isPowerOn() { + return isPowerOn; + } +} + \ No newline at end of file diff --git a/day01/src/com/inmind/test10/DeviceManager.java b/day01/src/com/inmind/test10/DeviceManager.java new file mode 100644 index 0000000..2b57ccc --- /dev/null +++ b/day01/src/com/inmind/test10/DeviceManager.java @@ -0,0 +1,121 @@ +package com.inmind.test10; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.Comparator; +import java.util.List; + +// 设备管理器类 +public class DeviceManager { + private List devices; // 存储设备的集合 + + public DeviceManager() { + devices = new ArrayList<>(); + } + + // 添加设备 + public void addDevice(Device device) { + if (device != null) { + devices.add(device); + System.out.println("已添加设备: " + device.getBrand() + " " + device.getModel()); + } + } + + // 移除设备 + public boolean removeDevice(String brand, String model) { + for (int i = 0; i < devices.size(); i++) { + Device device = devices.get(i); + if (device.getBrand().equals(brand) && device.getModel().equals(model)) { + devices.remove(i); + System.out.println("已移除设备: " + brand + " " + model); + Device.totalDevices --; + return true; + } + } + System.out.println("未找到设备: " + brand + " " + model); + return false; + } + + // 显示所有设备 + public void showAllDevices() { + System.out.println("\n===== 所有设备列表 ====="); + if (devices.isEmpty()) { + System.out.println("没有任何设备"); + return; + } + + for (int i = 0; i < devices.size(); i++) { + System.out.print((i + 1) + ". "); + devices.get(i).introduce(); + } + } + + // 开机所有设备 + public void powerOnAllDevices() { + System.out.println("\n===== 开机所有设备 ====="); + for (Device device : devices) { + device.powerOn(); + } + } + + // 关机所有设备 + public void powerOffAllDevices() { + System.out.println("\n===== 关机所有设备 ====="); + for (Device device : devices) { + device.powerOff(); + } + } + + // 为所有可充电设备充电 + public void chargeAllChargeableDevices(int minutes) { + System.out.println("\n===== 为可充电设备充电 ====="); + for (Device device : devices) { + if (device instanceof Chargeable) { + Chargeable chargeable = (Chargeable) device; + chargeable.charge(minutes); + chargeable.showBatteryStatus(); + } + } + } + + // 按价格排序设备 + public void sortDevicesByPrice() { + System.out.println("\n===== 按价格排序设备 ====="); + // 使用匿名内部类实现Comparator接口 + Collections.sort(devices, new Comparator() { + @Override + public int compare(Device d1, Device d2) { + // 按价格升序排序 + return Double.compare(d1.getPrice(), d2.getPrice()); + } + }); + } + + // 查找特定品牌的设备 + public List findDevicesByBrand(String brand) { + List result = new ArrayList<>(); + for (Device device : devices) { + if (device.getBrand().equals(brand)) { + result.add(device); + } + } + return result; + } + + // 显示所有可充电设备 + public void showChargeableDevices() { + System.out.println("\n===== 可充电设备 ====="); + boolean hasChargeable = false; + for (Device device : devices) { + if (device instanceof Chargeable) { + hasChargeable = true; + device.introduce(); + ((Chargeable) device).showBatteryStatus(); + } + } + if (!hasChargeable) { + System.out.println("没有可充电设备"); + } + } +} + \ No newline at end of file diff --git a/day01/src/com/inmind/test10/DeviceTest.java b/day01/src/com/inmind/test10/DeviceTest.java new file mode 100644 index 0000000..92bb8c5 --- /dev/null +++ b/day01/src/com/inmind/test10/DeviceTest.java @@ -0,0 +1,65 @@ +package com.inmind.test10; + +import java.util.List; + +// 测试类 +public class DeviceTest { + public static void main(String[] args) { + // 创建设备管理器 + DeviceManager manager = new DeviceManager(); + + // 添加设备 + manager.addDevice(new Smartphone("Apple", "iPhone 14", 6999.0, 256)); + manager.addDevice(new Laptop("Dell", "XPS 15", 9999.0, 32)); + manager.addDevice(new SmartTV("Sony", "KD-65X9000H", 7999.0, 65.0)); + manager.addDevice(new Smartphone("Samsung", "Galaxy S23", 5999.0, 512)); + manager.addDevice(new Laptop("Lenovo", "ThinkPad X1", 8999.0, 16)); + + // 显示所有设备 + manager.showAllDevices(); + + // 显示设备总数(静态方法使用) + System.out.println("\n当前设备总数: " + Device.getTotalDevices()); + + // 开机所有设备 + manager.powerOnAllDevices(); + + // 为所有可充电设备充电60分钟 + manager.chargeAllChargeableDevices(60); + + // 显示可充电设备及其电量 + manager.showChargeableDevices(); + + // 按价格排序并显示 + /*manager.sortDevicesByPrice(); + manager.showAllDevices();*/ + + // 测试多态:调用特定设备的方法 + System.out.println("\n===== 设备功能测试 ====="); + List appleDevices = manager.findDevicesByBrand("Apple"); + for (Device device : appleDevices) { + if (device instanceof Smartphone) { + Smartphone phone = (Smartphone) device; + phone.connectToNetwork("家庭WiFi"); + phone.takePhoto(); + phone.showBatteryStatus(); + phone.disconnectFromNetwork(); + } + } + + // 测试静态方法:计算折扣价格 + /*Device laptop = manager.findDevicesByBrand("Dell").get(0); + double discountPrice = Device.calculateDiscountPrice(laptop, 0.8); + System.out.println("\n" + laptop.getBrand() + " " + laptop.getModel() + + " 原价: " + laptop.getPrice() + " 折扣价: " + discountPrice);*/ + + // 关机所有设备 + manager.powerOffAllDevices(); + + // 移除一个设备 + manager.removeDevice("Sony", "KD-65X9000H"); + manager.showAllDevices(); + + } +} + \ No newline at end of file diff --git a/day01/src/com/inmind/test10/Laptop.java b/day01/src/com/inmind/test10/Laptop.java new file mode 100644 index 0000000..1a4f27d --- /dev/null +++ b/day01/src/com/inmind/test10/Laptop.java @@ -0,0 +1,69 @@ +package com.inmind.test10; + +// 笔记本电脑类 - 实现两个接口 +public class Laptop extends Device implements Networkable, Chargeable { + private int ramSize; // 内存大小(GB) + private int batteryLevel; // 电池电量(%) + + public Laptop(String brand, String model, double price, int ramSize) { + super(brand, model, price); + this.ramSize = ramSize; + this.batteryLevel = 70; // 初始电量70% + } + + @Override + public void introduce() { + System.out.println("这是一台" + brand + " " + model + "笔记本电脑,价格" + price + + "元,内存大小" + ramSize + "GB"); + } + + // 特有方法:运行程序 + public void runProgram(String programName) { + if (isPowerOn()) { + System.out.println(brand + " " + model + " 正在运行 " + programName); + batteryLevel -= 10; // 运行程序消耗电量 + } else { + System.out.println("请先开机再运行程序"); + } + } + + // 实现Networkable接口方法 + @Override + public void connectToNetwork(String networkName) { + if (isPowerOn() && Networkable.isNetworkAvailable()) { + System.out.println(brand + " " + model + " 已连接到 " + networkName); + } else if (!isPowerOn()) { + System.out.println("请先开机再连接网络"); + } else { + System.out.println("网络不可用,无法连接到 " + networkName); + } + } + + @Override + public void disconnectFromNetwork() { + System.out.println(brand + " " + model + " 已断开网络连接"); + } + + // 实现Chargeable接口方法 + @Override + public void charge(int minutes) { + if (minutes <= 0) { + System.out.println("充电时间必须为正数"); + return; + } + + System.out.println(brand + " " + model + " 正在充电" + minutes + "分钟"); + int chargeAmount = minutes / 5; // 每5分钟充1% + batteryLevel += chargeAmount; + + if (batteryLevel > 100) { + batteryLevel = 100; + } + } + + @Override + public int getBatteryPercentage() { + return batteryLevel; + } +} + \ No newline at end of file diff --git a/day01/src/com/inmind/test10/Networkable.java b/day01/src/com/inmind/test10/Networkable.java new file mode 100644 index 0000000..28b539e --- /dev/null +++ b/day01/src/com/inmind/test10/Networkable.java @@ -0,0 +1,17 @@ +package com.inmind.test10; + +// 可联网接口 +public interface Networkable { + // 抽象方法:连接网络 + void connectToNetwork(String networkName); + + // 抽象方法:断开网络 + void disconnectFromNetwork(); + + // 静态方法:检查网络可用性 + static boolean isNetworkAvailable() { + // 模拟网络检查 + return Math.random() > 0.2; // 80%概率网络可用 + } +} + \ No newline at end of file diff --git a/day01/src/com/inmind/test10/SmartTV.java b/day01/src/com/inmind/test10/SmartTV.java new file mode 100644 index 0000000..f80767e --- /dev/null +++ b/day01/src/com/inmind/test10/SmartTV.java @@ -0,0 +1,44 @@ +package com.inmind.test10; + +// 智能电视类 - 实现一个接口 +public class SmartTV extends Device implements Networkable { + private double screenSize; // 屏幕尺寸(英寸) + + public SmartTV(String brand, String model, double price, double screenSize) { + super(brand, model, price); + this.screenSize = screenSize; + } + + @Override + public void introduce() { + System.out.println("这是一台" + brand + " " + model + "智能电视,价格" + price + + "元,屏幕尺寸" + screenSize + "英寸"); + } + + // 特有方法:播放视频 + public void playVideo(String videoName) { + if (isPowerOn()) { + System.out.println(brand + " " + model + " 正在播放 " + videoName); + } else { + System.out.println("请先开机再播放视频"); + } + } + + // 实现Networkable接口方法 + @Override + public void connectToNetwork(String networkName) { + if (isPowerOn() && Networkable.isNetworkAvailable()) { + System.out.println(brand + " " + model + " 已连接到 " + networkName); + } else if (!isPowerOn()) { + System.out.println("请先开机再连接网络"); + } else { + System.out.println("网络不可用,无法连接到 " + networkName); + } + } + + @Override + public void disconnectFromNetwork() { + System.out.println(brand + " " + model + " 已断开网络连接"); + } +} + \ No newline at end of file diff --git a/day01/src/com/inmind/test10/Smartphone.java b/day01/src/com/inmind/test10/Smartphone.java new file mode 100644 index 0000000..d5c4de9 --- /dev/null +++ b/day01/src/com/inmind/test10/Smartphone.java @@ -0,0 +1,69 @@ +package com.inmind.test10; + +// 智能手机类 - 实现两个接口 +public class Smartphone extends Device implements Networkable, Chargeable { + private int storage; // 存储容量(GB) + private int batteryLevel; // 电池电量(%) + + public Smartphone(String brand, String model, double price, int storage) { + super(brand, model, price); + this.storage = storage; + this.batteryLevel = 50; // 初始电量50% + } + + @Override + public void introduce() { + System.out.println("这是一部" + brand + " " + model + "智能手机,价格" + price + + "元,存储容量" + storage + "GB"); + } + + // 特有方法:拍照 + public void takePhoto() { + if (isPowerOn()) { + System.out.println(brand + " " + model + " 正在拍照"); + batteryLevel -= 5; // 拍照消耗电量 + } else { + System.out.println("请先开机再拍照"); + } + } + + // 实现Networkable接口方法 + @Override + public void connectToNetwork(String networkName) { + if (isPowerOn() && Networkable.isNetworkAvailable()) { + System.out.println(brand + " " + model + " 已连接到 " + networkName); + } else if (!isPowerOn()) { + System.out.println("请先开机再连接网络"); + } else { + System.out.println("网络不可用,无法连接到 " + networkName); + } + } + + @Override + public void disconnectFromNetwork() { + System.out.println(brand + " " + model + " 已断开网络连接"); + } + + // 实现Chargeable接口方法 + @Override + public void charge(int minutes) { + if (minutes <= 0) { + System.out.println("充电时间必须为正数"); + return; + } + + System.out.println(brand + " " + model + " 正在充电" + minutes + "分钟"); + int chargeAmount = minutes / 2; // 每2分钟充1% + batteryLevel += chargeAmount; + + if (batteryLevel > 100) { + batteryLevel = 100; + } + } + + @Override + public int getBatteryPercentage() { + return batteryLevel; + } +} + \ No newline at end of file diff --git a/day01/src/com/inmind/test11/CorssFire.java b/day01/src/com/inmind/test11/CorssFire.java new file mode 100644 index 0000000..8cae7cc --- /dev/null +++ b/day01/src/com/inmind/test11/CorssFire.java @@ -0,0 +1,299 @@ +package com.inmind.test11;// 导入所需的Java工具类 +import java.util.ArrayList; // 用于创建动态数组 +import java.util.List; // 用于定义列表接口 +import java.util.Random; // 用于生成随机数(本案例未直接使用,预留扩展) + +// 武器接口 - 定义所有武器的共同行为 +interface Weapon { + // 开火方法,参数为攻击目标玩家 + void fire(Player target); + // 换弹方法 + void reload(); + // 获取武器名称 + String getName(); + // 获取武器伤害值 + int getDamage(); + // 获取当前弹夹剩余弹药 + int getAmmoCount(); +} + +// 玩家类 - 代表游戏中的玩家角色 +class Player { + private String name; // 玩家名称 + private int hp; // 玩家生命值 + private List weapons; // 玩家持有的武器列表 + private Weapon currentWeapon; // 当前使用的武器 + + // 构造方法 - 初始化玩家名称和生命值 + public Player(String name) { + this.name = name; + this.hp = 100; // 初始生命值设为100 + this.weapons = new ArrayList<>(); // 初始化武器列表 + } + + // 拾取武器方法 - 将武器添加到玩家的武器库 + public void pickUpWeapon(Weapon weapon) { + weapons.add(weapon); // 添加武器到列表 + if (currentWeapon == null) { // 如果还没有当前武器 + currentWeapon = weapon; // 自动装备该武器 + } + System.out.println(name + "拾取了" + weapon.getName()); + } + + // 切换武器方法 - 接口作为参数 + public void switchWeapon(Weapon weapon) { + // 检查玩家是否拥有该武器\ + for (int i = 0; i < weapons.size(); i++) { + Weapon w = weapons.get(i); + if (w.getName().equals(weapon.getName())) { + currentWeapon = weapon; // 切换到该武器 + System.out.println(name + "切换到" + weapon.getName()); + return; + } + } + + System.out.println(name + "没有该武器!"); + + /*if (weapons.contains(weapon)) { + currentWeapon = weapon; // 切换到该武器 + System.out.println(name + "切换到" + weapon.getName()); + } else { + System.out.println(name + "没有该武器!"); + }*/ + } + + // 攻击目标玩家方法 + public void attack(Player target) { + if (currentWeapon == null) { // 检查是否持有武器 + System.out.println(name + "没有武器!"); + return; + } + + // 输出攻击信息 + System.out.println("\n" + name + "使用" + currentWeapon.getName() + "攻击" + target.name); + currentWeapon.fire(target); // 使用当前武器攻击目标 + + // 如果弹药耗尽,自动换弹 + if (currentWeapon.getAmmoCount() == 0) { + currentWeapon.reload(); + } + } + + // 受到伤害方法 + public void takeDamage(int damage) { + // 计算剩余生命值,确保不会为负数 + hp = Math.max(0, hp - damage); + System.out.println(name + "受到" + damage + "点伤害,剩余HP:" + hp); + // 如果生命值为0,输出被淘汰信息 + if (hp == 0) { + System.out.println(name + "被淘汰!"); + } + } + + // 获取玩家名称的方法 + public String getName() { + return name; + } + + public int getHp() { + return hp; + } +} + +// 武器工厂类 - 用于创建各种武器实例(工厂模式) +class WeaponFactory { + // 创建武器的静态方法 - 接口作为返回值 + public static Weapon createWeapon(String type) { + // 根据类型创建不同武器(使用匿名内部类实现Weapon接口) + switch (type.toLowerCase()) { + case "ak47": // 创建AK47步枪 + return new Weapon() { + private int ammo = 30; // 当前弹药 + private final int maxAmmo = 30; // 最大弹容量 + + @Override + public void fire(Player target) { + if (ammo <= 0) { // 检查弹药是否充足 + System.out.println("弹药耗尽,请换弹!"); + return; + } + ammo--; // 消耗1发弹药 + target.takeDamage(42); // 造成42点伤害 + System.out.println("🔫 AK47开火!剩余弹药:" + ammo); + } + + @Override + public void reload() { + System.out.println("AK47换弹中..."); + ammo = maxAmmo; // 装满弹药 + } + + @Override + public String getName() { + return "AK47"; + } + + @Override + public int getDamage() { + return 42; + } + + @Override + public int getAmmoCount() { + return ammo; + } + }; + + case "awm": // 创建AWM狙击枪 + return new Weapon() { + private int ammo = 10; // 当前弹药 + private final int maxAmmo = 10; // 最大弹容量 + + @Override + public void fire(Player target) { + if (ammo <= 0) { + System.out.println("弹药耗尽,请换弹!"); + return; + } + ammo--; + target.takeDamage(100); // 造成100点伤害(狙击枪威力大) + System.out.println("🎯 AWM开镜射击!剩余弹药:" + ammo); + } + + @Override + public void reload() { + System.out.println("AWM换弹中..."); + ammo = maxAmmo; + } + + @Override + public String getName() { + return "AWM"; + } + + @Override + public int getDamage() { + return 100; + } + + @Override + public int getAmmoCount() { + return ammo; + } + }; + + default: // 默认创建沙漠之鹰手枪 + return new Weapon() { + private int ammo = 12; // 当前弹药 + private final int maxAmmo = 12; // 最大弹容量 + + @Override + public void fire(Player target) { + if (ammo <= 0) { + System.out.println("弹药耗尽,请换弹!"); + return; + } + ammo--; + target.takeDamage(25); // 造成25点伤害 + System.out.println("🔫 沙漠之鹰开火!剩余弹药:" + ammo); + } + + @Override + public void reload() { + System.out.println("沙漠之鹰换弹中..."); + ammo = maxAmmo; + } + + @Override + public String getName() { + return "沙漠之鹰"; + } + + @Override + public int getDamage() { + return 25; + } + + @Override + public int getAmmoCount() { + return ammo; + } + }; + } + } +} + +// 主类 - 程序入口 +public class CorssFire { + public static void main(String[] args) { + // 创建两个玩家 + Player player1 = new Player("潜伏者-小明"); + Player player2 = new Player("保卫者-小红"); + + // 玩家拾取武器(通过武器工厂创建) + player1.pickUpWeapon(WeaponFactory.createWeapon("ak47")); + player2.pickUpWeapon(WeaponFactory.createWeapon("awm")); + + // 玩家2额外拾取M4A1(使用匿名内部类直接创建武器) + player2.pickUpWeapon(new Weapon() { + private int ammo = 30; + private final int maxAmmo = 30; + + @Override + public void fire(Player target) { + if (ammo <= 0) { + System.out.println("弹药耗尽,请换弹!"); + return; + } + ammo--; + target.takeDamage(30); // M4A1造成30点伤害 + System.out.println("🔫 M4A1开火!剩余弹药:" + ammo); + } + + @Override + public void reload() { + System.out.println("M4A1换弹中..."); + ammo = maxAmmo; + } + + @Override + public String getName() { + return "M4A1"; + } + + @Override + public int getDamage() { + return 30; + } + + @Override + public int getAmmoCount() { + return ammo; + } + }); + + /*// 模拟对战过程 + System.out.println("\n=== 开始对战 ==="); + player1.attack(player2); // 玩家1攻击玩家2 + player2.attack(player1); // 玩家2反击 + player1.attack(player2); // 玩家1再次攻击*/ + + while (true){ + // 模拟对战过程 + System.out.println("\n=== 开始对战 ==="); + player1.attack(player2); // 玩家1攻击玩家2 + if (player2.getHp() == 0) { + break; + } + player2.attack(player1); // 玩家2反击 + if (player1.getHp() == 0) { + break; + } + } + + // 玩家2切换武器 + player2.switchWeapon(WeaponFactory.createWeapon("awm")); +// player2.attack(player1); // 使用新武器攻击 + } +} + \ No newline at end of file diff --git a/day01/src/com/inmind/test11_1/Test.java b/day01/src/com/inmind/test11_1/Test.java new file mode 100644 index 0000000..c449f22 --- /dev/null +++ b/day01/src/com/inmind/test11_1/Test.java @@ -0,0 +1,261 @@ +package com.inmind.test11_1; + +import java.util.ArrayList; +import java.util.List; + +// 武器接口 +interface Weapon { + // 开火 + void fire(Player target); + // 换弹 + void reload(); + // 获取武器名称 + String getName(); + // 获取伤害值 + int getDamage(); + // 获取当前弹夹容量 + int getAmmoCount(); +} + +// 玩家类 +class Player { + private String name; + private int hp; + private List weapons = new ArrayList<>(); + private Weapon currentWeapon; + + public Player(String name) { + this.name = name; + this.hp = 100; + } + + // 拾取武器 + public void pickUpWeapon(Weapon weapon) { + weapons.add(weapon); + if (currentWeapon == null) { + currentWeapon = weapon; + } + System.out.println(name + "拾取了" + weapon.getName()); + } + + // 切换武器(接口作为参数) + public void switchWeapon(Weapon weapon) { + if (weapons.contains(weapon)) { + currentWeapon = weapon; + System.out.println(name + "切换到" + weapon.getName()); + } else { + System.out.println(name + "没有该武器!"); + } + } + + // 攻击目标 + public void attack(Player target) { + if (currentWeapon == null) { + System.out.println(name + "没有武器!"); + return; + } + + System.out.println("\n" + name + "使用" + currentWeapon.getName() + "攻击" + target.name); + currentWeapon.fire(target); + + if (currentWeapon.getAmmoCount() == 0) { + currentWeapon.reload(); + } + } + + // 受到伤害 + public void takeDamage(int damage) { + hp = Math.max(0, hp - damage); + System.out.println(name + "受到" + damage + "点伤害,剩余HP:" + hp); + if (hp == 0) { + System.out.println(name + "被淘汰!"); + } + } + + public String getName() { + return name; + } +} + +// 武器工厂 +class WeaponFactory { + // 创建武器(接口作为返回值) + public static Weapon createWeapon(String type) { + switch (type.toLowerCase()) { + case "ak47": + return new Weapon() { + private int ammo = 30; + private final int maxAmmo = 30; + + @Override + public void fire(Player target) { + if (ammo <= 0) { + System.out.println("弹药耗尽,请换弹!"); + return; + } + ammo--; + target.takeDamage(42); + System.out.println("🔫 AK47开火!剩余弹药:" + ammo); + } + + @Override + public void reload() { + System.out.println("AK47换弹中..."); + ammo = maxAmmo; + } + + @Override + public String getName() { + return "AK47"; + } + + @Override + public int getDamage() { + return 42; + } + + @Override + public int getAmmoCount() { + return ammo; + } + }; + + case "awm": + return new Weapon() { + private int ammo = 10; + private final int maxAmmo = 10; + + @Override + public void fire(Player target) { + if (ammo <= 0) { + System.out.println("弹药耗尽,请换弹!"); + return; + } + ammo--; + target.takeDamage(100); + System.out.println("🎯 AWM开镜射击!剩余弹药:" + ammo); + } + + @Override + public void reload() { + System.out.println("AWM换弹中..."); + ammo = maxAmmo; + } + + @Override + public String getName() { + return "AWM"; + } + + @Override + public int getDamage() { + return 100; + } + + @Override + public int getAmmoCount() { + return ammo; + } + }; + + default: + return new Weapon() { + private int ammo = 12; + private final int maxAmmo = 12; + + @Override + public void fire(Player target) { + if (ammo <= 0) { + System.out.println("弹药耗尽,请换弹!"); + return; + } + ammo--; + target.takeDamage(25); + System.out.println("🔫 沙漠之鹰开火!剩余弹药:" + ammo); + } + + @Override + public void reload() { + System.out.println("沙漠之鹰换弹中..."); + ammo = maxAmmo; + } + + @Override + public String getName() { + return "沙漠之鹰"; + } + + @Override + public int getDamage() { + return 25; + } + + @Override + public int getAmmoCount() { + return ammo; + } + }; + } + } +} + +public class Test { + public static void main(String[] args) { + // 创建玩家 + Player player1 = new Player("潜伏者-小明"); + Player player2 = new Player("保卫者-小红"); + + // 拾取武器 + player1.pickUpWeapon(WeaponFactory.createWeapon("ak47")); + player2.pickUpWeapon(WeaponFactory.createWeapon("awm")); + + // 玩家2额外拾取手枪(匿名内部类实现) + player2.pickUpWeapon(new Weapon() { + private int ammo = 30; + private final int maxAmmo = 30; + + @Override + public void fire(Player target) { + if (ammo <= 0) { + System.out.println("弹药耗尽,请换弹!"); + return; + } + ammo--; + target.takeDamage(30); + System.out.println("🔫 M4A1开火!剩余弹药:" + ammo); + } + + @Override + public void reload() { + System.out.println("M4A1换弹中..."); + ammo = maxAmmo; + } + + @Override + public String getName() { + return "M4A1"; + } + + @Override + public int getDamage() { + return 30; + } + + @Override + public int getAmmoCount() { + return ammo; + } + }); + + // 模拟对战 + System.out.println("\n=== 开始对战 ==="); + player1.attack(player2); + player2.attack(player1); + player1.attack(player2); + + // 切换武器 + player2.switchWeapon(WeaponFactory.createWeapon("default")); + player2.attack(player1); + } +} + \ No newline at end of file diff --git a/day01/src/logback.xml b/day01/src/logback.xml new file mode 100644 index 0000000..4874d47 --- /dev/null +++ b/day01/src/logback.xml @@ -0,0 +1,47 @@ + + + + + + System.out + + + %d{yyyy-MM-dd HH:mm:ss.SSS} [%-5level] %c [%thread] : %msg%n + + + + + + + %d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + utf-8 + + + D:/log/inmind-data.log + + + + D:/log/inmind-data-%i-%d{yyyy-MM-dd}-.log.gz + + 1MB + + + + + + + + + + + \ No newline at end of file diff --git a/day02/src/Demo.java b/day02/src/Demo.java new file mode 100644 index 0000000..61a31c5 --- /dev/null +++ b/day02/src/Demo.java @@ -0,0 +1,26 @@ +/* +循环的嵌套:外层循环执行一次,内层循环要执行一轮 +*/ +public class Demo{ + public static void main(String[] args){ + //使用循环的嵌套,实现时钟的效果(一天有0~23小时,每小时有0~59分) + for(int h = 0;h<24;h++){ + //System.out.println(h+"点"); + for(int m = 0;m<60;m++){ + System.out.println(h+"点"+m+"分"); + } + } + } + + + public static void test1(String[] args){ + //打印出一个5行5列的矩形的* + for(int i = 1;i<=5;i++){ + for(int j = 1;j<=5;j++){ + System.out.print("*"); + } + System.out.println(""); + } + } + +} \ No newline at end of file diff --git a/day02/src/com/inmind/student/test1/Server4.java b/day02/src/com/inmind/student/test1/Server4.java new file mode 100644 index 0000000..bd3f071 --- /dev/null +++ b/day02/src/com/inmind/student/test1/Server4.java @@ -0,0 +1,27 @@ +package com.inmind.student.test1; + +import java.io.*; +import java.net.ServerSocket; +import java.net.Socket; +public class Server4 { + public static void main(String[] args) { + try { + ServerSocket serverSocket = new ServerSocket(8002); + Socket socket = serverSocket.accept(); + DataInputStream dis = new DataInputStream(socket.getInputStream()); + FileOutputStream fos = new FileOutputStream("D:\\io_test\\upload\\1.jpg"); + byte[] buffer = new byte[1024]; + int bytesRead; + while ((bytesRead = dis.read(buffer)) != -1) { + fos.write(buffer, 0, bytesRead); + } + fos.close(); + dis.close(); + socket.close(); + serverSocket.close(); + System.out.println("上传成功"); + } catch (IOException e) { + e.printStackTrace(); + } + } +} \ No newline at end of file diff --git a/day02/src/com/inmind/student/test1/Test9.java b/day02/src/com/inmind/student/test1/Test9.java new file mode 100644 index 0000000..006200c --- /dev/null +++ b/day02/src/com/inmind/student/test1/Test9.java @@ -0,0 +1,35 @@ +package com.inmind.student.test1; + +/* +练习三:上传图片文件 +客户端需求:把一个图片文件发送到服务端并读取回馈信息。要求判断文件是否存在及格式是否为jpg并要求文件小于2M。 +服务端需求:接收客户端发送过来的图片数据。进行存储后,回馈一个“上传成功”字样。支持多用户的并发访问。 + + */ +import java.io.*; +import java.net.Socket; +public class Test9 { + public static void main(String[] args) throws IOException { + Socket socket = new Socket("192.168.23.34", 8002); + DataOutputStream dos = new DataOutputStream(socket.getOutputStream()); + FileInputStream fis = new FileInputStream("aa.jpg"); + + byte[] buffer = new byte[1024]; + int bytesRead; + while ((bytesRead = fis.read(buffer)) != -1) { + /* if (!"png".equals("jpg")) { + System.out.println("文件格式错误"); + break; + } + if (fis.available() > 2 * 1024 * 1024) { + System.out.println("文件大小错误"); + break; + }*/ + dos.write(buffer, 0, bytesRead); + } + + fis.close(); + dos.close(); + socket.close(); + } +} \ No newline at end of file diff --git a/day02/src/com/inmind/student/吕征洋/Log.java b/day02/src/com/inmind/student/吕征洋/Log.java new file mode 100644 index 0000000..5c9a4f8 --- /dev/null +++ b/day02/src/com/inmind/student/吕征洋/Log.java @@ -0,0 +1,34 @@ +package com.inmind.student.吕征洋; +import java.io.Serializable; +public class Log implements Serializable, Comparable { + private final long timestamp; + private final String level; + private final String module; + private final String content; + public Log(long timestamp, String level, String module, String content) { + this.timestamp = timestamp; + this.level = level; + this.module = module; + this.content = content; + } + public long getTimestamp() { + return timestamp; + } + public String getLevel() { + return level; + } + public String getModule() { + return module; + } + public String getContent() { + return content; + } + @Override + public String toString() { + return "[" + timestamp + "] " + level + " " + module + ": " + content; + } + @Override + public int compareTo(Log other) { + return Long.compare(this.timestamp, other.timestamp); + } +} \ No newline at end of file diff --git a/day02/src/com/inmind/student/吕征洋/LogAnalyzerClient.java b/day02/src/com/inmind/student/吕征洋/LogAnalyzerClient.java new file mode 100644 index 0000000..38abbe4 --- /dev/null +++ b/day02/src/com/inmind/student/吕征洋/LogAnalyzerClient.java @@ -0,0 +1,139 @@ +package com.inmind.student.吕征洋; +import java.io.*; +import java.net.ConnectException; +import java.net.Socket; +import java.nio.file.*; +import java.util.*; +import java.util.concurrent.*; +import java.util.stream.*; +import java.util.stream.Collectors; +public class LogAnalyzerClient { + private static final String LOG_DIR = "D:\\io_test\\"; + private static final String SERVER_HOST = "localhost"; + private static final int SERVER_PORT = 8080; + private final List logs = Collections.synchronizedList(new ArrayList<>()); + public static void main(String[] args) { + LogAnalyzerClient analyzer = new LogAnalyzerClient(); + analyzer.startAnalysis(); + } + public void startAnalysis() { + List logFiles = findLogFiles(); + System.out.println("找到 " + logFiles.size() + " 个日志文件,开始解析..."); + parseLogFiles(logFiles); + System.out.println("日志解析完成,共解析 " + logs.size() + " 条日志"); + Map levelStats = analyzeByLevel(); + Map moduleErrorStats = analyzeModuleErrors(); + List earliestLogs = findEarliestLogs(3); + reportToServer(levelStats, moduleErrorStats, earliestLogs); + } + private List findLogFiles() { + try { + try (Stream paths = Files.list(Paths.get(LOG_DIR))) { + return paths + .filter(Files::isRegularFile) + .filter(path -> path.toString().endsWith(".log")) + .collect(Collectors.toList()); + } + } catch (IOException e) { + System.err.println("读取日志目录失败: " + e.getMessage()); + return Collections.emptyList(); + } + } + private void parseLogFiles(List logFiles) { + ExecutorService executor = Executors.newFixedThreadPool(5); + List> futures = new ArrayList<>(); + for (Path file : logFiles) { + futures.add(executor.submit(() -> parseSingleFile(file))); + } + for (Future future : futures) { + try { + future.get(); + } catch (InterruptedException | ExecutionException e) { + System.err.println("文件解析异常: " + e.getCause().getMessage()); + } + } + executor.shutdown(); + try { + if (!executor.awaitTermination(60, TimeUnit.SECONDS)) { + executor.shutdownNow(); + } + } catch (InterruptedException e) { + executor.shutdownNow(); + Thread.currentThread().interrupt(); + } + } + private void parseSingleFile(Path file) { + int lineCount = 0; + try (BufferedReader reader = Files.newBufferedReader(file)) { + String line; + while ((line = reader.readLine()) != null) { + try { + Log log = parseLogLine(line); + logs.add(log); + lineCount++; + } catch (IllegalArgumentException e) { + System.err.println("日志解析失败: " + line + " - " + e.getMessage()); + } + } + System.out.println("解析完成:" + file.getFileName() + ",共 " + lineCount + " 行"); + } catch (IOException e) { + System.err.println("读取文件失败: " + file + " - " + e.getMessage()); + } + } + private Log parseLogLine(String line) { + String[] parts = line.split(",", 4); + if (parts.length != 4) { + throw new IllegalArgumentException("日志格式错误: " + line); + } + try { + long timestamp = Long.parseLong(parts[0].trim()); + String level = parts[1].trim(); + String module = parts[2].trim(); + String content = parts[3].trim(); + + return new Log(timestamp, level, module, content); + } catch (NumberFormatException e) { + throw new IllegalArgumentException("时间戳格式错误: " + parts[0]); + } + } + private Map analyzeByLevel() { + return logs.parallelStream() + .collect(Collectors.groupingBy( + Log::getLevel, + Collectors.counting() + )); + } + private Map analyzeModuleErrors() { + return logs.parallelStream() + .filter(log -> "ERROR".equals(log.getLevel())) + .collect(Collectors.groupingBy( + Log::getModule, + Collectors.counting() + )); + } + private List findEarliestLogs(int count) { + return logs.parallelStream() + .sorted() + .limit(count) + .collect(Collectors.toList()); + } + private void reportToServer(Map levelStats, + Map moduleErrorStats, + List earliestLogs) { + try (Socket socket = new Socket(SERVER_HOST, SERVER_PORT); + ObjectOutputStream oos = new ObjectOutputStream(socket.getOutputStream()); + ObjectInputStream ois = new ObjectInputStream(socket.getInputStream())) { + oos.writeObject(levelStats); + oos.writeObject(moduleErrorStats); + oos.writeObject(earliestLogs); + oos.flush(); + String response = (String) ois.readObject(); + System.out.println("服务器响应:" + response); + System.out.println("日志分析和上报完成"); + } catch (ConnectException e) { + System.err.println("无法连接到服务器: " + e.getMessage()); + } catch (IOException | ClassNotFoundException e) { + System.err.println("网络通信错误: " + e.getMessage()); + } + } +} \ No newline at end of file diff --git a/day02/src/com/inmind/student/吕征洋/LogServer.java b/day02/src/com/inmind/student/吕征洋/LogServer.java new file mode 100644 index 0000000..7cf50e3 --- /dev/null +++ b/day02/src/com/inmind/student/吕征洋/LogServer.java @@ -0,0 +1,46 @@ +package com.inmind.student.吕征洋; +import java.io.*; +import java.net.ServerSocket; +import java.net.Socket; +import java.util.List; +import java.util.Map; +public class LogServer { + private static final int PORT = 8080; + public static void main(String[] args) { + try (ServerSocket serverSocket = new ServerSocket(PORT)) { + System.out.println("日志服务器已启动,监听端口:" + PORT); + while (true) { + try (Socket clientSocket = serverSocket.accept(); + ObjectInputStream ois = new ObjectInputStream(clientSocket.getInputStream()); + ObjectOutputStream oos = new ObjectOutputStream(clientSocket.getOutputStream())) { + System.out.println("\n客户端连接成功:" + clientSocket.getInetAddress()); + Map levelStats = (Map) ois.readObject(); + Map moduleErrorStats = (Map) ois.readObject(); + List earliestLogs = (List) ois.readObject(); + printStats(levelStats, moduleErrorStats, earliestLogs); + oos.writeObject("上报成功"); + System.out.println("结果已返回客户端"); + } catch (ClassNotFoundException e) { + System.err.println("数据格式错误: " + e.getMessage()); + } catch (IOException e) { + System.err.println("客户端连接异常: " + e.getMessage()); + } + } + } catch (IOException e) { + System.err.println("服务器启动失败: " + e.getMessage()); + } + } + private static void printStats(Map levelStats, + Map moduleErrorStats, + List earliestLogs) { + System.out.println("\n===== 日志统计结果 ====="); + System.out.println("\n1. 按级别统计:"); + levelStats.forEach((level, count) -> + System.out.println(level + ": " + count + "条")); + System.out.println("\n2. 按模块错误统计:"); + moduleErrorStats.forEach((module, count) -> + System.out.println(module + ": " + count + "条错误")); + System.out.println("\n3. 最早的3条日志:"); + earliestLogs.forEach(System.out::println); + } +} \ No newline at end of file diff --git a/day02/src/com/inmind/student/宣智荣/Log.java b/day02/src/com/inmind/student/宣智荣/Log.java new file mode 100644 index 0000000..73af498 --- /dev/null +++ b/day02/src/com/inmind/student/宣智荣/Log.java @@ -0,0 +1,24 @@ +package com.inmind.student.宣智荣; + +import java.io.Serializable; // + +public class Log implements Serializable { // 实现序列化接口 + private long timestamp; + private String level; + private String module; + private String content; + + // 构造方法和 getter 不变 + public Log(long timestamp, String level, String module, String content) { + this.timestamp = timestamp; + this.level = level; + this.module = module; + this.content = content; + } + + // getter 方法... + public long getTimestamp() { return timestamp; } + public String getLevel() { return level; } + public String getModule() { return module; } + public String getContent() { return content; } +} \ No newline at end of file diff --git a/day02/src/com/inmind/student/宣智荣/LogClient.java b/day02/src/com/inmind/student/宣智荣/LogClient.java new file mode 100644 index 0000000..9cde14c --- /dev/null +++ b/day02/src/com/inmind/student/宣智荣/LogClient.java @@ -0,0 +1,152 @@ +package com.inmind.student.宣智荣; + + +import java.io.*; +import java.net.Socket; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.*; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.regex.Matcher; +import java.util.regex.Pattern; +import java.util.stream.Collectors; + +public class LogClient { + // 日志文件目录 + private static final String LOG_DIR = "D:\\io_test"; + // 服务器地址与端口 + private static final String SERVER_HOST = "127.0.0.1"; + private static final int SERVER_PORT = 8080; + + // 存储所有解析后的日志(线程安全的 List) + private static final List logList = Collections.synchronizedList(new ArrayList<>()); + + public static void main(String[] args) { + // 1. 获取所有 .log 文件 + File[] logFiles = getLogFiles(); + if (logFiles == null || logFiles.length == 0) { + System.err.println("未找到日志文件"); + return; + } + System.out.println("找到 " + logFiles.length + " 个日志文件,开始解析..."); + + // 2. 线程池并发解析文件 + ExecutorService executor = Executors.newFixedThreadPool(5); + for (File file : logFiles) { + executor.submit(() -> parseLogFile(file)); + } + // 关闭线程池(不再接受新任务,等待现有任务完成) + executor.shutdown(); + // 等待所有任务完成 + while (!executor.isTerminated()) { + Thread.yield(); + } + + System.out.println("日志解析完成,共解析 " + logList.size() + " 条日志"); + + // 3. 统计分析(Stream + Lambda) + Map levelCount = analyzeLevelCount(); + Map errorModuleCount = analyzeErrorModuleCount(); + List earliestLogs = findEarliestLogs(3); + + // 4. 网络上报 + try { + sendToServer(levelCount, errorModuleCount, earliestLogs); + System.out.println("日志分析和上报完成"); + } catch (IOException e) { + System.err.println("网络上报失败:" + e.getMessage()); + } + } + + // 获取目录下所有 .log 文件 + private static File[] getLogFiles() { + File dir = new File(LOG_DIR); + if (!dir.exists() || !dir.isDirectory()) { + System.err.println("日志目录不存在:" + LOG_DIR); + return null; + } + return dir.listFiles((d, name) -> name.endsWith(".log")); + } + + // 解析单个日志文件 + private static void parseLogFile(File file) { + try (BufferedReader reader = new BufferedReader(new FileReader(file))) { + String line; + // 日志格式正则:时间戳, 级别, 模块, 内容(内容可能包含逗号,简单处理) + Pattern pattern = Pattern.compile("(\\d+),(\\w+),(\\w+),(.+)"); + while ((line = reader.readLine()) != null) { + Matcher matcher = pattern.matcher(line); + if (matcher.matches()) { + try { + long timestamp = Long.parseLong(matcher.group(1)); + String level = matcher.group(2); + String module = matcher.group(3); + String content = matcher.group(4); + logList.add(new Log(timestamp, level, module, content)); + } catch (NumberFormatException e) { + System.err.println("解析日志失败(时间戳格式错误):" + line); + } + } else { + System.err.println("解析日志失败(格式不匹配):" + line); + } + } + System.out.println("解析完成:" + file.getName() + ",共 " + logList.size() + " 行"); + } catch (FileNotFoundException e) { + System.err.println("文件未找到:" + e.getMessage()); + } catch (IOException e) { + System.err.println("读取文件失败:" + e.getMessage()); + } + } + + // 按级别统计数量 + private static Map analyzeLevelCount() { + return logList.stream() + .collect(Collectors.groupingBy(Log::getLevel, Collectors.counting())); + } + + // 按模块统计 ERROR 级别日志数量 + private static Map analyzeErrorModuleCount() { + return logList.stream() + .filter(log -> "ERROR".equals(log.getLevel())) + .collect(Collectors.groupingBy(Log::getModule, Collectors.counting())); + } + + // 找出时间戳最早的 N 条日志 + private static List findEarliestLogs(int n) { + return logList.stream() + .sorted(Comparator.comparingLong(Log::getTimestamp)) + .limit(n) + .collect(Collectors.toList()); + } + + // 发送数据到服务器 + private static void sendToServer(Map levelCount, + Map errorModuleCount, + List earliestLogs) throws IOException { + try (Socket socket = new Socket(SERVER_HOST, SERVER_PORT); + ObjectOutputStream oos = new ObjectOutputStream(socket.getOutputStream()); + ObjectInputStream ois = new ObjectInputStream(socket.getInputStream())) { + + // 封装要发送的数据(简单用 Map 包含结果) + Map data = new HashMap<>(); + data.put("levelCount", levelCount); + data.put("errorModuleCount", errorModuleCount); + data.put("earliestLogs", earliestLogs); + + oos.writeObject(data); + oos.flush(); + + // 接收服务器响应:捕获 ClassNotFoundException + try { + String response = (String) ois.readObject(); + System.out.println("服务器响应:" + response); + } catch (ClassNotFoundException e) { + System.err.println("反序列化失败!找不到对应类定义,异常信息:"); + e.printStackTrace(); + } + + } + } +} \ No newline at end of file diff --git a/day02/src/com/inmind/student/宣智荣/LogServer.java b/day02/src/com/inmind/student/宣智荣/LogServer.java new file mode 100644 index 0000000..2b5f7df --- /dev/null +++ b/day02/src/com/inmind/student/宣智荣/LogServer.java @@ -0,0 +1,66 @@ +package com.inmind.student.宣智荣; + +import java.io.IOException; +import java.io.ObjectInputStream; +import java.io.ObjectOutputStream; +import java.net.ServerSocket; +import java.net.Socket; +import java.util.List; +import java.util.Map; + +public class LogServer { + private static final int PORT = 8080; + + public static void main(String[] args) { + try (ServerSocket serverSocket = new ServerSocket(PORT)) { + System.out.println("服务器启动,监听端口:" + PORT); + while (true) { + // 接受客户端连接 + Socket clientSocket = serverSocket.accept(); + System.out.println("客户端连接成功:" + clientSocket.getInetAddress()); + + // 处理客户端数据(单独线程,支持多客户端) + new Thread(() -> handleClient(clientSocket)).start(); + } + } catch (IOException e) { + System.err.println("服务器异常:" + e.getMessage()); + } + } + + private static void handleClient(Socket clientSocket) { + try (ObjectInputStream ois = new ObjectInputStream(clientSocket.getInputStream()); + ObjectOutputStream oos = new ObjectOutputStream(clientSocket.getOutputStream())) { + + // 读取客户端发送的数据 + Map data = (Map) ois.readObject(); + Map levelCount = (Map) data.get("levelCount"); + Map errorModuleCount = (Map) data.get("errorModuleCount"); + List earliestLogs = (List) data.get("earliestLogs"); + + // 打印统计结果 + System.out.println("===== 日志统计结果 ====="); + System.out.println("1. 按级别统计:"); + levelCount.forEach((level, count) -> System.out.println(level + ": " + count + " 条")); + + System.out.println("\n2. 按模块错误统计:"); + errorModuleCount.forEach((module, count) -> System.out.println(module + ": " + count + " 条错误")); + + System.out.println("\n3. 最早的 " + earliestLogs.size() + " 条日志:"); + earliestLogs.forEach(log -> + System.out.println("[" + log.getTimestamp() + "] " + log.getLevel() + " " + + log.getModule() + ": " + log.getContent()) + ); + + // 发送响应 + oos.writeObject("上报成功"); + } catch (IOException | ClassNotFoundException e) { + System.err.println("处理客户端数据失败:" + e.getMessage()); + } finally { + try { + clientSocket.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + } +} diff --git a/day02/src/com/inmind/student/张宇轩/Log.java b/day02/src/com/inmind/student/张宇轩/Log.java new file mode 100644 index 0000000..29ed923 --- /dev/null +++ b/day02/src/com/inmind/student/张宇轩/Log.java @@ -0,0 +1,31 @@ +package com.inmind.student.张宇轩; +import java.io.Serializable; + +public class Log implements Serializable, Comparable { + private final long timestamp; + private final String level; + private final String module; + private final String content; + + public Log(long timestamp, String level, String module, String content) { + this.timestamp = timestamp; + this.level = level; + this.module = module; + this.content = content; + } + + public long getTimestamp() { return timestamp; } + public String getLevel() { return level; } + public String getModule() { return module; } + public String getContent() { return content; } + + @Override + public String toString() { + return "[" + timestamp + "] " + level + " " + module + ": " + content; + } + + @Override + public int compareTo(Log other) { + return Long.compare(this.timestamp, other.timestamp); + } +} \ No newline at end of file diff --git a/day02/src/com/inmind/student/张宇轩/LogAnalyzer.java b/day02/src/com/inmind/student/张宇轩/LogAnalyzer.java new file mode 100644 index 0000000..392ae65 --- /dev/null +++ b/day02/src/com/inmind/student/张宇轩/LogAnalyzer.java @@ -0,0 +1,183 @@ +package com.inmind.student.张宇轩; + +import java.io.*; +import java.net.Socket; +import java.nio.file.DirectoryStream; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.Map; +import java.util.concurrent.*; +import java.util.regex.Pattern; +import java.util.stream.Collectors; + +public class LogAnalyzer { + private static final String LOG_DIR = "C:\\io_test"; + private static final String SERVER_HOST = "localhost"; + private static final int SERVER_PORT = 8080; + private static final Pattern LOG_PATTERN = Pattern.compile("(\\d+),(\\w+),(\\w+),(.*)"); + + private final List logs = Collections.synchronizedList(new ArrayList<>()); + private final ExecutorService executor = Executors.newFixedThreadPool(5); + + public static void main(String[] args) { + LogAnalyzer analyzer = new LogAnalyzer(); + analyzer.startAnalysis(); + } + + public void startAnalysis() { + try { + File[] logFiles = getLogFiles(); + processFilesConcurrently(logFiles); + executor.shutdown(); + if (!executor.awaitTermination(1, TimeUnit.MINUTES)) { + System.err.println("线程池未在指定时间内关闭"); + } + if (logs.isEmpty()) { + System.out.println("未找到有效日志"); + return; + } + Map levelCounts = countByLevel(); + Map moduleErrorCounts = countErrorByModule(); + List earliestLogs = findEarliestLogs(3); + sendResultsToServer(levelCounts, moduleErrorCounts, earliestLogs); + } catch (Exception e) { + System.err.println("分析失败: " + e.getMessage()); + e.printStackTrace(); + } finally { + if (!executor.isShutdown()) { + executor.shutdownNow(); + } + } + } + + private File[] getLogFiles() throws IOException { + Path dirPath = Paths.get(LOG_DIR); + if (!Files.exists(dirPath)) { + throw new FileNotFoundException("日志目录不存在: " + LOG_DIR); + } + + try (DirectoryStream stream = Files.newDirectoryStream(dirPath, "*.log")) { + List files = new ArrayList<>(); + for (Path path : stream) { + files.add(path.toFile()); + } + + if (files.isEmpty()) { + throw new FileNotFoundException("目录中没有日志文件"); + } + + System.out.println("找到 " + files.size() + " 个日志文件"); + return files.toArray(new File[0]); + } + } + + private void processFilesConcurrently(File[] files) { + List> futures = new ArrayList<>(); + + for (File file : files) { + futures.add(executor.submit(() -> { + try { + parseLogFile(file); + System.out.println("完成处理: " + file.getName()); + } catch (IOException e) { + System.err.println("处理文件出错 [" + file.getName() + "]: " + e.getMessage()); + } + })); + } + for (Future future : futures) { + try { + future.get(); + } catch (InterruptedException | ExecutionException e) { + System.err.println("任务执行异常: " + e.getMessage()); + } + } + } + + private void parseLogFile(File file) throws IOException { + try (BufferedReader reader = new BufferedReader(new FileReader(file))) { + String line; + while ((line = reader.readLine()) != null) { + try { + Log log = parseLogLine(line); + if (log != null) { + logs.add(log); + } + } catch (IllegalArgumentException e) { + System.err.println("解析失败 [" + file.getName() + "]: " + line + " | 原因: " + e.getMessage()); + } + } + } + } + + private Log parseLogLine(String line) { + if (line == null || line.trim().isEmpty()) return null; + + String[] parts = line.split(",", 4); + if (parts.length != 4) { + throw new IllegalArgumentException("日志格式错误"); + } + + try { + long timestamp = Long.parseLong(parts[0].trim()); + String level = parts[1].trim().toUpperCase(); + String module = parts[2].trim(); + String content = parts[3].trim(); + + return new Log(timestamp, level, module, content); + } catch (NumberFormatException e) { + throw new IllegalArgumentException("时间戳格式错误"); + } + } + + private Map countByLevel() { + return logs.stream() + .collect(Collectors.groupingBy( + Log::getLevel, + Collectors.counting() + )); + } + + private Map countErrorByModule() { + return logs.stream() + .filter(log -> "ERROR".equals(log.getLevel())) + .collect(Collectors.groupingBy( + Log::getModule, + Collectors.counting() + )); + } + + private List findEarliestLogs(int count) { + return logs.stream() + .sorted() + .limit(count) + .collect(Collectors.toList()); + } + + private void sendResultsToServer( + Map levelCounts, + Map moduleErrorCounts, + List earliestLogs + ) { + try (Socket socket = new Socket(SERVER_HOST, SERVER_PORT); + ObjectOutputStream out = new ObjectOutputStream(socket.getOutputStream()); + ObjectInputStream in = new ObjectInputStream(socket.getInputStream())) { + + out.writeObject(levelCounts); + out.writeObject(moduleErrorCounts); + out.writeObject(earliestLogs); + out.flush(); + + String response = (String) in.readObject(); + System.out.println("服务器响应: " + response); + + } catch (IOException e) { + System.err.println("网络通信失败: " + e.getMessage()); + } catch (ClassNotFoundException e) { + System.err.println("响应解析失败: " + e.getMessage()); + } + } +} \ No newline at end of file diff --git a/day02/src/com/inmind/student/张宇轩/LogServer.java b/day02/src/com/inmind/student/张宇轩/LogServer.java new file mode 100644 index 0000000..c92da43 --- /dev/null +++ b/day02/src/com/inmind/student/张宇轩/LogServer.java @@ -0,0 +1,59 @@ +package com.inmind.student.张宇轩; + +import java.io.IOException; +import java.io.ObjectInputStream; +import java.io.ObjectOutputStream; +import java.net.ServerSocket; +import java.net.Socket; +import java.util.List; +import java.util.Map; + +public class LogServer { + private static final int PORT = 8080; + + public static void main(String[] args) { + try (ServerSocket serverSocket = new ServerSocket(PORT)) { + System.out.println("日志服务器启动,监听端口: " + PORT); + + while (true) { + try (Socket clientSocket = serverSocket.accept(); + ObjectInputStream in = new ObjectInputStream(clientSocket.getInputStream()); + ObjectOutputStream out = new ObjectOutputStream(clientSocket.getOutputStream())) { + + Map levelCounts = (Map) in.readObject(); + Map moduleErrorCounts = (Map) in.readObject(); + List earliestLogs = (List) in.readObject(); + + printResults(levelCounts, moduleErrorCounts, earliestLogs); + + out.writeObject("上报成功"); + out.flush(); + + } catch (IOException | ClassNotFoundException e) { + System.err.println("客户端处理异常: " + e.getMessage()); + } + } + } catch (IOException e) { + System.err.println("服务器启动失败: " + e.getMessage()); + System.exit(1); + } + } + + private static void printResults( + Map levelCounts, + Map moduleErrorCounts, + List earliestLogs + ) { + System.out.println("\n===== 日志分析报告 ====="); + System.out.println("\n[级别统计]"); + levelCounts.forEach((level, count) -> + System.out.printf("%-6s: %d 条%n", level, count)); + System.out.println("\n[模块错误统计]"); + moduleErrorCounts.forEach((module, count) -> + System.out.printf("%-10s: %d 条错误%n", module, count)); + System.out.println("\n[最早的3条日志]"); + earliestLogs.forEach(System.out::println); + + System.out.println("======================\n"); + } +} \ No newline at end of file diff --git a/day02/src/com/inmind/student/张崇昊/Log.java b/day02/src/com/inmind/student/张崇昊/Log.java new file mode 100644 index 0000000..938d3b8 --- /dev/null +++ b/day02/src/com/inmind/student/张崇昊/Log.java @@ -0,0 +1,68 @@ +package com.inmind.student.张崇昊; + + + +import java.io.Serializable; + +//解析每条日志,提取时间戳(long)、级别(String)、模块(String)、内容(String)。 +public class Log implements Serializable { + + private static final long serialVersionUID = 1L; + Long timeChuo; + String level; + String moudel; + String context; + + + public Log(Long timeChuo, String level, String moudel, String context) { + this.timeChuo = timeChuo; + this.level = level; + this.moudel = moudel; + this.context = context; + } + + public Log() { + } + + public Long getTimeChuo() { + return timeChuo; + } + + public String getLevel() { + return level; + } + + public String getMoudel() { + return moudel; + } + + public String getContext() { + return context; + } + + public void setTimeChuo(Long timeChuo) { + this.timeChuo = timeChuo; + } + + public void setLevel(String level) { + this.level = level; + } + + public void setMoudel(String moudel) { + this.moudel = moudel; + } + + public void setContext(String context) { + this.context = context; + } + + @Override + public String toString() { + return "Log{" + + "timeChuo=" + timeChuo + + ", level='" + level + '\'' + + ", moudel='" + moudel + '\'' + + ", context='" + context + '\'' + + '}'; + } +} diff --git a/day02/src/com/inmind/student/张崇昊/LogAnalysisClient.java b/day02/src/com/inmind/student/张崇昊/LogAnalysisClient.java new file mode 100644 index 0000000..bdf5e41 --- /dev/null +++ b/day02/src/com/inmind/student/张崇昊/LogAnalysisClient.java @@ -0,0 +1,180 @@ +package com.inmind.student.张崇昊; +import java.io.*; +import java.net.Socket; +import java.nio.file.*; +import java.util.*; +import java.util.concurrent.*; +import java.util.stream.Collectors; + +public class LogAnalysisClient { + private static final String LOG_DIRECTORY = "C:\\Users\\21554\\Desktop\\桌面\\javaSE上机测试题内容"; + private static final String SERVER_HOST = "localhost"; + private static final int SERVER_PORT = 8080; + private List allLogs = new ArrayList<>(); + + public static void main(String[] args) { + LogAnalysisClient client = new LogAnalysisClient(); + try { + // 1. 读取并解析所有日志文件 + client.readAndParseLogs(); + + // 2. 分析日志 + Result result = client.analyzeLogs(); + + // 3. 上报结果 + client.reportResult(result); + + } catch (Exception e) { + e.printStackTrace(); + } + } + + /** + * 使用线程池并发读取并解析所有日志文件 + */ + public void readAndParseLogs() throws IOException, InterruptedException, ExecutionException { + // 获取目录下所有.log文件 + Path dirPath = Paths.get(LOG_DIRECTORY); + if (!Files.exists(dirPath) || !Files.isDirectory(dirPath)) { + throw new FileNotFoundException("日志目录不存在: " + LOG_DIRECTORY); + } + + List logFiles = Files.list(dirPath) + .filter(p -> Files.isRegularFile(p) && p.getFileName().toString().endsWith(".log")) + .collect(Collectors.toList()); + + if (logFiles.isEmpty()) { + System.out.println("没有找到日志文件"); + return; + } + + // 创建线程池 + int threadCount = Math.min(logFiles.size(), Runtime.getRuntime().availableProcessors() + 1); + ExecutorService executor = Executors.newFixedThreadPool(threadCount); + + try { + // 提交所有文件处理任务 + List> futures = new ArrayList<>(); + for (Path file : logFiles) { + futures.add(executor.submit(() -> processLogFile(file))); + } + + // 等待所有任务完成 + for (Future future : futures) { + future.get(); // 等待任务完成,会抛出异常 + } + + System.out.println("所有日志文件解析完成,共解析 " + allLogs.size() + " 条日志"); + } finally { + executor.shutdown(); // 关闭线程池 + } + } + + /** + * 处理单个日志文件,读取并解析每一行 + */ + private void processLogFile(Path file) { + try (BufferedReader reader = Files.newBufferedReader(file)) { + String line; + while ((line = reader.readLine()) != null) { + try { + Log log = parseLogLine(line); + if (log != null) { + allLogs.add(log); + } + } catch (Exception e) { + System.err.println("解析日志行失败,文件: " + file.getFileName() + ", 行内容: " + line); + System.err.println("错误信息: " + e.getMessage()); + } + } + } catch (IOException e) { + System.err.println("读取日志文件失败: " + file.getFileName()); + System.err.println("错误信息: " + e.getMessage()); + } + } + + /** + * 解析单行日志 + */ + private Log parseLogLine(String line) { + + // 分割日志行,处理可能的逗号 + String[] parts = line.split(",", 4); + + long timestamp = Long.parseLong(parts[0].trim()); + String level = parts[1].trim(); + String module = parts[2].trim(); + String content = parts[3].trim(); + + return new Log(timestamp, level, module, content); + + } + + + /** + * 分析日志数据,使用Stream和Lambda表达式 + */ + public Result analyzeLogs() { + // 1. 按级别统计日志数量 + Map levelCount = allLogs.stream() + .collect(Collectors.groupingBy(Log::getLevel, Collectors.counting())); + + // 2. 按模块统计错误日志数量 + Map moduleErrorCount = allLogs.stream() + .filter(log -> "ERROR".equals(log.getLevel())) + .collect(Collectors.groupingBy(Log::getMoudel, Collectors.counting())); + + // 3. 找出时间戳最早的3条日志 + List earliestLogs = allLogs.stream() + .sorted(Comparator.comparingLong(Log::getTimeChuo)) + .limit(3) + .collect(Collectors.toList()); + + return new Result(levelCount, moduleErrorCount, earliestLogs); + } + + /** + * 将分析结果通过Socket上报到服务器 + */ + public void reportResult(Result result) throws IOException { + Socket socket = null; + ObjectOutputStream out = null; + BufferedReader in = null; + + try { + // 连接服务器 + socket = new Socket(SERVER_HOST, SERVER_PORT); + + // 发送结果对象 + out = new ObjectOutputStream(socket.getOutputStream()); + out.writeObject(result); + out.flush(); + + // 接收服务器响应 + in = new BufferedReader(new InputStreamReader(socket.getInputStream())); + String response = in.readLine(); + System.out.println("服务器响应: " + response); + + } catch (IOException e) { + e.printStackTrace(); + + } finally { + // 释放资源 + if (in != null) { + try { + in.close(); + } catch (IOException e) { /* 忽略关闭异常 */ } + } + if (out != null) { + try { + out.close(); + } catch (IOException e) { /* 忽略关闭异常 */ } + } + if (socket != null) { + try { + socket.close(); + } catch (IOException e) { /* 忽略关闭异常 */ } + } + } + } +} \ No newline at end of file diff --git a/day02/src/com/inmind/student/张崇昊/LogAnalysisServer.java b/day02/src/com/inmind/student/张崇昊/LogAnalysisServer.java new file mode 100644 index 0000000..ba6ec6b --- /dev/null +++ b/day02/src/com/inmind/student/张崇昊/LogAnalysisServer.java @@ -0,0 +1,106 @@ +package com.inmind.student.张崇昊; + +import java.io.*; +import java.net.*; +import java.util.List; +import java.util.Map; + +/** + * 日志分析服务器,负责接收客户端上报的分析结果 + */ +public class LogAnalysisServer { + private static final int PORT = 8080; + + public static void main(String[] args) { + ServerSocket serverSocket = null; + + try { + // 创建服务器Socket并监听端口 + serverSocket = new ServerSocket(PORT); + System.out.println("服务器已启动,监听端口 " + PORT + " ..."); + + while (true) { // 循环接受客户端连接 + Socket clientSocket = serverSocket.accept(); + System.out.println("接收到客户端连接: " + clientSocket.getInetAddress()); + + // 为每个客户端连接创建一个新线程处理 + new Thread(() -> handleClient(clientSocket)).start(); + } + + } catch (IOException e) { + System.err.println("服务器启动失败: " + e.getMessage()); + e.printStackTrace(); + } finally { + if (serverSocket != null) { + try { + serverSocket.close(); + System.out.println("服务器已关闭"); + } catch (IOException e) { + System.err.println("服务器关闭失败: " + e.getMessage()); + } + } + } + } + + /** + * 处理客户端连接,接收分析结果并返回响应 + */ + private static void handleClient(Socket clientSocket) { + ObjectInputStream in = null; + PrintWriter out = null; + + try { + // 获取输入流,读取客户端发送的对象 + in = new ObjectInputStream(clientSocket.getInputStream()); + Result result = (Result) in.readObject(); + + // 打印接收的分析结果 + printAnalysisResult(result); + + // 发送响应 + out = new PrintWriter(clientSocket.getOutputStream(), true); + out.println("上报成功"); + + } catch (IOException | ClassNotFoundException e) { + System.err.println("处理客户端请求出错: " + e.getMessage()); + e.printStackTrace(); + } finally { + if (clientSocket != null) { + try { + clientSocket.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + } + } + + /** + * 打印分析结果到控制台 + */ + private static void printAnalysisResult(Result result) { + System.out.println("\n===== 接收到的日志分析结果 ====="); + + // 打印级别统计 + System.out.println("1. 各级别日志数量统计:"); + Map levelCount = result.getLevelCount(); + for (Map.Entry entry : levelCount.entrySet()) { + System.out.println(" " + entry.getKey() + ": " + entry.getValue()); + } + + // 打印模块错误统计 + System.out.println("2. 各模块错误日志数量统计:"); + Map moduleErrorCount = result.getModuleErrorCount(); + for (Map.Entry entry : moduleErrorCount.entrySet()) { + System.out.println(" " + entry.getKey() + ": " + entry.getValue()); + } + + // 打印最早的3条日志 + System.out.println("3. 时间戳最早的3条日志:"); + List earliestLogs = result.getEarliestLogs(); + for (int i = 0; i < earliestLogs.size(); i++) { + System.out.println(" " + (i + 1) + ". " + earliestLogs.get(i)); + } + + } +} \ No newline at end of file diff --git a/day02/src/com/inmind/student/张崇昊/Result.java b/day02/src/com/inmind/student/张崇昊/Result.java new file mode 100644 index 0000000..6dd96a7 --- /dev/null +++ b/day02/src/com/inmind/student/张崇昊/Result.java @@ -0,0 +1,43 @@ +package com.inmind.student.张崇昊; + +import java.io.Serializable; +import java.util.List; +import java.util.Map; + +public class Result implements Serializable { + private static final long serialVersionUID = 1L; + + private Map levelCount; + private Map moduleErrorCount; + private List earliestLogs; + + public Result(Map levelCount, Map moduleErrorCount, List earliestLogs) { + this.levelCount = levelCount; + this.moduleErrorCount = moduleErrorCount; + this.earliestLogs = earliestLogs; + } + + public Map getLevelCount() { + return levelCount; + } + + public Map getModuleErrorCount() { + return moduleErrorCount; + } + + public List getEarliestLogs() { + return earliestLogs; + } + + public void setLevelCount(Map levelCount) { + this.levelCount = levelCount; + } + + public void setModuleErrorCount(Map moduleErrorCount) { + this.moduleErrorCount = moduleErrorCount; + } + + public void setEarliestLogs(List earliestLogs) { + this.earliestLogs = earliestLogs; + } +} diff --git a/day02/src/com/inmind/student/张洁/Log.java b/day02/src/com/inmind/student/张洁/Log.java new file mode 100644 index 0000000..adadf0e --- /dev/null +++ b/day02/src/com/inmind/student/张洁/Log.java @@ -0,0 +1,35 @@ +package com.inmind.student.张洁; + +import java.io.Serializable; + +public class Log implements Serializable { + private long timetamp; + private String level; + private String module; + private String content; + + public Log(long timetamp, String level, String module, String content) { + this.timetamp = timetamp; + this.level = level; + this.module = module; + this.content = content; + } + public long getTimetamp() { + return timetamp; + } + public String getLevel() { + return level; + } + public String getModule() { + return module; + } + + public String getContent() { + return content; + } + + @Override + public String toString() { + return "["+timetamp+"] "+level+" "+module+": "+content; + } +} diff --git a/day02/src/com/inmind/student/张洁/LogAnalyzer.java b/day02/src/com/inmind/student/张洁/LogAnalyzer.java new file mode 100644 index 0000000..46d82bf --- /dev/null +++ b/day02/src/com/inmind/student/张洁/LogAnalyzer.java @@ -0,0 +1,151 @@ +package com.inmind.student.张洁; + +import java.io.*; +import java.net.Socket; +import java.nio.file.Files; +import java.nio.file.Paths; +import java.util.*; + +public class LogAnalyzer { + public static final String LOG_DIR = "D:/workspace_idea/JavaSE202507/NextDay13_test/logs/"; + private static final String serverAdd = "localhost"; + private static final int port = 8080; + + private List logs = new ArrayList(); + + private static final Object LOCK = new Object(); + + public static void main(String[] args) { + try { + if (!Files.exists(Paths.get(LOG_DIR))) { + throw new FileNotFoundException("��־Ŀ¼������" + LOG_DIR); + } + } catch (FileNotFoundException e) { + e.printStackTrace(); + } + + // ��ȡ��־�ļ��б� + File logFile = new File(LOG_DIR); + File[] files = logFile.listFiles((dir, name) -> name.endsWith(".log")); + if (files == null) { + System.out.println("δ�ҵ���־�ļ�"); + return; + } + // �����������߳� + List threads = new ArrayList<>(); + LogAnalyzer analyzer = new LogAnalyzer(); + for (File file : files) { + Thread thread = new Thread(() -> analyzer.parseLogFile(file)); + threads.add(thread); + thread.start(); + } + + for (Thread thread : threads) { + try { + thread.join(); + } catch (InterruptedException e) { + Thread.currentThread().interrupt(); + e.printStackTrace(); + } + } + + LogAnalyzer analyzer2= new LogAnalyzer(); + Map levelmap = analyzer2.levelmapCount(); + Map moduleErrorMap = analyzer2.moduleErrorCount(); + List earlistLogs = analyzer2.earlistLogsCount(); + analyzer2.sendToServer(levelmap, moduleErrorMap, earlistLogs); + } + + // ������־�ļ�����Ϊ�Ǿ�̬������ʹ�ö����� + private void parseLogFile(File file) { + try (BufferedReader br = new BufferedReader(new FileReader(file))) { + String line; + while ((line = br.readLine()) != null) { + try { + Log log = parseLogLine(line); + synchronized (LOCK) { + logs.add(log); + } + } catch (IllegalArgumentException e) { + System.out.println("������־�ļ� " + file.getName() + " �����У�" + line + "��������Ϣ��" + e.getMessage()); + } + } + } catch (IOException e) { + e.printStackTrace(); + } + } + + public static Log parseLogLine(String line) { + String[] parts = line.split(",", 4); + if (parts.length != 4) { + throw new IllegalArgumentException("��־��ʽ������Ϊ ʱ���,����,ģ��,����"); + } + + try { + long timestamp = Long.parseLong(parts[0]); + return new Log(timestamp, parts[1], parts[2], parts[3]); + } catch (NumberFormatException e) { + throw new IllegalArgumentException("ʱ�����ʽ����" + parts[0], e); + } + } + + // ������ͳ�� + public Map levelmapCount() { + HashMap hmap = new HashMap<>(); + synchronized (LOCK) { + for (Log log : logs) { + String level = log.getLevel(); + hmap.put(level, hmap.getOrDefault(level, 0) + 1); + } + } + return hmap; + } + + // ��ģ��ͳ�ƴ�����־�������߼���key Ϊģ������ + public Map moduleErrorCount() { + HashMap hmap = new HashMap<>(); + synchronized (LOCK) { + for (Log log : logs) { + if ("ERROR".equals(log.getLevel())) { + String module = log.getModule(); + hmap.put(module, hmap.getOrDefault(module, 0) + 1); + } + } + } + return hmap; + } + + // ��ȡ����� 3 ����־ + public List earlistLogsCount() { + List copy; + synchronized (LOCK) { + copy = new ArrayList<>(logs); + } + Collections.sort(copy, Comparator.comparingLong(Log::getTimetamp)); + if (copy.size() <= 3) { + return copy; + } else { + return copy.subList(0, 3); + } + } + + // �ϱ�ͳ�ƽ�� + private void sendToServer(Map levelStats, Map moduleErrorStats, List earliestLogs) { + try (Socket socket = new Socket(serverAdd, port); + ObjectOutputStream oos = new ObjectOutputStream(socket.getOutputStream()); + ObjectInputStream ois = new ObjectInputStream(socket.getInputStream())) { + + oos.writeObject(levelStats); + oos.writeObject(moduleErrorStats); + oos.writeObject(earliestLogs); + oos.flush(); + + String response = (String) ois.readObject(); + System.out.println("��������Ӧ��" + response); + + } catch (IOException | ClassNotFoundException e) { + System.out.println(e.getMessage()); + e.printStackTrace(); + } + } +} \ No newline at end of file diff --git a/day02/src/com/inmind/student/张洁/LogServer.java b/day02/src/com/inmind/student/张洁/LogServer.java new file mode 100644 index 0000000..7aac10c --- /dev/null +++ b/day02/src/com/inmind/student/张洁/LogServer.java @@ -0,0 +1,48 @@ +package com.inmind.student.张洁; + +import java.io.ObjectInputStream; +import java.io.ObjectOutputStream; +import java.net.ServerSocket; +import java.net.Socket; +import java.util.List; +import java.util.Map; + +public class LogServer { + public static final int PORT = 8080; + + public static void main(String[] args) { + try { + ServerSocket ss = new ServerSocket(PORT); + while(true){ + try{ + Socket s = ss.accept(); + ObjectInputStream ois = new ObjectInputStream(s.getInputStream()); + ObjectOutputStream oos = new ObjectOutputStream(s.getOutputStream()); + + //�������� + Map levelmap = (Map) ois.readObject(); + Map mouduleErrorMap = (Map) ois.readObject(); + List earlistLogs = (List) ois.readObject(); + + System.out.println("����ͳ�ƣ�"); + for(String key : levelmap.keySet()){ + System.out.println(key+"��"+levelmap.get(key)); + } + System.out.println("ģ�����ͳ�ƣ�"); + for(String key : mouduleErrorMap.keySet()){ + System.out.println(key+":"+mouduleErrorMap.get(key)); + } + System.out.println("����3����־��"); + for (Log earlistLog : earlistLogs) { + System.out.println(earlistLog); + } + oos.writeObject("�ϱ��ɹ�"); + }catch (Exception e){ + e.printStackTrace(); + } + } + }catch (Exception e){ + e.printStackTrace(); + } + } +} diff --git a/day02/src/com/inmind/student/张洁/Main.java b/day02/src/com/inmind/student/张洁/Main.java new file mode 100644 index 0000000..55a8229 --- /dev/null +++ b/day02/src/com/inmind/student/张洁/Main.java @@ -0,0 +1,17 @@ +package com.inmind.student.张洁; + +//TIP To Run code, press or +// click the icon in the gutter. +public class Main { + public static void main(String[] args) { + //TIP Press with your caret at the highlighted text + // to see how IntelliJ IDEA suggests fixing it. + System.out.printf("Hello and welcome!"); + + for (int i = 1; i <= 5; i++) { + //TIP Press to start debugging your code. We have set one breakpoint + // for you, but you can always add more by pressing . + System.out.println("i = " + i); + } + } +} \ No newline at end of file diff --git a/day02/src/com/inmind/student/张洁/logback.xml b/day02/src/com/inmind/student/张洁/logback.xml new file mode 100644 index 0000000..45b1f72 --- /dev/null +++ b/day02/src/com/inmind/student/张洁/logback.xml @@ -0,0 +1,41 @@ + + + + + + System.out + + + %d{yyyy-MM-dd HH:mm:ss.SSS} [%-5level] %c [%thread] : %msg%n + + + + + + + %d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + utf-8 + + + D:/log/inmind-data.log + + + + D:/log/inmind-data-%i-%d{yyyy-MM-dd}-.log.gz + + 1MB + + + + + + + + + \ No newline at end of file diff --git a/day02/src/com/inmind/student/杨靖宇/Log.java b/day02/src/com/inmind/student/杨靖宇/Log.java new file mode 100644 index 0000000..62d5502 --- /dev/null +++ b/day02/src/com/inmind/student/杨靖宇/Log.java @@ -0,0 +1,37 @@ +package com.inmind.student.杨靖宇; + +public class Log { + private long timestamp; + + private String level; + + private String module; + + private String content; + public Log(long timestamp, String level, String module, String content) { + this.timestamp = timestamp; + this.level = level; + this.module = module; + this.content = content; + } + + public long getTimestamp() { + return timestamp; + } + + public String getLevel() { + return level; + } + + public String getModule() { + return module; + } + + public String getContent() { + return content; + } + @Override + public String toString() { + return String.format("[%s] [%s] [%s] %s", timestamp, level, module, content); + } +} diff --git a/day02/src/com/inmind/student/杨靖宇/LogAnalyzer.java b/day02/src/com/inmind/student/杨靖宇/LogAnalyzer.java new file mode 100644 index 0000000..81ccb5e --- /dev/null +++ b/day02/src/com/inmind/student/杨靖宇/LogAnalyzer.java @@ -0,0 +1,227 @@ +package com.inmind.student.杨靖宇; + +import java.io.*; +import java.net.Socket; +import java.util.*; +import java.net.*; + + +public class LogAnalyzer { + private static final String LOG_DIR = "D:\\io_test"; + private static final String SERVER_HOST = "localhost"; + private static final int SERVER_PORT = 8080; + + private final List logs = Collections.synchronizedList(new ArrayList<>()); + private final List threads = new ArrayList<>(); + + public static void main(String[] args) { + LogAnalyzer analyzer = new LogAnalyzer(); + try { + analyzer.analyze(); + } catch (FileNotFoundException e) { + System.err.println("[错误] 日志目录不存在: " + e.getMessage()); + } catch (Exception e) { + System.err.println("[错误] 分析过程中出现异常: " + e.getMessage()); + e.printStackTrace(); + } + } + + public void analyze() throws FileNotFoundException { + // 1. 检查并创建日志目录 + ensureLogDirectoryExists(); + + // 2. 读取日志文件 + readLogFiles(); + + // 3. 等待所有线程完成 + waitForThreads(); + + if (logs.isEmpty()) { + System.out.println("[提示] 没有解析到任何有效日志"); + return; + } + + // 4. 统计日志数据 + Map levelStats = countByLevel(); + Map moduleErrorStats = countModuleErrors(); + List earliestLogs = getEarliestLogs(3); + + // 5. 上报统计结果 + reportToServer(levelStats, moduleErrorStats, earliestLogs); + } + + private void ensureLogDirectoryExists() throws FileNotFoundException { + File logDir = new File(LOG_DIR); + if (!logDir.exists()) { + System.out.println("[提示] 日志目录不存在,尝试创建..."); + if (!logDir.mkdirs()) { + throw new FileNotFoundException("无法创建日志目录: " + LOG_DIR); + } + System.out.println("[成功] 已创建日志目录: " + LOG_DIR); + } + } + + private void readLogFiles() throws FileNotFoundException { + File logDir = new File(LOG_DIR); + File[] logFiles = logDir.listFiles((dir, name) -> name.endsWith(".log")); + + if (logFiles == null || logFiles.length == 0) { + System.out.println("[提示] 目录中没有找到.log文件"); + return; + } + + System.out.printf("[信息] 找到 %d 个日志文件\n", logFiles.length); + + for (File file : logFiles) { + Thread thread = new Thread(() -> parseLogFile(file)); + threads.add(thread); + thread.start(); + } + } + + private void waitForThreads() { + for (Thread thread : threads) { + try { + thread.join(); + } catch (InterruptedException e) { + System.err.println("[警告] 线程等待被中断"); + Thread.currentThread().interrupt(); + break; + } + } + } + + private void parseLogFile(File file) { + System.out.printf("[信息] 开始解析文件: %s\n", file.getName()); + + try (BufferedReader reader = new BufferedReader(new FileReader(file))) { + String line; + int lineNum = 0; + int successCount = 0; + + while ((line = reader.readLine()) != null) { + lineNum++; + try { + Log log = parseLogLine(line); + logs.add(log); + successCount++; + } catch (NumberFormatException e) { + System.err.printf("[警告] %s 第 %d 行: 时间戳格式错误\n", + file.getName(), lineNum); + } catch (IllegalArgumentException e) { + System.err.printf("[警告] %s 第 %d 行: 日志格式错误\n", + file.getName(), lineNum); + } + } + + System.out.printf("[成功] 文件 %s 解析完成: 总行数 %d, 成功 %d, 失败 %d\n", + file.getName(), lineNum, successCount, lineNum - successCount); + } catch (FileNotFoundException e) { + System.err.printf("[错误] 文件不存在: %s\n", file.getPath()); + } catch (IOException e) { + System.err.printf("[错误] 读取文件 %s 失败: %s\n", file.getName(), e.getMessage()); + } + } + + private Log parseLogLine(String line) throws IllegalArgumentException, NumberFormatException { + String[] parts = line.split(",", 4); + if (parts.length != 4) { + throw new IllegalArgumentException("需要4个字段但找到" + parts.length); + } + + long timestamp = Long.parseLong(parts[0].trim()); + return new Log(timestamp, parts[1].trim(), parts[2].trim(), parts[3].trim()); + } + + private Map countByLevel() { + Map stats = new HashMap<>(); + synchronized (logs) { + for (Log log : logs) { + stats.merge(log.getLevel(), 1, Integer::sum); + } + } + return stats; + } + + private Map countModuleErrors() { + Map stats = new HashMap<>(); + synchronized (logs) { + for (Log log : logs) { + if ("ERROR".equals(log.getLevel())) { + stats.merge(log.getModule(), 1, Integer::sum); + } + } + } + return stats; + } + + private List getEarliestLogs(int count) { + List copy; + synchronized (logs) { + copy = new ArrayList<>(logs); + } + + if (copy.isEmpty()) { + return Collections.emptyList(); + } + + copy.sort(Comparator.comparingLong(Log::getTimestamp)); + return new ArrayList<>(copy.subList(0, Math.min(count, copy.size()))); + } + + private void reportToServer(Map levelStats, + Map moduleErrorStats, + List earliestLogs) { + final int maxRetries = 3; + int attempt = 0; + + while (attempt < maxRetries) { + attempt++; + try (Socket socket = new Socket()) { + // 设置连接和读取超时 + socket.connect(new InetSocketAddress(SERVER_HOST, SERVER_PORT), 5000); + socket.setSoTimeout(10000); + + try (ObjectOutputStream oos = new ObjectOutputStream(socket.getOutputStream()); + ObjectInputStream ois = new ObjectInputStream(socket.getInputStream())) { + + // 确保发送的是可序列化的ArrayList + oos.writeObject(new HashMap<>(levelStats)); + oos.writeObject(new HashMap<>(moduleErrorStats)); + oos.writeObject(new ArrayList<>(earliestLogs)); + oos.flush(); + + String response = (String) ois.readObject(); + System.out.println("[成功] 服务器响应: " + response); + return; + } + } catch (ConnectException e) { + System.err.printf("[错误] 连接失败(尝试 %d/%d): %s\n", + attempt, maxRetries, e.getMessage()); + if (attempt >= maxRetries) { + System.err.println("[错误] 达到最大重试次数,放弃连接"); + } else { + try { + Thread.sleep(1000 * attempt); + } catch (InterruptedException ie) { + Thread.currentThread().interrupt(); + return; + } + } + } catch (SocketTimeoutException e) { + System.err.println("[错误] 连接或读取超时"); + } catch (EOFException e) { + System.err.println("[错误] 连接意外中断"); + } catch (UnknownHostException e) { + System.err.println("[错误] 未知主机: " + SERVER_HOST); + break; + } catch (IOException e) { + System.err.println("[错误] 通信错误: " + e.getMessage()); + break; + } catch (ClassNotFoundException e) { + System.err.println("[错误] 协议错误: 收到未知响应类型"); + break; + } + } + } +} \ No newline at end of file diff --git a/day02/src/com/inmind/student/杨靖宇/LogServer.java b/day02/src/com/inmind/student/杨靖宇/LogServer.java new file mode 100644 index 0000000..19df3fb --- /dev/null +++ b/day02/src/com/inmind/student/杨靖宇/LogServer.java @@ -0,0 +1,79 @@ + +package com.inmind.student.杨靖宇; + +import java.io.*; +import java.net.*; +import java.util.*; + +public class LogServer { + // 定义服务器端口常量 + private static final int PORT = 8080; + + public static void main(String[] args) { + // 创建ServerSocket,监听指定端口 + try (ServerSocket serverSocket = new ServerSocket(PORT)) { + System.out.println("日志服务器已启动,正在监听端口 " + PORT + "..."); + + // 持续等待客户端连接 + while (true) { + try (Socket clientSocket = serverSocket.accept(); + ObjectInputStream ois = new ObjectInputStream(clientSocket.getInputStream()); + ObjectOutputStream oos = new ObjectOutputStream(clientSocket.getOutputStream())) { + + System.out.println("客户端连接成功: " + clientSocket.getInetAddress()); + + // 接收3类数据 + @SuppressWarnings("unchecked") + Map levelStats = (Map) ois.readObject(); + + @SuppressWarnings("unchecked") + Map moduleErrorStats = (Map) ois.readObject(); + + @SuppressWarnings("unchecked") + List earliestLogs = (List) ois.readObject(); + + // 打印统计结果 + printStatistics(levelStats, moduleErrorStats, earliestLogs); + + // 向客户端返回响应 + oos.writeObject("上报成功"); + oos.flush(); + + } catch (ClassNotFoundException e) { + System.err.println("类未找到异常: " + e.getMessage()); + } catch (IOException e) { + System.err.println("客户端连接处理异常: " + e.getMessage()); + } + } + } catch (IOException e) { + System.err.println("服务器启动异常: " + e.getMessage()); + } + } + + // 打印统计结果 + private static void printStatistics(Map levelStats, + Map moduleErrorStats, + List earliestLogs) { + System.out.println("\n=== 日志统计结果 ==="); + + // 打印级别统计 + System.out.println("\n日志级别统计:"); + for (Map.Entry entry : levelStats.entrySet()) { + System.out.println(entry.getKey() + ": " + entry.getValue() + " 条"); + } + + // 打印模块错误统计 + System.out.println("\n模块错误统计:"); + for (Map.Entry entry : moduleErrorStats.entrySet()) { + System.out.println(entry.getKey() + ": " + entry.getValue() + " 次错误"); + } + + // 打印最早的3条日志 + System.out.println("\n最早的3条日志:"); + for (Log log : earliestLogs) { + System.out.println(log); + } + + System.out.println("=== 统计结束 ===\n"); + } +} diff --git a/day02/src/com/inmind/student/狄德蓉/Log.java b/day02/src/com/inmind/student/狄德蓉/Log.java new file mode 100644 index 0000000..0267f07 --- /dev/null +++ b/day02/src/com/inmind/student/狄德蓉/Log.java @@ -0,0 +1,34 @@ +package com.inmind.student.狄德蓉; + +import java.io.Serializable; +import java.util.Objects; + +public class Log implements Serializable { + + + private long timestamp; + private String level; + private String module; + private String content; + + + public Log(long timestamp, String level, String module, String content) { + this.timestamp = timestamp; + this.level = Objects.requireNonNull(level, "日志级别不可为空"); + this.module = Objects.requireNonNull(module, "日志模块不可为空"); + this.content = Objects.requireNonNull(content, "日志内容不可为空"); + } + + + public long getTimestamp() { return timestamp; } + public String getLevel() { return level; } + public String getModule() { return module; } + public String getContent() { return content; } + + + @Override + public String toString() { + return "[" + timestamp + "] " + level + " " + module + ": " + content; + } +} + diff --git a/day02/src/com/inmind/student/狄德蓉/LogAnalyzer.java b/day02/src/com/inmind/student/狄德蓉/LogAnalyzer.java new file mode 100644 index 0000000..bc421ad --- /dev/null +++ b/day02/src/com/inmind/student/狄德蓉/LogAnalyzer.java @@ -0,0 +1,176 @@ +package com.inmind.student.狄德蓉; +import java.io.BufferedReader; +import java.io.File; +import java.io.FileReader; +import java.io.ObjectOutputStream; +import java.net.Socket; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.regex.Matcher; +import java.util.regex.Pattern; +import java.util.stream.Collectors; + + +public class LogAnalyzer { + + private static final String LOG_DIR = "D:\\io_test"; + private static final String SERVER_HOST = "localhost"; + private static final int SERVER_PORT = 8080; + + + private static final List logs = new ArrayList<>(); + + public static void main(String[] args) { + + + try { + + int fileCount = readLogFiles(); + System.out.println("找到 " + fileCount + " 个日志文件,开始解析..."); + + Map levelCountMap = countByLevel(); + Map errorModuleCountMap = countErrorByModule(); + List earliestLogs = getEarliestLogs(3); + + + reportToServer(levelCountMap, errorModuleCountMap, earliestLogs); + + System.out.println("日志分析和上报完成"); + } catch (Exception e) { + System.err.println("程序执行异常:" + e.getMessage()); + } + } + + + private static int readLogFiles() throws Exception { + File logDir = new File(LOG_DIR); + if (!logDir.exists() || !logDir.isDirectory()) { + throw new RuntimeException("日志目录不存在:" + LOG_DIR); + } + + + File[] logFiles = logDir.listFiles(file -> + file.isFile() && file.getName().endsWith(".log") + ); + + if (logFiles == null || logFiles.length == 0) { + throw new RuntimeException("日志目录中没有 .log 文件:" + LOG_DIR); + } + + + ExecutorService executor = Executors.newFixedThreadPool(logFiles.length); + + try { + for (File logFile : logFiles) { + + executor.submit(() -> parseLogFile(logFile)); + } + + + executor.shutdown(); + while (!executor.isTerminated()) { + Thread.sleep(100); + } + } finally { + + executor.shutdownNow(); + } + + System.out.println("日志解析完成,共解析 " + logs.size() + " 条日志"); + return logFiles.length; + } + + + private static void parseLogFile(File logFile) { + try (BufferedReader br = new BufferedReader(new FileReader(logFile))) { + String line; + int lineCount = 0; + + Pattern pattern = Pattern.compile( + "^(\\d+),(\\w+),(\\w+),(.*)$" + ); + + while ((line = br.readLine()) != null) { + lineCount++; + Matcher matcher = pattern.matcher(line); + if (matcher.matches()) { + try { + + long timestamp = Long.parseLong(matcher.group(1)); + String level = matcher.group(2); + String module = matcher.group(3); + String content = matcher.group(4); + + + synchronized (logs) { + logs.add(new Log(timestamp, level, module, content)); + } + } catch (Exception e) { + System.err.println("解析日志失败(跳过该行):" + line); + System.err.println(" 异常:" + e.getMessage()); + } + } else { + System.err.println("日志格式错误(跳过该行):" + line); + } + } + + System.out.println("解析完成:" + logFile.getName() + ",共 " + (lineCount-1) + " 行"); + } catch (Exception e) { + System.err.println(" 解析日志文件失败:" + logFile.getAbsolutePath()); + System.err.println(" 异常:" + e.getMessage()); + } + } + + + private static Map countByLevel() { + return logs.stream() + .collect(Collectors.groupingBy( + Log::getLevel, + Collectors.counting() + )); + } + + + private static Map countErrorByModule() { + return logs.stream() + .filter(log -> "ERROR".equals(log.getLevel())) // 只统计 ERROR 级别 + .collect(Collectors.groupingBy( + Log::getModule, + Collectors.counting() + )); + } + + + private static List getEarliestLogs(int n) { + return logs.stream() + .sorted((log1, log2) -> + Long.compare(log1.getTimestamp(), log2.getTimestamp()) + ) + .limit(n) + .collect(Collectors.toList()); + } + + + private static void reportToServer( + Map levelCountMap, + Map errorModuleCountMap, + List earliestLogs + ) throws Exception { + try ( + Socket socket = new Socket(SERVER_HOST, SERVER_PORT); + ObjectOutputStream oos = new ObjectOutputStream(socket.getOutputStream()) + ) { + + oos.writeObject(levelCountMap); + oos.writeObject(errorModuleCountMap); + oos.writeObject(earliestLogs); + + System.out.println("服务器响应:上报成功"); + } catch (Exception e) { + throw new RuntimeException("上报失败:" + e.getMessage(), e); + } + } +} \ No newline at end of file diff --git a/day02/src/com/inmind/student/狄德蓉/LogServer.java b/day02/src/com/inmind/student/狄德蓉/LogServer.java new file mode 100644 index 0000000..98d3730 --- /dev/null +++ b/day02/src/com/inmind/student/狄德蓉/LogServer.java @@ -0,0 +1,69 @@ +package com.inmind.student.狄德蓉; +import java.io.ObjectInputStream; +import java.io.ObjectOutputStream; +import java.net.ServerSocket; +import java.net.Socket; +import java.util.List; +import java.util.Map; + + +public class LogServer { + + private static final int PORT = 8080; + + public static void main(String[] args) { + try (ServerSocket serverSocket = new ServerSocket(PORT)) { + + while (true) { + try ( + Socket clientSocket = serverSocket.accept(); + ObjectInputStream ois = new ObjectInputStream(clientSocket.getInputStream()); + ObjectOutputStream oos = new ObjectOutputStream(clientSocket.getOutputStream()) + ) { + System.out.println("客户端连接成功:" + clientSocket.getInetAddress()); + + + Map levelCountMap = (Map) ois.readObject(); + Map errorModuleCountMap = (Map) ois.readObject(); + List earliestLogs = (List) ois.readObject(); + + + printStatistics(levelCountMap, errorModuleCountMap, earliestLogs); + + + } catch (Exception e) { + System.err.println("服务器处理异常:" + e.getMessage() ); + } + } + } catch (Exception e) { + System.err.println("服务器启动失败:" + e.getMessage() ); + } + } + + + private static void printStatistics( + Map levelCountMap, + Map errorModuleCountMap, + List earliestLogs + ) { + System.out.println("\n=== 日志统计结果 ==="); + + + System.out.println("1. 按级别统计:"); + levelCountMap.forEach((level, count) -> + System.out.println(" " + level + ":" + count + " 条") + ); + + + System.out.println("\n2. 按模块错误统计:"); + errorModuleCountMap.forEach((module, count) -> + System.out.println(" " + module + ":" + count + " 条错误") + ); + + + System.out.println("\n3. 最早的 3 条日志:"); + earliestLogs.forEach(log -> + System.out.println(" " + log) + ); + } +} \ No newline at end of file diff --git a/day02/src/com/inmind/student/罗康凯/Log.java b/day02/src/com/inmind/student/罗康凯/Log.java new file mode 100644 index 0000000..ebbedba --- /dev/null +++ b/day02/src/com/inmind/student/罗康凯/Log.java @@ -0,0 +1,28 @@ +package com.inmind.student.罗康凯; + +import java.io.Serializable; + +public class Log implements Serializable, Comparable { + private long timestamp; + private String level; + private String module; + private String content; + + public Log(long timestamp, String level, String module, String content) { + this.timestamp = timestamp; + this.level = level; + this.module = module; + this.content = content; + } + + // Getters + public long getTimestamp() { return timestamp; } + public String getLevel() { return level; } + public String getModule() { return module; } + public String getContent() { return content; } + + @Override + public int compareTo(Log other) { + return Long.compare(this.timestamp, other.timestamp); + } +} diff --git a/day02/src/com/inmind/student/罗康凯/LogAnalyzer.java b/day02/src/com/inmind/student/罗康凯/LogAnalyzer.java new file mode 100644 index 0000000..202d58a --- /dev/null +++ b/day02/src/com/inmind/student/罗康凯/LogAnalyzer.java @@ -0,0 +1,106 @@ +package com.inmind.student.罗康凯; + + +import java.io.*; +import java.net.*; +import java.util.*; +import java.util.concurrent.*; +import java.util.regex.*; +import java.util.stream.*; + +public class LogAnalyzer { + private static final String LOG_DIR = "C:\\Users\\30914\\IdeaProjects\\WebProject\\summerday\\S_day13\\src\\testkaoshi"; + private static final String SERVER_HOST = "localhost"; + private static final int SERVER_PORT = 8080; + private static final Pattern LOG_PATTERN = Pattern.compile("^(\\d+),(\\w+),(\\w+),(.*)$"); + + private static final List logs = Collections.synchronizedList(new ArrayList<>()); + private static final ExecutorService executor = Executors.newFixedThreadPool(5); + + public static void main(String[] args) { + try { + // 1. 读取并解析日志文件 + File[] logFiles = new File(LOG_DIR).listFiles(f -> f.getName().endsWith(".log")); + if (logFiles == null || logFiles.length == 0) { + System.out.println("未找到日志文件"); + return; + } + + // 2. 多线程处理日志文件 + List> futures = Arrays.stream(logFiles) + .map(file -> executor.submit(() -> processLogFile(file))) + .collect(Collectors.toList()); + + // 等待所有任务完成 + for (Future future : futures) { + future.get(); + } + + // 3. 统计分析 + Map levelCount = logs.stream() + .collect(Collectors.groupingBy(Log::getLevel, Collectors.counting())); + + Map moduleErrorCount = logs.stream() + .filter(log -> "ERROR".equals(log.getLevel())) +// .collect(Collectors.groupingBy(Log::getModule, Collectors.counting())); + .collect(Collectors.groupingBy(l->l.getModule(), Collectors.counting())); + + List earliestLogs = logs.stream() + .sorted() + .limit(3) + .collect(Collectors.toList()); + + // 4. 网络上报 + sendResults(levelCount, moduleErrorCount, earliestLogs); + + } catch (Exception e) { + System.err.println("处理过程中发生错误: " + e.getMessage()); + } finally { + executor.shutdown(); + } + } + + private static void processLogFile(File file) { + try (BufferedReader reader = new BufferedReader(new FileReader(file))) { + String line; + while ((line = reader.readLine()) != null) { + try { + Matcher matcher = LOG_PATTERN.matcher(line.trim()); + if (matcher.matches()) { + long timestamp = Long.parseLong(matcher.group(1)); + String level = matcher.group(2); + String module = matcher.group(3); + String content = matcher.group(4); + logs.add(new Log(timestamp, level, module, content)); + } + } catch (Exception e) { + System.err.println("解析日志行失败: " + line + ", 错误: " + e.getMessage()); + } + } + } catch (IOException e) { + System.err.println("读取文件失败: " + file.getName() + ", 错误: " + e.getMessage()); + } + } + + private static void sendResults(Map levelCount, + Map moduleErrorCount, + List earliestLogs) { + try (Socket socket = new Socket(SERVER_HOST, SERVER_PORT); + ObjectOutputStream out = new ObjectOutputStream(socket.getOutputStream()); + BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()))) { + + // 发送统计结果 + out.writeObject(levelCount); + out.writeObject(moduleErrorCount); + out.writeObject(earliestLogs); + out.flush(); + + // 接收服务器响应 + String response = in.readLine(); + System.out.println("服务器响应: " + response); + + } catch (IOException e) { + System.err.println("网络通信失败: " + e.getMessage()); + } + } +} \ No newline at end of file diff --git a/day02/src/com/inmind/student/罗康凯/LogServer.java b/day02/src/com/inmind/student/罗康凯/LogServer.java new file mode 100644 index 0000000..5e2f474 --- /dev/null +++ b/day02/src/com/inmind/student/罗康凯/LogServer.java @@ -0,0 +1,44 @@ +package com.inmind.student.罗康凯; + +import java.io.*; +import java.net.*; +import java.util.*; + +public class LogServer { + public static void main(String[] args) { + try (ServerSocket serverSocket = new ServerSocket(8080)) { + System.out.println("服务器已启动,等待客户端连接..."); + + while (true) { + try (Socket socket = serverSocket.accept(); + ObjectInputStream in = new ObjectInputStream(socket.getInputStream()); + PrintWriter out = new PrintWriter(socket.getOutputStream(), true)) { + + System.out.println("客户端已连接: " + socket.getInetAddress()); + + // 接收客户端数据 + Map levelCount = (Map) in.readObject(); + Map moduleErrorCount = (Map) in.readObject(); + List earliestLogs = (List) in.readObject(); + + // 打印统计结果 + System.out.println("\n=== 接收到的统计结果 ==="); + System.out.println("按级别统计: " + levelCount); + System.out.println("按模块错误统计: " + moduleErrorCount); + System.out.println("最早的3条日志:"); + earliestLogs.forEach(log -> System.out.printf( + "[%d] %s %s: %s%n", + log.getTimestamp(), log.getLevel(), log.getModule(), log.getContent())); + + // 发送响应 + out.println("上报成功"); + + } catch (Exception e) { + System.err.println("处理客户端请求时出错: " + e.getMessage()); + } + } + } catch (IOException e) { + System.err.println("服务器启动失败: " + e.getMessage()); + } + } +} \ No newline at end of file diff --git a/day02/src/com/inmind/student/罗康凯2/Log.java b/day02/src/com/inmind/student/罗康凯2/Log.java new file mode 100644 index 0000000..469ca10 --- /dev/null +++ b/day02/src/com/inmind/student/罗康凯2/Log.java @@ -0,0 +1,28 @@ +package com.inmind.student.罗康凯2; + +import java.io.Serializable; + +public class Log implements Serializable, Comparable { + private long timestamp; + private String level; + private String module; + private String content; + + public Log(long timestamp, String level, String module, String content) { + this.timestamp = timestamp; + this.level = level; + this.module = module; + this.content = content; + } + + // Getters + public long getTimestamp() { return timestamp; } + public String getLevel() { return level; } + public String getModule() { return module; } + public String getContent() { return content; } + + @Override + public int compareTo(Log other) { + return Long.compare(this.timestamp, other.timestamp); + } +} diff --git a/day02/src/com/inmind/student/罗康凯2/LogAnalyzer.java b/day02/src/com/inmind/student/罗康凯2/LogAnalyzer.java new file mode 100644 index 0000000..e785e05 --- /dev/null +++ b/day02/src/com/inmind/student/罗康凯2/LogAnalyzer.java @@ -0,0 +1,105 @@ +package com.inmind.student.罗康凯2; + + +import java.io.*; +import java.net.*; +import java.util.*; +import java.util.concurrent.*; +import java.util.regex.*; +import java.util.stream.*; + +public class LogAnalyzer { + private static final String LOG_DIR = "C:\\Users\\30914\\IdeaProjects\\WebProject\\summerday\\S_day13\\src\\testkaoshi"; + private static final String SERVER_HOST = "localhost"; + private static final int SERVER_PORT = 8080; + private static final Pattern LOG_PATTERN = Pattern.compile("^(\\d+),(\\w+),(\\w+),(.*)$"); + + private static final List logs = Collections.synchronizedList(new ArrayList<>()); + private static final ExecutorService executor = Executors.newFixedThreadPool(5); + + public static void main(String[] args) { + try { + // 1. 读取并解析日志文件 + File[] logFiles = new File(LOG_DIR).listFiles(f -> f.getName().endsWith(".log")); + if (logFiles == null || logFiles.length == 0) { + System.out.println("未找到日志文件"); + return; + } + + // 2. 多线程处理日志文件 + List> futures = Arrays.stream(logFiles) + .map(file -> executor.submit(() -> processLogFile(file))) + .collect(Collectors.toList()); + + // 等待所有任务完成 + for (Future future : futures) { + future.get(); + } + + // 3. 统计分析 + Map levelCount = logs.stream() + .collect(Collectors.groupingBy(Log::getLevel, Collectors.counting())); + + Map moduleErrorCount = logs.stream() + .filter(log -> "ERROR".equals(log.getLevel())) + .collect(Collectors.groupingBy(Log::getModule, Collectors.counting())); + + List earliestLogs = logs.stream() + .sorted() + .limit(3) + .collect(Collectors.toList()); + + // 4. 网络上报 + sendResults(levelCount, moduleErrorCount, earliestLogs); + + } catch (Exception e) { + System.err.println("处理过程中发生错误: " + e.getMessage()); + } finally { + executor.shutdown(); + } + } + + private static void processLogFile(File file) { + try (BufferedReader reader = new BufferedReader(new FileReader(file))) { + String line; + while ((line = reader.readLine()) != null) { + try { + Matcher matcher = LOG_PATTERN.matcher(line.trim()); + if (matcher.matches()) { + long timestamp = Long.parseLong(matcher.group(1)); + String level = matcher.group(2); + String module = matcher.group(3); + String content = matcher.group(4); + logs.add(new Log(timestamp, level, module, content)); + } + } catch (Exception e) { + System.err.println("解析日志行失败: " + line + ", 错误: " + e.getMessage()); + } + } + } catch (IOException e) { + System.err.println("读取文件失败: " + file.getName() + ", 错误: " + e.getMessage()); + } + } + + private static void sendResults(Map levelCount, + Map moduleErrorCount, + List earliestLogs) { + try (Socket socket = new Socket(SERVER_HOST, SERVER_PORT); + ObjectOutputStream out = new ObjectOutputStream(socket.getOutputStream()); + BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()))) { + + // 发送统计结果 + out.writeObject(levelCount); + out.writeObject(moduleErrorCount); + out.writeObject(earliestLogs); + out.flush(); + + // 接收服务器响应 + String response = in.readLine(); + System.out.println("服务器响应: " + response); + + } catch (IOException e) { + System.err.println("网络通信失败: " + e.getMessage()); + } + } +} \ No newline at end of file diff --git a/day02/src/com/inmind/student/罗康凯2/LogProcessor.java b/day02/src/com/inmind/student/罗康凯2/LogProcessor.java new file mode 100644 index 0000000..46e6a04 --- /dev/null +++ b/day02/src/com/inmind/student/罗康凯2/LogProcessor.java @@ -0,0 +1,133 @@ +package com.inmind.student.罗康凯2; + +import java.io.*; +import java.net.*; +import java.util.*; +import java.util.concurrent.*; +import java.util.regex.*; +import java.util.stream.Collectors; + +public class LogProcessor implements AutoCloseable { + // 配置常量 + private static final String LOG_DIR = "C:\\Users\\30914\\IdeaProjects\\WebProject\\summerday\\S_day13\\src\\testkaoshi"; + private static final String SERVER_HOST = "localhost"; + private static final int SERVER_PORT = 8080; + private static final int THREAD_POOL_SIZE = 5; + private static final Pattern LOG_PATTERN = Pattern.compile("^(\\d+),(\\w+),(\\w+),(.*)$"); + + // 线程安全集合与线程池 + private final List logs = Collections.synchronizedList(new ArrayList<>()); + private final ExecutorService executor = Executors.newFixedThreadPool(THREAD_POOL_SIZE); + + // 主处理流程 + public void process() { + try { + File[] logFiles = listLogFiles(); + if (logFiles == null || logFiles.length == 0) { + System.out.println("未找到日志文件"); + return; + } + + processFilesAsync(logFiles); + Stats stats = calculateStats(); + sendStatsToServer(stats); + } catch (Exception e) { + System.err.println("处理失败: " + e.getMessage()); + } + } + + // 获取日志文件列表 + private File[] listLogFiles() throws IOException { + File dir = new File(LOG_DIR); + if (!dir.exists()) throw new FileNotFoundException("日志目录不存在: " + LOG_DIR); + if (!dir.isDirectory()) throw new IOException("路径不是目录: " + LOG_DIR); + + File[] files = dir.listFiles(f -> f.getName().endsWith(".log")); + return files == null ? new File[0] : files; + } + + // 异步处理文件 + private void processFilesAsync(File[] files) throws InterruptedException, ExecutionException { + List> futures = Arrays.stream(files) + .map(file -> executor.submit(() -> processSingleFile(file))) + .collect(Collectors.toList()); + + // 等待所有任务完成 + for (Future future : futures) { + future.get(); + } + } + + // 处理单个日志文件 + private void processSingleFile(File file) { + try (BufferedReader reader = new BufferedReader(new FileReader(file))) { + String line; + while ((line = reader.readLine()) != null) { + parseLogLine(line.trim()); + } + } catch (IOException e) { + System.err.println("读取文件失败[" + file.getName() + "]: " + e.getMessage()); + } + } + + // 解析日志行 + private void parseLogLine(String line) { + try { + Matcher matcher = LOG_PATTERN.matcher(line); + if (matcher.matches()) { + logs.add(new Log( + Long.parseLong(matcher.group(1)), + matcher.group(2), + matcher.group(3), + matcher.group(4) + )); + } + } catch (Exception e) { + System.err.println("解析日志行失败[" + line + "]: " + e.getMessage()); + } + } + + // 计算统计结果 + private Stats calculateStats() { + Map levelCount = logs.stream() + .collect(Collectors.groupingBy(Log::getLevel, Collectors.counting())); + + Map moduleErrorCount = logs.stream() + .filter(log -> "ERROR".equals(log.getLevel())) + .collect(Collectors.groupingBy(Log::getModule, Collectors.counting())); + + List earliestLogs = logs.stream() + .sorted() + .limit(3) + .collect(Collectors.toList()); + + return new Stats(levelCount, moduleErrorCount, earliestLogs); + } + + // 发送统计结果到服务器 + private void sendStatsToServer(Stats stats) throws IOException { + try (Socket socket = new Socket(SERVER_HOST, SERVER_PORT); + ObjectOutputStream out = new ObjectOutputStream(socket.getOutputStream()); + BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()))) { + + out.writeObject(stats); + out.flush(); + System.out.println("服务器响应: " + in.readLine()); + } catch (ConnectException e) { + throw new IOException("连接服务器失败,请确保服务器已启动", e); + } + } + + // 资源释放 + @Override + public void close() { + executor.shutdown(); + } + + // 程序入口 + public static void main(String[] args) { + try (LogProcessor processor = new LogProcessor()) { + processor.process(); + } + } +} \ No newline at end of file diff --git a/day02/src/com/inmind/student/罗康凯2/LogServer.java b/day02/src/com/inmind/student/罗康凯2/LogServer.java new file mode 100644 index 0000000..4b77808 --- /dev/null +++ b/day02/src/com/inmind/student/罗康凯2/LogServer.java @@ -0,0 +1,42 @@ +package com.inmind.student.罗康凯2; + +import java.io.*; +import java.net.*; +import java.util.*; + +public class LogServer { + public static void main(String[] args) { + try (ServerSocket serverSocket = new ServerSocket(8080)) { + System.out.println("服务器已启动,等待客户端连接..."); + + while (true) { + try (Socket socket = serverSocket.accept(); + ObjectInputStream in = new ObjectInputStream(socket.getInputStream()); + PrintWriter out = new PrintWriter(socket.getOutputStream(), true)) { + System.out.println("客户端已连接: " + socket.getInetAddress()); + // 接收客户端数据 + Map levelCount = (Map) in.readObject(); + Map moduleErrorCount = (Map) in.readObject(); + List earliestLogs = (List) in.readObject(); + + // 打印统计结果 + System.out.println("\n=== 接收到的统计结果 ==="); + System.out.println("按级别统计: " + levelCount); + System.out.println("按模块错误统计: " + moduleErrorCount); + System.out.println("最早的3条日志:"); + earliestLogs.forEach(log -> System.out.printf( + "[%d] %s %s: %s%n", + log.getTimestamp(), log.getLevel(), log.getModule(), log.getContent())); + + // 发送响应 + out.println("上报成功"); + + } catch (Exception e) { + System.err.println("处理客户端请求时出错: " + e.getMessage()); + } + } + } catch (IOException e) { + System.err.println("服务器启动失败: " + e.getMessage()); + } + } +} \ No newline at end of file diff --git a/day02/src/com/inmind/student/罗康凯2/LogServer2.java b/day02/src/com/inmind/student/罗康凯2/LogServer2.java new file mode 100644 index 0000000..8cc96b4 --- /dev/null +++ b/day02/src/com/inmind/student/罗康凯2/LogServer2.java @@ -0,0 +1,39 @@ +package com.inmind.student.罗康凯2; + +import java.io.*; +import java.net.*; + +public class LogServer2 { + public static void main(String[] args) { + try (ServerSocket serverSocket = new ServerSocket(8080)) { + System.out.println("服务器已启动,监听端口8080..."); + + while (true) { + try (Socket socket = serverSocket.accept(); + ObjectInputStream in = new ObjectInputStream(socket.getInputStream()); + PrintWriter out = new PrintWriter(socket.getOutputStream(), true)) { + + Stats stats = (Stats) in.readObject(); + printStats(stats); + out.println("上报成功"); + } catch (Exception e) { + System.err.println("处理客户端请求异常: " + e.getMessage()); + } + } + } catch (IOException e) { + System.err.println("服务器启动失败: " + e.getMessage()); + } + } + + // 打印统计结果 + private static void printStats(Stats stats) { + System.out.println("\n=== 接收到统计结果 ==="); + System.out.println("级别统计: " + stats.getLevelCount()); + System.out.println("模块错误统计: " + stats.getModuleErrorCount()); + System.out.println("最早3条日志:"); + stats.getEarliestLogs().forEach(log -> + System.out.printf("[%d] %s-%s: %s%n", + log.getTimestamp(), log.getLevel(), log.getModule(), log.getContent()) + ); + } +} \ No newline at end of file diff --git a/day02/src/com/inmind/student/罗康凯2/Stats.java b/day02/src/com/inmind/student/罗康凯2/Stats.java new file mode 100644 index 0000000..2fa0f23 --- /dev/null +++ b/day02/src/com/inmind/student/罗康凯2/Stats.java @@ -0,0 +1,23 @@ +package com.inmind.student.罗康凯2; + +import java.io.Serializable; +import java.util.List; +import java.util.Map; + +// 统计结果封装类 +public class Stats implements Serializable { + private final Map levelCount; + private final Map moduleErrorCount; + private final List earliestLogs; + + public Stats(Map levelCount, Map moduleErrorCount, List earliestLogs) { + this.levelCount = levelCount; + this.moduleErrorCount = moduleErrorCount; + this.earliestLogs = earliestLogs; + } + + // Getter方法 + public Map getLevelCount() { return levelCount; } + public Map getModuleErrorCount() { return moduleErrorCount; } + public List getEarliestLogs() { return earliestLogs; } +} \ No newline at end of file diff --git a/day02/src/com/inmind/student/金雯欣/Log.java b/day02/src/com/inmind/student/金雯欣/Log.java new file mode 100644 index 0000000..3e9b194 --- /dev/null +++ b/day02/src/com/inmind/student/金雯欣/Log.java @@ -0,0 +1,37 @@ +package com.inmind.student.金雯欣; + + +import java.io.Serializable; + +public class Log implements Serializable { + private static final long serialVersionUID = 1L; + // 日志时间戳(毫秒级) + private final long timestamp; + // 日志级别(如 ERROR、INFO 等) + private final String level; + // 日志所属模块(如 Payment、User 等) + private final String module; + // 日志具体内容 + private final String content; + + // 带参构造方法 + public Log(long timestamp, String level, String module, String content) { + this.timestamp = timestamp; + this.level = level; + this.module = module; + this.content = content; + } + + // Getter 方法(日志属性创建后不可修改,无需 Setter) + public long getTimestamp() { return timestamp; } + public String getLevel() { return level; } + public String getModule() { return module; } + public String getContent() { return content; } + + // 重写 toString,方便日志内容打印(格式:[时间戳] 级别 模块: 内容) + @Override + public String toString() { + return "[" + timestamp + "] " + level + " " + module + ": " + content; + } +} + diff --git a/day02/src/com/inmind/student/金雯欣/LogAnalyzer.java b/day02/src/com/inmind/student/金雯欣/LogAnalyzer.java new file mode 100644 index 0000000..2d30cd6 --- /dev/null +++ b/day02/src/com/inmind/student/金雯欣/LogAnalyzer.java @@ -0,0 +1,159 @@ +package com.inmind.student.金雯欣; + +import java.io.BufferedReader; +import java.io.File; +import java.io.FileReader; +import java.io.IOException; +import java.io.ObjectOutputStream; +import java.net.Socket; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.regex.Pattern; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.stream.Collectors; +import java.util.Comparator; + +public class LogAnalyzer { + // 日志文件目录(题目要求:D:\\io_test) + private static final String LOG_DIR = "D:\\io_test"; + // 服务器地址(本地测试) + private static final String SERVER_HOST = "127.0.0.1"; + // 服务器端口 + private static final int SERVER_PORT = 8080; + + // 存储解析后的日志(通过 synchronized 保证线程安全) + private List logs = new ArrayList<>(); + + public static void main(String[] args) { + LogAnalyzer analyzer = new LogAnalyzer(); + try { + // 1. 多线程读取并解析日志 + analyzer.readAndParseLogs(); + // 2. 统计分析 + Map levelStats = analyzer.analyzeByLevel(); + Map moduleErrorStats = analyzer.analyzeErrorByModule(); + List top3Logs = analyzer.findTop3EarlyLogs(); + + // 3. 网络上报 + analyzer.reportToServer(levelStats, moduleErrorStats, top3Logs); + + System.out.println("日志分析和上报完成"); + } catch (IOException e) { + System.err.println("客户端执行异常: " + e.getMessage()); + } + } + + // 多线程读取并解析日志文件(使用线程池) + private void readAndParseLogs() throws IOException { + File dir = new File(LOG_DIR); + if (!dir.exists() || !dir.isDirectory()) { + throw new IOException("日志目录不存在: " + LOG_DIR); + } + + // 筛选 .log 后缀的文件 + File[] logFiles = dir.listFiles(file -> file.getName().endsWith(".log")); + if (logFiles == null || logFiles.length == 0) { + System.err.println("目录中无 .log 日志文件: " + LOG_DIR); + return; + } + + // 创建线程池(题目要求:Executors.newFixedThreadPool(5)) + ExecutorService executor = Executors.newFixedThreadPool(5); + for (File file : logFiles) { + // 提交文件解析任务 + executor.submit(() -> parseLogFile(file)); + } + // 关闭线程池(不再接受新任务,等待现有任务完成) + executor.shutdown(); + while (!executor.isTerminated()) { + // 等待任务完成 + Thread.yield(); + } + + System.out.println("日志解析完成,共解析 " + logs.size() + " 条日志"); + } + + // 解析单个日志文件(线程任务) + private void parseLogFile(File file) { + // try-with-resources 自动关闭流 + try (BufferedReader br = new BufferedReader(new FileReader(file))) { + String line; + int lineNum = 0; + // 正则匹配日志格式:时间戳,级别,模块,内容(内容可能包含逗号,需限制分割) + Pattern pattern = Pattern.compile("^\\d+,\\w+,\\w+,.*$"); + while ((line = br.readLine()) != null) { + lineNum++; + try { + if (!pattern.matcher(line).matches()) { + throw new IllegalArgumentException("日志格式错误"); + } + // 分割日志(限制分割为4部分,保留内容中的逗号) + String[] parts = line.split(",", 4); + if (parts.length != 4) { + throw new IllegalArgumentException("日志字段数量错误"); + } + + long timestamp = Long.parseLong(parts[0]); + String level = parts[1].trim(); + String module = parts[2].trim(); + String content = parts[3].trim(); + + // 线程安全地添加到 logs(synchronized 保证) + synchronized (this) { + logs.add(new Log(timestamp, level, module, content)); + } + } catch (IllegalArgumentException e) { + System.err.println("解析文件 " + file.getName() + + " 第" + lineNum + "行失败: " + e.getMessage()); + } + } + System.out.println("解析完成: " + file.getName() + ",共 " + lineNum + " 行"); + } catch (IOException e) { + System.err.println("读取文件 " + file.getName() + " 失败: " + e.getMessage()); + } + } + + // 按级别统计日志数量(Stream + Lambda) + private Map analyzeByLevel() { + return logs.stream() + .collect(Collectors.groupingBy(Log::getLevel, Collectors.counting())); + } + + // 按模块统计错误日志(级别为 ERROR)数量(Stream + Lambda) + private Map analyzeErrorByModule() { + return logs.stream() + .filter(log -> "ERROR".equals(log.getLevel())) + .collect(Collectors.groupingBy(Log::getModule, Collectors.counting())); + } + + // 找出时间戳最早的3条日志 + private List findTop3EarlyLogs() { + return logs.stream() + .sorted(Comparator.comparingLong(Log::getTimestamp)) + .limit(3) + .collect(Collectors.toList()); + } + + // 通过 Socket 上报统计结果到服务器 + private void reportToServer(Map levelStats, + Map moduleErrorStats, + List top3Logs) throws IOException { + // try-with-resources 自动关闭 Socket + try (Socket socket = new Socket(SERVER_HOST, SERVER_PORT); + ObjectOutputStream oos = new ObjectOutputStream(socket.getOutputStream())) { + + // 发送统计结果 + oos.writeObject(levelStats); + oos.writeObject(moduleErrorStats); + oos.writeObject(top3Logs); + + // 接收响应 + String response = (String) new java.io.ObjectInputStream(socket.getInputStream()).readObject(); + System.out.println("服务器响应: " + response); + } catch (ClassNotFoundException e) { + System.err.println("解析服务器响应异常: " + e.getMessage()); + } + } +} diff --git a/day02/src/com/inmind/student/金雯欣/LogServer.java b/day02/src/com/inmind/student/金雯欣/LogServer.java new file mode 100644 index 0000000..d53a205 --- /dev/null +++ b/day02/src/com/inmind/student/金雯欣/LogServer.java @@ -0,0 +1,66 @@ +package com.inmind.student.金雯欣; + +import java.io.IOException; +import java.io.ObjectInputStream; +import java.io.ObjectOutputStream; +import java.net.ServerSocket; +import java.net.Socket; +import java.util.List; +import java.util.Map; + +public class LogServer { + // 服务器监听端口 + private static final int PORT = 8080; + + public static void main(String[] args) { + // try-with-resources 自动关闭 ServerSocket + try (ServerSocket serverSocket = new ServerSocket(PORT)) { + System.out.println("服务器启动,监听端口: " + PORT); + while (true) { + // 等待客户端连接 + Socket clientSocket = serverSocket.accept(); + System.out.println("客户端连接成功: " + clientSocket.getInetAddress()); + + // 处理客户端连接(try-with-resources 处理流) + try (ObjectInputStream ois = new ObjectInputStream(clientSocket.getInputStream()); + ObjectOutputStream oos = new ObjectOutputStream(clientSocket.getOutputStream())) { + + // 接收统计结果 + Map levelStats = (Map) ois.readObject(); + Map moduleErrorStats = (Map) ois.readObject(); + List top3Logs = (List) ois.readObject(); + + // 打印统计结果 + printStats(levelStats, moduleErrorStats, top3Logs); + + // 返回响应 + oos.writeObject("上报成功"); + } catch (ClassNotFoundException | IOException e) { + System.err.println("服务器处理客户端数据异常: " + e.getMessage()); + } + } + } catch (IOException e) { + System.err.println("服务器启动失败: " + e.getMessage()); + } + } + + // 按格式打印统计结果到控制台 + private static void printStats(Map levelStats, + Map moduleErrorStats, + List top3Logs) { + System.out.println("\n===== 日志统计结果 ====="); + // 打印级别统计 + System.out.println("1. 按级别统计:"); + levelStats.forEach((level, count) -> + System.out.println(level + ": " + count + "条")); + + // 打印模块错误统计 + System.out.println("\n2. 按模块错误统计:"); + moduleErrorStats.forEach((module, count) -> + System.out.println(module + ": " + count + "条错误")); + + // 打印最早3条日志 + System.out.println("\n3. 最早的3条日志:"); + top3Logs.forEach(System.out::println); + } +} diff --git a/day02/src/com/inmind/student/陈家芮/Log.java b/day02/src/com/inmind/student/陈家芮/Log.java new file mode 100644 index 0000000..09ed49e --- /dev/null +++ b/day02/src/com/inmind/student/陈家芮/Log.java @@ -0,0 +1,38 @@ +package com.inmind.student.陈家芮; + +import java.io.Serializable; + +public class Log implements Serializable, Comparable { + private final long timestamp; + private final String level; + private final String module; + private final String content; + + public Log(long timestamp, String level, String module, String content) { + this.timestamp = timestamp; + this.level = level; + this.module = module; + this.content = content; + } + + // Getters + public long getTimestamp() { return timestamp; } + public String getLevel() { return level; } + public String getModule() { return module; } + public String getContent() { return content; } + + @Override + public int compareTo(Log other) { + return Long.compare(this.timestamp, other.timestamp); + } + + @Override + public String toString() { + return "Log{" + + "timestamp=" + timestamp + + ", level='" + level + '\'' + + ", module='" + module + '\'' + + ", content='" + content + '\'' + + '}'; + } +} \ No newline at end of file diff --git a/day02/src/com/inmind/student/陈家芮/LogAnalyzer.java b/day02/src/com/inmind/student/陈家芮/LogAnalyzer.java new file mode 100644 index 0000000..6c2f470 --- /dev/null +++ b/day02/src/com/inmind/student/陈家芮/LogAnalyzer.java @@ -0,0 +1,164 @@ +package com.inmind.student.陈家芮; + +import java.io.*; +import java.net.Socket; +import java.nio.file.*; +import java.util.*; +import java.util.concurrent.*; +import java.util.regex.*; +import java.util.stream.*; + +public class LogAnalyzer { + private static final String LOG_DIR = "D:\\io_test"; + private static final String LOG_FILE_PATTERN = ".*\\.log$"; + private static final Pattern LOG_LINE_PATTERN = + Pattern.compile("^(\\d+),(\\w+),(\\w+),(.*)$"); + private static final String SERVER_HOST = "localhost"; + private static final int SERVER_PORT = 8080; + + private final List allLogs = Collections.synchronizedList(new ArrayList<>()); + private final ExecutorService executor = Executors.newFixedThreadPool(5); + + public static void main(String[] args) { + LogAnalyzer analyzer = new LogAnalyzer(); + try { + analyzer.processLogs(); + } catch (Exception e) { + System.err.println("Error processing logs: " + e.getMessage()); + e.printStackTrace(); + } finally { + analyzer.shutdown(); + } + } + + public void processLogs() throws InterruptedException { + // 1. 读取并解析日志文件 + readAndParseLogFiles(); + + // 2. 统计分析 + Map levelCounts = countLogsByLevel(); + Map moduleErrorCounts = countErrorLogsByModule(); + List earliestLogs = findEarliestLogs(3); + + // 3. 打印统计结果(可选) + printStatistics(levelCounts, moduleErrorCounts, earliestLogs); + + // 4. 上报结果到服务器 + reportToServer(levelCounts, moduleErrorCounts, earliestLogs); + } + + private void readAndParseLogFiles() throws InterruptedException { + try { + File[] logFiles = Paths.get(LOG_DIR).toFile() + .listFiles((dir, name) -> name.matches(LOG_FILE_PATTERN)); + + if (logFiles == null || logFiles.length == 0) { + System.out.println("No log files found in directory: " + LOG_DIR); + return; + } + + List> futures = new ArrayList<>(); + for (File file : logFiles) { + futures.add(executor.submit(() -> parseLogFile(file))); + } + + // 等待所有任务完成 + for (Future future : futures) { + future.get(); + } + } catch (ExecutionException e) { + System.err.println("Error processing log files: " + e.getCause().getMessage()); + } + } + + private void parseLogFile(File file) { + try (BufferedReader reader = new BufferedReader(new FileReader(file))) { + String line; + while ((line = reader.readLine()) != null) { + try { + Matcher matcher = LOG_LINE_PATTERN.matcher(line.trim()); + if (matcher.matches()) { + long timestamp = Long.parseLong(matcher.group(1)); + String level = matcher.group(2); + String module = matcher.group(3); + String content = matcher.group(4); + allLogs.add(new Log(timestamp, level, module, content)); + } + } catch (Exception e) { + System.err.println("Failed to parse line: " + line + " in file: " + file.getName()); + } + } + } catch (IOException e) { + System.err.println("Error reading file: " + file.getName() + " - " + e.getMessage()); + } + } + + private Map countLogsByLevel() { + return allLogs.stream() + .collect(Collectors.groupingBy(Log::getLevel, Collectors.counting())); + } + + private Map countErrorLogsByModule() { + return allLogs.stream() + .filter(log -> "ERROR".equals(log.getLevel())) + .collect(Collectors.groupingBy(Log::getModule, Collectors.counting())); + } + + private List findEarliestLogs(int count) { + return allLogs.stream() + .sorted() + .limit(count) + .collect(Collectors.toList()); + } + + private void printStatistics(Map levelCounts, + Map moduleErrorCounts, + List earliestLogs) { + System.out.println("\n=== 日志统计结果 ==="); + System.out.println("按级别统计:"); + levelCounts.forEach((level, count) -> System.out.printf("%s: %d%n", level, count)); + + System.out.println("\n按模块统计错误日志:"); + moduleErrorCounts.forEach((module, count) -> System.out.printf("%s: %d%n", module, count)); + + System.out.println("\n最早的3条日志:"); + earliestLogs.forEach(System.out::println); + } + + private void reportToServer(Map levelCounts, + Map moduleErrorCounts, + List earliestLogs) { + try (Socket socket = new Socket(SERVER_HOST, SERVER_PORT); + ObjectOutputStream out = new ObjectOutputStream(socket.getOutputStream()); + ObjectInputStream in = new ObjectInputStream(socket.getInputStream())) { + + // 创建结果对象 + Map result = new HashMap<>(); + result.put("levelCounts", levelCounts); + result.put("moduleErrorCounts", moduleErrorCounts); + result.put("earliestLogs", earliestLogs); + + // 发送结果 + out.writeObject(result); + out.flush(); + + // 接收服务器响应 + String response = (String) in.readObject(); + System.out.println("\n服务器响应: " + response); + } catch (IOException | ClassNotFoundException e) { + System.err.println("Error reporting to server: " + e.getMessage()); + } + } + + public void shutdown() { + executor.shutdown(); + try { + if (!executor.awaitTermination(5, TimeUnit.SECONDS)) { + executor.shutdownNow(); + } + } catch (InterruptedException e) { + executor.shutdownNow(); + Thread.currentThread().interrupt(); + } + } +} diff --git a/day02/src/com/inmind/student/陈家芮/Server.java b/day02/src/com/inmind/student/陈家芮/Server.java new file mode 100644 index 0000000..fd44a5c --- /dev/null +++ b/day02/src/com/inmind/student/陈家芮/Server.java @@ -0,0 +1,64 @@ +package com.inmind.student.陈家芮; +import java.io.*; +import java.net.*; +import java.util.*; +/** + * ClassName:Server + * + * @author: karoy + * @Date: 2025/8/13 + * @Description: + * @version: 1.0 + */ +public class Server { + public static void main(String[] args) { + try (ServerSocket serverSocket = new ServerSocket(8080)) { + System.out.println("日志服务器启动,监听端口 8080..."); + + while (true) { + try (Socket clientSocket = serverSocket.accept(); + ObjectInputStream in = new ObjectInputStream(clientSocket.getInputStream()); + ObjectOutputStream out = new ObjectOutputStream(clientSocket.getOutputStream())) { + + System.out.println("\n接收到客户端连接: " + clientSocket.getInetAddress()); + + // 接收客户端数据 + @SuppressWarnings("unchecked") + Map result = (Map) in.readObject(); + + // 打印统计结果 + printResults(result); + + // 发送响应 + out.writeObject("上报成功"); + out.flush(); + } catch (IOException | ClassNotFoundException e) { + System.err.println("处理客户端请求时出错: " + e.getMessage()); + } + } + } catch (IOException e) { + System.err.println("无法启动服务器: " + e.getMessage()); + } + } + + private static void printResults(Map result) { + @SuppressWarnings("unchecked") + Map levelCounts = (Map) result.get("levelCounts"); + + @SuppressWarnings("unchecked") + Map moduleErrorCounts = (Map) result.get("moduleErrorCounts"); + + @SuppressWarnings("unchecked") + List earliestLogs = (List) result.get("earliestLogs"); + + System.out.println("\n=== 接收到的日志统计 ==="); + System.out.println("按级别统计:"); + levelCounts.forEach((level, count) -> System.out.printf("%s: %d%n", level, count)); + + System.out.println("\n按模块统计错误日志:"); + moduleErrorCounts.forEach((module, count) -> System.out.printf("%s: %d%n", module, count)); + + System.out.println("\n最早的3条日志:"); + earliestLogs.forEach(System.out::println); + } +} diff --git a/day02/src/com/inmind/student/陈桐/LogAnalyzer.java b/day02/src/com/inmind/student/陈桐/LogAnalyzer.java new file mode 100644 index 0000000..3c45553 --- /dev/null +++ b/day02/src/com/inmind/student/陈桐/LogAnalyzer.java @@ -0,0 +1,104 @@ +package com.inmind.student.陈桐; + +import java.io.*; +import java.net.ConnectException; +import java.net.Socket; +import java.net.SocketException; +import java.util.ArrayList; +import java.util.List; + +public class LogAnalyzer { + //定义日志目录LOG_DIR = "logs/"、服务器地址和端口 + // 日志目录(确保目录以斜杠结尾,方便拼接文件路径) + public static final String LOG_DIR = "E:\\workspace_idea\\Java_Advanced\\Day13_Test\\Log/"; + + // 服务器地址(localhost表示本地,可根据需要修改为具体IP) + public static final String SERVER_HOST = "localhost"; + + // 服务器端口(建议使用1024以上的端口,避免与系统端口冲突) + public static final int SERVER_PORT = 8080; + + //声明日志集合private List logs = new ArrayList<>()(非线程安全,后续通过同步机制保证安全) + private List logs = new ArrayList<>(); + + + public void readLogFiles() throws FileNotFoundException, InterruptedException { + // 检查日志目录是否存在 + File logDirectory = new File(LOG_DIR); + if (!logDirectory.exists() || !logDirectory.isDirectory()) { + throw new FileNotFoundException("日志目录不存在: " + LOG_DIR); + } + + // 获取.log后缀的日志文件列表 + File[] logFiles = logDirectory.listFiles((log, name) -> + name.endsWith(".log") + ); + + if (logFiles == null || logFiles.length == 0) { + System.out.println("日志目录中没有找到.log文件"); + return; + } + + // 存储所有线程的列表 + List threadList = new ArrayList<>(); + + // 为每个日志文件创建并启动线程 + for (File logFile : logFiles) { + Thread thread = new Thread(() -> { + try { + parseLogFile(logFile); + } catch (IOException e) { + throw new RuntimeException(e); + } + }); + threadList.add(thread); + thread.start(); + } + + // 等待所有线程执行完毕 + for (Thread thread : threadList) { + thread.join(); + } + + System.out.println("所有日志文件解析完成,共解析 " + logFiles.length + " 条日志"); + } + + private void parseLogFile(File logFile) throws IOException { + System.out.println("开始解析日志文件: " + logFile.getName() + ",线程: " + Thread.currentThread().getName()); + + // 使用try-with-resources自动关闭资源 + try (BufferedReader reader = new BufferedReader(new FileReader(logFile)); + Socket socket = new Socket(SERVER_HOST, SERVER_PORT); + BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()))) { + + String line; + while ((line = reader.readLine()) != null) { + writer.write(line); + writer.newLine(); // 确保每行有换行符,便于服务器解析 + writer.flush(); // 立即发送数据 + } + System.out.println("日志文件解析完成: " + logFile.getName()); + + } catch (FileNotFoundException e) { + System.err.println("日志文件不存在: " + logFile.getName() + ",错误: " + e.getMessage()); + } catch (ConnectException e) { + System.err.println("无法连接到服务器 " + SERVER_HOST + ":" + SERVER_PORT + ",错误: " + e.getMessage()); + } catch (SocketException e) { + System.err.println("网络连接异常,文件: " + logFile.getName() + ",错误: " + e.getMessage()); + } catch (IOException e) { + System.err.println("IO操作异常,文件: " + logFile.getName() + ",错误: " + e.getMessage()); + } + } + + public static void main(String[] args) { + LogAnalyzer reader = new LogAnalyzer(); + try { + reader.readLogFiles(); + } catch (FileNotFoundException e) { + System.err.println("错误: " + e.getMessage()); + } catch (InterruptedException e) { + System.err.println("线程等待被中断: " + e.getMessage()); + Thread.currentThread().interrupt(); + } + } +} diff --git a/day02/src/com/inmind/student/陈桐/LogServe.java b/day02/src/com/inmind/student/陈桐/LogServe.java new file mode 100644 index 0000000..4b3f210 --- /dev/null +++ b/day02/src/com/inmind/student/陈桐/LogServe.java @@ -0,0 +1,131 @@ +package com.inmind.student.陈桐; + +import java.io.*; +import java.net.ServerSocket; +import java.net.Socket; +import java.util.ArrayList; +import java.util.Comparator; +import java.util.HashMap; +import java.util.Map; + +/* +定义服务器端口常量PORT = 8080 +在main方法中创建ServerSocket,监听指定端口 +使用while(true)循环持续等待客户端连接 +客户端连接后,通过ObjectInputStream接收 3 类数据: +级别统计 Map(Map) +模块错误统计 Map(Map) +最早的 3 条日志(List) +遍历接收的 Map 和 List,按格式打印统计结果到控制台 +通过ObjectOutputStream向客户端返回 "上报成功" 响应 +使用try-with-resources自动关闭ServerSocket、Socket和流资源 +捕获并处理IOException等异常,确保服务器稳定运行 + */ +public class LogServe { + public static void main(String[] args) throws IOException { + System.out.println("服务器启动"); + //在main方法中创建ServerSocket,监听指定端口 + ServerSocket serverSocket = new ServerSocket(8080); + HashMap levelMap = new HashMap<>(); + levelMap.put("ERROR", 0); + levelMap.put("INFO", 0); + levelMap.put("WARNING", 0); + levelMap.put("DEBUG", 0); + HashMap errMap = new HashMap<>(); + errMap.put("SystemModule", 0); + errMap.put("PaymentGateway",0); + errMap.put("DatabaseModule",0); + + ArrayList list = new ArrayList<>(); + + //使用while(true)循环持续等待客户端连接 + int count = 0; + while (true) { + try (Socket socket = serverSocket.accept(); + BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream())); + OutputStream os = socket.getOutputStream()) { + //客户端连接后,通过ObjectInputStream接收 3 类数据 + String msg; + while ((msg = br.readLine()) != null) { + String[] split = msg.split(","); + if(split.length != 5 || !levelMap.containsKey(split[1]) || !errMap.containsKey(split[2])){ + // 创建日志对象 + MyLog log = new MyLog(Long.parseLong(split[0]), split[1], split[2], split[3]); + // 创建level集合 + getLeveMap(split, levelMap, msg); + // 创建err集合 + getErrMap(split, errMap, msg); + list.add(log); + }else{ + throw new IllegalArgumentException("不符合日志格式"); + } + + } + + // 遍历接收的 Map 和 List,按格式打印统计结果到控制台 + System.out.println(socket.getLocalAddress()+"已成功连接客户端"); + System.out.println("======日志统计结果====="); + + System.out.println("1.按级别统计结果"); + for(Map.Entry entry: levelMap.entrySet()) { + System.out.println(entry.getKey() + " : " + entry.getValue()); + } + + System.out.println("2.按模块错误统计"); + for(Map.Entry entry: errMap.entrySet()) { + System.out.println(entry.getKey() + " : " + entry.getValue()); + } + + System.out.println("3.最早的三条日志"); + list.sort(new Comparator() { + + @Override + public int compare(MyLog o1, MyLog o2) { + return Long.compare(o1.getTimestamp(),o2.getTimestamp()); + } + }); + int count2 = 0; + for (MyLog log : list) { + if(count2 < 3){ + System.out.println(log.toString()); + } + count2++; + } + + // 通过OutputStream向客户端返回 "上报成功" 响应 + os.write("上报成功".getBytes()); + os.flush(); // 确保数据被发送出去 + + } catch (IOException e) { + e.printStackTrace(); + } + } + } + + + + private static void getErrMap(String[] split, HashMap errMap, String msg) { + if (split[2].equals("SystemModule")) { + errMap.put("SystemModule", errMap.get("SystemModule")+1); + } + if (split[2].equals("PaymentGateway")) { + errMap.put("PaymentGateway", errMap.get("PaymentGateway")+1); + } + if (split[2].equals("DatabaseModule")) { + errMap.put("DatabaseModule", errMap.get("DatabaseModule")+1); + } + } + + private static void getLeveMap(String[] split, HashMap levelMap, String msg) { + if (split[1].equals("ERROR")) { + levelMap.put("ERROR", levelMap.get("ERROR")+1); + }else if (split[1].equals("INFO")) { + levelMap.put("INFO", levelMap.get("INFO")+1); + }else if (split[1].equals("WARNING")) { + levelMap.put("WARNING", levelMap.get("WARNING")+1); + } else if (split[1].equals("DEBUG")) { + levelMap.put("DEBUG", levelMap.get("DEBUG")+1); + } + + } +} diff --git a/day02/src/com/inmind/student/陈桐/MyLog.java b/day02/src/com/inmind/student/陈桐/MyLog.java new file mode 100644 index 0000000..b44431a --- /dev/null +++ b/day02/src/com/inmind/student/陈桐/MyLog.java @@ -0,0 +1,54 @@ +package com.inmind.student.陈桐; + +import java.io.Serializable; + +/* +定义Log类,封装日志的核心属性: +private long timestamp:日志时间戳(毫秒级) +private String level:日志级别(如 ERROR、INFO 等) +private String module:日志所属模块(如 Payment、User 等) +private String content:日志具体内容 +提供带参构造方法Log(long timestamp, String level, String module, String content),用于初始化日志对象 +生成所有属性的getter方法(无需 setter,日志属性创建后不可修改) +实现Serializable接口,使对象可通过网络传输 +重写toString()方法,方便日志内容打印(格式:[时间戳] 级别 模块: 内容) + */ +public class MyLog implements Serializable { + private long timestamp; + private String level; + private String module; + private String content; + + public MyLog(long timestamp, String level, String module, String content) { + this.timestamp = timestamp; + this.level = level; + this.module = module; + this.content = content; + } + + public long getTimestamp() { + return timestamp; + } + + public String getLevel() { + return level; + } + + public String getModule() { + return module; + } + + public String getContent() { + return content; + } + + @Override + public String toString() { + return "MyLog{" + + "[时间戳]:" + timestamp + + ", 级别:'" + level + '\'' + + ", 模块:'" + module + '\'' + + ", 内容:'" + content + '\'' + + '}'; + } +} diff --git a/day02/src/com/inmind/student/黄越/Log.java b/day02/src/com/inmind/student/黄越/Log.java new file mode 100644 index 0000000..5f064d1 --- /dev/null +++ b/day02/src/com/inmind/student/黄越/Log.java @@ -0,0 +1,40 @@ +package com.inmind.student.黄越; + +import java.io.Serializable; + +public class Log implements Serializable { + private static final long serialVersionUID = 1L; + private long timestamp; + private String level; + private String module; + private String content; + + public Log(long timestamp, String level, String module, String content) { + } + + public void Log(long timestamp, String level, String module, String content) { + this.timestamp = timestamp; + this.level = level; + this.module = module; + this.content = content; + } + public long getTimestamp() { + return timestamp; + } + + public String getLevel() { + return level; + } + + public String getModule() { + return module; + } + + public String getContent() { + return content; + } + + public String toString() { + return "[" + timestamp + "] " + level + " " + module + ": " + content; + } +} diff --git a/day02/src/com/inmind/student/黄越/LogClient.java b/day02/src/com/inmind/student/黄越/LogClient.java new file mode 100644 index 0000000..d36cf17 --- /dev/null +++ b/day02/src/com/inmind/student/黄越/LogClient.java @@ -0,0 +1,120 @@ +package com.inmind.student.黄越; + +import java.io.*; +import java.net.Socket; +import java.nio.file.Files; +import java.nio.file.Paths; +import java.util.*; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.concurrent.TimeUnit; +import java.util.regex.Matcher; +import java.util.regex.Pattern; +import java.util.stream.Collectors; + +public class LogClient { + private static final Pattern LOG_PATTERN = Pattern.compile("(\\d+),(\\w+),(\\w+),(.*)"); + private static final List logList = Collections.synchronizedList(new ArrayList<>()); + private static final String DIR_PATH = "D:\\io_test"; + + public static void main(String[] args) { + File dir = new File(DIR_PATH); + if (!dir.exists() || !dir.isDirectory()) { + System.out.println("Directory " + DIR_PATH + " does not exist or is not a directory"); + return; + } + + File[] logFiles = dir.listFiles((file) -> file.getName().endsWith(".log")); + if (logFiles == null || logFiles.length == 0) { + System.out.println("No .log files found in " + DIR_PATH); + return; + } + + System.out.println("找到 " + logFiles.length + " 个日志文件,开始解析..."); + + ExecutorService executorService = Executors.newFixedThreadPool(5); + List threads = new ArrayList<>(); + for (File file : logFiles) { + Thread thread = new Thread(() -> readAndParseLogFile(file)); + threads.add(thread); + executorService.submit(thread); + } + + for (Thread thread : threads) { + try { + thread.join(); + } catch (InterruptedException e) { + Thread.currentThread().interrupt(); + System.out.println("Thread join interrupted: " + e.getMessage()); + } + } + executorService.shutdown(); + try { + if (!executorService.awaitTermination(60, TimeUnit.SECONDS)) { + executorService.shutdownNow(); + } + } catch (InterruptedException e) { + executorService.shutdownNow(); + Thread.currentThread().interrupt(); + } + + System.out.println("日志解析完成,共解析 " + logList.size() + " 条日志"); + + // 统计分析 + Map levelCountMap = logList.stream() + .filter(log -> log.getLevel() != null) + .collect(Collectors.groupingBy(Log::getLevel, Collectors.counting())); + + Map errorModuleCountMap = logList.stream() + .filter(log -> "ERROR".equals(log.getLevel()) && log.getModule() != null) + .collect(Collectors.groupingBy(Log::getModule, Collectors.counting())); + + Log[] earliestLogs = logList.stream() + .sorted(Comparator.comparingLong(Log::getTimestamp)) + .limit(3) + .toArray(Log[]::new); + + // 网络上报 + try (Socket socket = new Socket("localhost", 8080); + ObjectOutputStream oos = new ObjectOutputStream(socket.getOutputStream()); + ObjectInputStream ois = new ObjectInputStream(socket.getInputStream())) { + oos.writeObject(levelCountMap); + oos.writeObject(errorModuleCountMap); + oos.writeObject(earliestLogs); + + String response = (String) ois.readObject(); + System.out.println("服务器响应:" + response); + } catch (Exception e) { + System.out.println("Client socket error: " + e.getMessage()); + } + + System.out.println("日志分析和上报完成"); + } + + private static void readAndParseLogFile(File file) { + try (BufferedReader br = Files.newBufferedReader(Paths.get(file.getPath()))) { + String line; + int lineCount = 0; + while ((line = br.readLine()) != null) { + lineCount++; + Matcher matcher = LOG_PATTERN.matcher(line); + if (matcher.matches()) { + long timestamp = Long.parseLong(matcher.group(1)); + String level = matcher.group(2); + String module = matcher.group(3); + String content = matcher.group(4); + logList.add(new Log(timestamp, level, module, content)); + } else { + System.out.println("Parse failed for line: " + line + " in file: " + file.getName()); + } + } + System.out.println("解析完成:" + file.getName() + ",共 " + lineCount + " 行"); + } catch (IOException e) { + System.out.println("Error reading file " + file.getName() + ": " + e.getMessage()); + } catch (NumberFormatException e) { + System.out.println("Number format error when parsing timestamp in file " + file.getName() + ": " + e.getMessage()); + } catch (Exception e) { + System.out.println("Unexpected error when parsing file " + file.getName() + ": " + e.getMessage()); + } + } +} diff --git a/day02/src/com/inmind/student/黄越/LogServer.java b/day02/src/com/inmind/student/黄越/LogServer.java new file mode 100644 index 0000000..985374f --- /dev/null +++ b/day02/src/com/inmind/student/黄越/LogServer.java @@ -0,0 +1,46 @@ +package com.inmind.student.黄越; + +import java.io.ObjectInputStream; +import java.io.ObjectOutputStream; +import java.net.ServerSocket; +import java.net.Socket; +import java.util.Map; + +public class LogServer { + public static void main(String[] args) { + try (ServerSocket serverSocket = new ServerSocket(8080)) { + System.out.println("LogServer started, listening on port 8080"); + while (true) { + Socket socket = serverSocket.accept(); + try (ObjectInputStream ois = new ObjectInputStream(socket.getInputStream()); + ObjectOutputStream oos = new ObjectOutputStream(socket.getOutputStream())) { + Map levelCountMap = (Map) ois.readObject(); + Map errorModuleCountMap = (Map) ois.readObject(); + Log[] earliestLogs = (Log[]) ois.readObject(); + + System.out.println("1. 按级别统计:"); + levelCountMap.forEach((level, count) -> { + String color = "ERROR".equals(level) ? "\u001B[43m" : ("WARNING".equals(level) ? "\u001B[43m" : "\u001B[37m"); + System.out.println(color + level + ": " + count + "条" + "\u001B[0m"); + }); + + System.out.println("\n2. 按模块错误统计:"); + errorModuleCountMap.forEach((module, count) -> System.out.println(module + ": " + count + "条错误")); + + System.out.println("\n3. 最早的3条日志:"); + for (int i = 0; i < earliestLogs.length; i++) { + Log log = earliestLogs[i]; + String color = i == 1 ? "\u001B[43m" : (i == 2 ? "\u001B[43m" : "\u001B[37m"); + System.out.println(color + log + "\u001B[0m"); + } + + oos.writeObject("上报成功"); + } catch (Exception e) { + System.out.println("Server error: " + e.getMessage()); + } + } + } catch (Exception e) { + System.out.println("Server socket error: " + e.getMessage()); + } + } +} diff --git a/day04/src/com/inmind/array/Demo01.java b/day04/src/com/inmind/array/Demo01.java new file mode 100644 index 0000000..e0594df --- /dev/null +++ b/day04/src/com/inmind/array/Demo01.java @@ -0,0 +1,47 @@ +package com.inmind.array; +/* +数组概念: 数组就是存储数据长度固定的容器,保证多个数据的数据类型要一致。 + +数组的3种定义格式 +一.数据的动态初始化 + 数组存储的数据类型[] 数组名字 = new 数组存储的数据类型[长度]; + 数据类型[] 数组名 = new 数据类型[数组长度]; + + 数组存储的数据类型:当前就是4类8种的基本数据类型,但是可以使用java中任意类型(引用类型) + []:数组 + 数组名:就是标识符的一种,用来操作数据 + new:java中的关键字,在堆内存中开辟空间 + 数组存储的数据类型:与前面的数据类型保持一致 + [长度]:决定 数组的长度 + +二.数组的静态初始化 +数据类型[] 数组名 = new 数据类型[]{值1,值2,值3...}; +这种格式,没有直接给出数组的长度,但是根据传入的数据的数量,来确定 + +三.数组的静态初始化简写形式 +数据类型[] 数组名 = {值1,值2,值3...}; +这种格式,没有直接给出数组的长度,但是根据传入的数据的数量,来确定 + */ +public class Demo01 { + public static void main(String[] args) { + //一.数据的动态初始化 + int[] arr1 = new int[3]; + + //取出arr1的第二个空间的值 + int b = arr1[1]; + System.out.println("arr1的第二个空间的值:"+b); + + + //二.数组的静态初始化 + double[] arr2 = new double[]{1.0,2.0}; + System.out.println("arr2的长度:"+arr2.length); + + //三.数组的静态初始化简写形式 + String[] arr3 = {"a","b","c"}; + //对arr3的第三 个空间,赋值d + arr3[2] = "d"; + System.out.println(arr3[2]); + //说明:数组的定义格式三,只能在定义数组初始化时,直接{}赋值,创建数组之后,不能再使用了 + //arr3 = {"1","2","3"}; + } +} diff --git a/day04/src/com/inmind/array/Demo02.java b/day04/src/com/inmind/array/Demo02.java new file mode 100644 index 0000000..10656e4 --- /dev/null +++ b/day04/src/com/inmind/array/Demo02.java @@ -0,0 +1,18 @@ +package com.inmind.array; + +public class Demo02 { + public static void main(String[] args) { + //定义一个长度为5的布尔型数组 + boolean[] arr = new boolean[5]; + //取出第3个空间的值,打印 + System.out.println(arr[2]); + + //定义一个长度为3的字符数组 + char[] arr1 = new char[3]; + System.out.println((int)arr1[0]); + + //定义一个长度为3的字符串数组 + String[] arr2 = new String[3]; + System.out.println(arr2[1]); +} +} diff --git a/day04/src/com/inmind/array/Demo03.java b/day04/src/com/inmind/array/Demo03.java new file mode 100644 index 0000000..d6b9869 --- /dev/null +++ b/day04/src/com/inmind/array/Demo03.java @@ -0,0 +1,20 @@ +package com.inmind.array; + +public class Demo03 { + public static void main(String[] args) { + //定义一个长度为3的整数数组 + int[] arr = new int[3]; + //打印数组的内容 + /* + [I@5594a1b5 + [I:表示当前是一个int数组 + 5594a1b5:表示的是数组在堆内存中开辟空间的地址 + */ + System.out.println(arr); + + //打印数组中第二个空间的值 + System.out.println(arr[1]); + arr[1] = 5; + System.out.println(arr[1]); + } +} diff --git a/day04/src/com/inmind/array/Demo04.java b/day04/src/com/inmind/array/Demo04.java new file mode 100644 index 0000000..91bb9df --- /dev/null +++ b/day04/src/com/inmind/array/Demo04.java @@ -0,0 +1,19 @@ +package com.inmind.array; + +public class Demo04 { + public static void main(String[] args) { + //定义长度为2的整型数组 + int[] arr = new int[2]; + System.out.println(arr); + System.out.println(arr[0]); + + //定义长度为3的double数组 + double[] arr1 = {1.0,2.0,3}; + /* + [D@6a5fc7f7 + [D:double的数组 + */ + System.out.println(arr1); + System.out.println(arr1[2]); + } +} diff --git a/day04/src/com/inmind/array/Demo05.java b/day04/src/com/inmind/array/Demo05.java new file mode 100644 index 0000000..c4cf956 --- /dev/null +++ b/day04/src/com/inmind/array/Demo05.java @@ -0,0 +1,19 @@ +package com.inmind.array; + +import java.util.Arrays; + +public class Demo05 { + public static void main(String[] args) { + //定义一个整数的数组,直接赋值1,2,3 + int[] arr = new int[]{1,2,3}; + //打印arr第二个空间的值(索引为1) + System.out.println(arr[1]); + //重新定义个int型的数组,接收arr的值 + int[] newArr = arr; + //修改newArr第二个空间的值 + newArr[1] = 100; + + //打印原来的数组arr的第二个空间的值 + System.out.println(arr[1]);//100 + } +} diff --git a/day04/src/com/inmind/array/Demo06.java b/day04/src/com/inmind/array/Demo06.java new file mode 100644 index 0000000..069ee32 --- /dev/null +++ b/day04/src/com/inmind/array/Demo06.java @@ -0,0 +1,17 @@ +package com.inmind.array; + +/** + * ArrayIndexOutOfBoundsException + * 数组索引越界异常 + * 注意:数组的长度固定不变的,数组的最大的索引值为arr.length-1 + * 0~(arr.length-1) + */ +public class Demo06 { + public static void main(String[] args) { + //定义一个整数的数组,直接赋值1,2,3 + int[] arr = new int[]{1,2,3}; + System.out.println(arr[0]); + System.out.println(arr[1]); + System.out.println(arr[2]); + } +} diff --git a/day04/src/com/inmind/array/Demo07.java b/day04/src/com/inmind/array/Demo07.java new file mode 100644 index 0000000..0119e32 --- /dev/null +++ b/day04/src/com/inmind/array/Demo07.java @@ -0,0 +1,16 @@ +package com.inmind.array; + +public class Demo07 { + public static void main(String[] args) { + //定义一个整数的数组,直接赋值1,2,3 + int[] arr = new int[]{1,2,3}; + System.out.println(arr[2]); + + arr = null; + //代码健壮性 + if(arr != null) { + System.out.println(arr[2]); + } + System.out.println("程序结束"); + } +} diff --git a/day04/src/com/inmind/array/Demo08.java b/day04/src/com/inmind/array/Demo08.java new file mode 100644 index 0000000..e692684 --- /dev/null +++ b/day04/src/com/inmind/array/Demo08.java @@ -0,0 +1,26 @@ +package com.inmind.array; + +/** + * 数组的遍历 + * 遍历:将数组中的每个数据,一一展示 + */ +public class Demo08 { + public static void main(String[] args) { + int[] arr = {1,2,3}; + /*System.out.println(arr[0]); + System.out.println(arr[1]); + System.out.println(arr[2]); + System.out.println(arr[3]); + System.out.println(arr[4]);*/ + + //采用for循环,来遍历数组(数组的正向遍历) + for (int i = 0; i < arr.length; i++) { + System.out.println(arr[i]); + } + System.out.println("-------------------------"); + //数组的反向遍历 + for(int i = arr.length-1;i>=0;i--){ + System.out.println(arr[i]); + } + } +} diff --git a/day04/src/com/inmind/array/Demo11.java b/day04/src/com/inmind/array/Demo11.java new file mode 100644 index 0000000..2225cbc --- /dev/null +++ b/day04/src/com/inmind/array/Demo11.java @@ -0,0 +1,28 @@ +package com.inmind.array; +/* +12.数组作为方法参数_传递地址 + */ +public class Demo11 { + public static void main(String[] args) { + //定义2个int数组,进行遍历 + int[] arr1 = {1,2,3}; + printArray(arr1); + System.out.println("------------------------"); + + int[] arr2 = {4,5,6}; + printArray(arr2); + } + + //定义出一个方法,接收一个整数数组,并遍历数据,没有返回值 + /* + 2个明确: + 1.明确参数类型 :(int[] arr) + 2.明确返回值类型:void + */ + + public static void printArray(int[] arr){ + for (int i = 0; i < arr.length; i++) { + System.out.println(arr[i]); + } + } +} diff --git a/day04/src/com/inmind/array/Demo12.java b/day04/src/com/inmind/array/Demo12.java new file mode 100644 index 0000000..b34bd41 --- /dev/null +++ b/day04/src/com/inmind/array/Demo12.java @@ -0,0 +1,81 @@ +package com.inmind.array; + +import java.util.Arrays; + +/* +数组作为方法返回值类型_返回地址 + */ +public class Demo12 { + public static void main(String[] args) { + //根据一个整数数组,定义一个方法,将数组中的偶数,提出来组成新的数组返回 + int[] arr = {1,2,3,4,5}; + //调用获取偶数数组的方法 +// int[] newArr = getOuShuArray(arr); +// int[] newArr = getOuShuArray1(arr); + int[] newArr = getOuShuArray2(arr); + System.out.println(Arrays.toString(newArr)); + + } + + public static int[] getOuShuArray2(int[] arr){ + //动态地计算出偶数的总数,才创建新的数组 + int count = 0; + + //遍历原数组统计偶数的个数 + for (int i = 0; i < arr.length; i++) { + int temp = arr[i]; + if (temp % 2 == 0) { + count++; + } + } + + int[] newArr = new int[count]; + int index = 0; + + //遍历传入的数组,判断是否是偶数,如果是,保存到新数组中 + for (int i = 0; i < arr.length; i++) { + int temp = arr[i];//传入数组的每个空间值 + if (temp % 2 == 0) { + newArr[index] = temp; + index++; + } + } + return newArr; + } + + + + public static int[] getOuShuArray1(int[] arr){ + int[] newArr = new int[arr.length]; + int index = 0; + + //遍历传入的数组,判断是否是偶数,如果是,保存到新数组中 + for (int i = 0; i < arr.length; i++) { + int temp = arr[i];//传入数组的每个空间值 + if (temp % 2 == 0) { + newArr[index] = temp; + index++; + } + } + return newArr; + } + + + /* + 2个明确 + 1.明确参数类型:(int[] arr) + 2.明确返回值类型:int[] + */ + + public static int[] getOuShuArray(int[] arr){ + int[] newArr = new int[arr.length]; + //遍历传入的数组,判断是否是偶数,如果是,保存到新数组中 + for (int i = 0; i < arr.length; i++) { + int temp = arr[i];//传入数组的每个空间值 + if (temp % 2 == 0) { + newArr[i] = temp; + } + } + return newArr; + } +} diff --git a/day04/src/com/inmind/array/Demo13.java b/day04/src/com/inmind/array/Demo13.java new file mode 100644 index 0000000..e7ccf2d --- /dev/null +++ b/day04/src/com/inmind/array/Demo13.java @@ -0,0 +1,20 @@ +package com.inmind.array; +/* +基本类型与引用类型作为方法参数的区别_debug说明 + */ +public class Demo13 { + public static void main(String[] args) { + //基本数据类型 + int a = 10; + int b = 20; + //定义一个方法,修改值 + changeValue(a,b); + System.out.println(a);// 10 20 + System.out.println(b);//20 40 + } + + public static void changeValue(int a, int b) { + a = a+a; + b = b+b; + } +} diff --git a/day04/src/com/inmind/array/Demo14.java b/day04/src/com/inmind/array/Demo14.java new file mode 100644 index 0000000..bddff76 --- /dev/null +++ b/day04/src/com/inmind/array/Demo14.java @@ -0,0 +1,18 @@ +package com.inmind.array; +/* +引用数据类型作为方法参数 + */ +public class Demo14 { + public static void main(String[] args) { + //定义整数数组 + int[] arr = {20,30}; + changeValue(arr); + System.out.println(arr[0]);//20 40 + System.out.println(arr[1]);//30 60 + } + + public static void changeValue(int[] arr) { + arr[0] = arr[0] + arr[0]; + arr[1] = arr[1] + arr[1]; + } +} diff --git a/day04/src/com/inmind/array/Test09.java b/day04/src/com/inmind/array/Test09.java new file mode 100644 index 0000000..ffc6767 --- /dev/null +++ b/day04/src/com/inmind/array/Test09.java @@ -0,0 +1,21 @@ +package com.inmind.array; +//数组的操作_获取数组中的最大值 +public class Test09 { + public static void main(String[] args) { + //定义一个整数数组 + int[] arr = {10,4,88,78,34}; + //定义一个变量,来记录当前数组中最大的值 + int max = arr[0]; + + //获取数组中每一个数据,依次比较,判断谁大 + for (int i = 1; i < arr.length; i++) { + int value = arr[i]; + //如果value的值比max的值还大,就要使用value中的值替换掉max + if (value > max) { + max = value; + } + } + //循环完毕,数组的每个空间的数据就比较结束,所以max中保存了当前最大的值 + System.out.println(max); + } +} diff --git a/day04/src/com/inmind/array/Test10.java b/day04/src/com/inmind/array/Test10.java new file mode 100644 index 0000000..a806c31 --- /dev/null +++ b/day04/src/com/inmind/array/Test10.java @@ -0,0 +1,43 @@ +package com.inmind.array; + +import java.util.Arrays; + +/* +数组的反转:定义一个数组,将原数组中的数据,倒转保存到另一个数组中 + */ +public class Test10 { + public static void main(String[] args) { + int[] arr = {1,2,3,4,5}; + //不创建新的数组,在原数组上实现反转,使用for循环,和2个循环变量来实现 + for(int start = 0,end = arr.length-1;start<=end;start++,end--){ + //定义一个临时变量用来保存一个空间的值 + int temp = arr[start]; + arr[start] = arr[end]; + arr[end] = temp; + } + System.out.println(Arrays.toString(arr)); + + + } + + private static void reverseArr() { + int[] arr = {1,2,3,4,5}; + //创建出一个同样长的新数组,反向遍历,进行新数组的赋值操作 + int[] newArr = new int[arr.length]; + + for (int i = arr.length-1; i >= 0; i--) { + /* + newArr[0] = arr[arr.length-1] + newArr[1] = arr[arr.length-1-1] + newArr[2] = arr[arr.length-1-2] + newArr[3] = arr[arr.length-1-3] + newArr[4] = arr[arr.length-1-4] + */ + newArr[arr.length-1 -i] = arr[i]; + } + System.out.println("---------"); + for (int i = 0; i < newArr.length; i++) { + System.out.print(newArr[i] + " "); + } + } +} diff --git a/day04/src/com/inmind/method/Demo01.java b/day04/src/com/inmind/method/Demo01.java new file mode 100644 index 0000000..b752190 --- /dev/null +++ b/day04/src/com/inmind/method/Demo01.java @@ -0,0 +1,33 @@ +package com.inmind.method; +/* +方法练习1_比较两个整数是否相同 + +2个明确: + 1.确定返回值类型:boolean + 2.确定参数列表:(int x ,int y) +*/ +public class Demo01 { + public static void main(String[] args) { + int a = 20; + int b = 30; + boolean result = getSum(a,b);//ctrl+Q + System.out.println(result); + } + + + /** + * + * @param x 第一个整数 + * @param y 第二个整数 + * @return 2个整数是否相同 + */ + public static boolean getSum(int x, int y) {// x = 20 y = 30 + boolean result = false;; + if (x == y) { + result = true; + } else { + result = false; + } + return result; + } +} diff --git a/day04/src/com/inmind/method/Demo02.java b/day04/src/com/inmind/method/Demo02.java new file mode 100644 index 0000000..f51b86c --- /dev/null +++ b/day04/src/com/inmind/method/Demo02.java @@ -0,0 +1,22 @@ +package com.inmind.method; +/* +方法练习2_运算1到n的累和 + +2个明确: + 1.明确参数:(int n) + 2.明确返回值类型 int + */ +public class Demo02 { + public static void main(String[] args) { + int sum = getSum(10); + System.out.println(sum); + } + + public static int getSum(int n){ + int result = 0; + for (int i = 1; i <= n; i++) { + result += i; + } + return result; + } +} diff --git a/day04/src/com/inmind/method/Demo03.java b/day04/src/com/inmind/method/Demo03.java new file mode 100644 index 0000000..4487208 --- /dev/null +++ b/day04/src/com/inmind/method/Demo03.java @@ -0,0 +1,42 @@ +package com.inmind.method; +/* +方法练习3_打印n遍HelloWorld. + +2个明确: + 1.明确参数列表:(int n) + 2.明确返回值类型:无返回值 void + + +学习方法定义的注意事项: +1.方法要定义在类中方法外 +2.当方法的返回值类型是void时候,需要写return?不需要 + 可以写return?可以,作用是提前结束方法,但是不能返回任何数据 +3.在一个方法中可以写多个return??? + 可以,最终最多只有一个return会执行 + + */ +public class Demo03 { + public static void main(String[] args) { + printHelloWorld(20); + System.out.println("程序结束"); + } + + public static void printHelloWorld(int n) { + //如果打印的次数超过20次,我就不执行打印 + if(n>=20){ + //提前结束方法 + return; + } + + if(n<= -20){ + //提前结束方法 + return; + } + + for (int i = 0; i < n; i++) { + System.out.println("Hello World"); + } + } + + +} diff --git a/day04/src/com/inmind/method/Demo04.java b/day04/src/com/inmind/method/Demo04.java new file mode 100644 index 0000000..1009512 --- /dev/null +++ b/day04/src/com/inmind/method/Demo04.java @@ -0,0 +1,42 @@ +package com.inmind.method; +/* +方法的三种调用方式: +1.直接调用 : 方法名(参数列表) + +2.赋值调用:数据类型 变量名 = 方法名(参数列表) + +3.打印输出调用: System.out.println(法名(参数列表)); + +总结:直接调用可以调用任意方法,赋值和打印输出调用只能调用有返回值的方法。 + */ +public class Demo04 { + public static void main(String[] args) { + //直接调用 + getSum(10); + printHelloWorld(10); + + //赋值调用 + int a = getSum(20); + + //打印输出调用 + System.out.println(getSum(30)); + System.out.println(a); + } + + + //有返回值 + public static int getSum(int n){ + int result = 0; + for (int i = 1; i <= n; i++) { + result += i; + } + return result; + } + + //无返回值 + public static void printHelloWorld(int n) { + for (int i = 0; i < n; i++) { + System.out.println("Hello World"); + } + } +} diff --git a/day04/src/com/inmind/method/Demo05.java b/day04/src/com/inmind/method/Demo05.java new file mode 100644 index 0000000..3c225ff --- /dev/null +++ b/day04/src/com/inmind/method/Demo05.java @@ -0,0 +1,59 @@ +package com.inmind.method; + +/** + * 方法重载:指在同一个类中,允许存在一个以上的同名方法,只要它们的参数列表不同即可,与修饰符和返回值类型无关。 + * 方法重载:两同一不同 + * 1.同一类中 + * 2.方法名相同 + * 3.参数列表不同(参数列表的个数,数据类型,参数的顺序) + * + * 总结:方法重载的作用:只要记住一个方法名,就可以调用不同的功能 + */ +public class Demo05 { + public static void main(String[] args) { + //定义2个整数的相加之和,并返回结果 + int a = 10; + int b = 20; + int c = 30; + int d = 40; + getSum(a, b, c, d); + //定义3个整数的相加之和,并返回结果 + //定义4个整数的相加之和,并返回结果 + System.out.println(1); + System.out.println(1.1); + System.out.println('a'); + System.out.println(true); + System.out.println("字符串"); + } + + public static int getSum(int a, int b) { + return a + b; + } + + public static int getSum(int a, int b, int c) { + return a + b+c; + } + + public static int getSum(int a, int b, int c, int d) { + return a + b+c+d; + } + + void show(int a,float b,char c) + { + + } + + //int show(int x,float y,char z)//不是 + + void show(float b,int a,char c){}; + + //void show(int c,float a,char b){}//不是 + + void show(int a,int b,int c){} + + double show(){ + return 0; + } + + +} diff --git a/day06/src/com/inmind/contructor05/Car.java b/day06/src/com/inmind/contructor05/Car.java new file mode 100644 index 0000000..4e618af --- /dev/null +++ b/day06/src/com/inmind/contructor05/Car.java @@ -0,0 +1,42 @@ +package com.inmind.contructor05; + +public class Car { + private String brand; + private double price; + private String color; + + //alt+insert + + public Car(String brand, double price, String color) { + this.brand = brand; + this.price = price; + this.color = color; + } + + public Car() { + } + + public String getBrand() { + return this.brand; + } + + public void setBrand(String brand) { + this.brand = brand; + } + + public double getPrice() { + return price; + } + + public void setPrice(double price) { + this.price = price; + } + + public String getColor() { + return this.color; + } + + public void setColor(String color) { + this.color = color; + } +} diff --git a/day06/src/com/inmind/contructor05/CarTest.java b/day06/src/com/inmind/contructor05/CarTest.java new file mode 100644 index 0000000..de2c950 --- /dev/null +++ b/day06/src/com/inmind/contructor05/CarTest.java @@ -0,0 +1,9 @@ +package com.inmind.contructor05; + +public class CarTest { + public static void main(String[] args) { + Car car = new Car(); + car.setPrice(100.0); + System.out.println(car.getPrice()); + } +} diff --git a/day06/src/com/inmind/contructor05/ContructorTest.java b/day06/src/com/inmind/contructor05/ContructorTest.java new file mode 100644 index 0000000..6fae7fd --- /dev/null +++ b/day06/src/com/inmind/contructor05/ContructorTest.java @@ -0,0 +1,17 @@ +package com.inmind.contructor05; +import com.inmind.contructor05.Student; + + +public class ContructorTest{ + public static void main(String[] args) { + //无参构造方法创建对象 + Student s1 = new Student(); + System.out.println(s1.getName()); + s1.study("java"); + + //全参构造方法创建对象 + Student s2 = new Student("赵六",20,2); + System.out.println(s2.getName()); + s2.study("mysql"); + } +} diff --git a/day06/src/com/inmind/contructor05/Student.java b/day06/src/com/inmind/contructor05/Student.java new file mode 100644 index 0000000..6a5b515 --- /dev/null +++ b/day06/src/com/inmind/contructor05/Student.java @@ -0,0 +1,79 @@ +package com.inmind.contructor05; +/* +Student():就是学生类的默认无参构造方法 + +普通自定义方法: +方法修饰符 返回值类型 方法名(参数列表){ + return;方法体 +} + +构造方法: +方法修饰符 构造方法名(参数列表){ + java方法体 +} + + +注意:当源文件(.java文件),进行编译时,编译器扫描整个类的内容,如果没有发现构造方法,那么它会自动帮你添加一个 +默认无参构造方法,如果你写了构造方法,编译器就不会自动添加默认无参构造方法 + +1.构造方法没有返回值类型 +2.构造方法必须与类名保持一致 +3.构造方法可以重载 + +构造方法的作用:通过new调用构造方法,创建对象,并且对该对象的属性进行赋值 + */ +public class Student { + private String name; + private int age; + private int id; + + public Student() {//无参构造方法 + + } + + //定义一个有参的构造方法 + public Student(String name) {//满参(全参)构造方法 + this.name = name; + } + + //定义一个有参的构造方法 + public Student(String name, int age, int id) {//满参(全参)构造方法 + this.name = name; + this.age = age; + this.id = id; + } + + + public void study(String book) { + System.out.println(name+"学生,今年"+age+"岁,学号:"+id+",正在学习"+book); + } + public void setName(String name) { + System.out.println("this:"+this); + this.name = name; + } + //get方法:对成员变量进行取值 + public String getName(){ + return this.name; + } + + public void setAge(int age) { + //增加一个年龄的判断功能 + if (age <= 0) { + System.out.println("传入的年龄有误"); + return;//提前结束方法 + } + + this.age = age; + } + public int getAge(){ + return this.age; + } + + + public void setId(int id) { + this.id = id; + } + public int getId(){ + return this.id; + } +} diff --git a/day06/src/com/inmind/member03/Phone.java b/day06/src/com/inmind/member03/Phone.java new file mode 100644 index 0000000..96d289c --- /dev/null +++ b/day06/src/com/inmind/member03/Phone.java @@ -0,0 +1,51 @@ +package com.inmind.member03; + +/* +成员变量:处于成员位置的变量 +成员位置:类中方法外 +局部变量:在方法中定义的变量 + +注意:在方法中,如果使用了成员变量和局部变量同名的变量(brand),符合就近原则,直接使用局部变量 + +成员变量与局部变量的区别: +1.定义的位置不同: + 成员变量:类中方法外 + 局部变量:方法中 +2.作用范围不同 + 成员变量:整个类中 + 局部变量:只能在定义该变量的方法中 使用 +3.所处内存的位置不同 + 成员变量:在堆内存中 + 局部变量:栈内存中 +4.默认值不同 + 成员变量:有默认值的 + 局部变量:没有默认值,一定要先赋值,才能使用 +5.生命周期不同 + 成员变量:随着对象的出现而出现,随着对象的销毁而销毁 + 局部变量:随着方法的出现而出现,随着方法的销毁而销毁 + */ +public class Phone { + //成员变量 + String brand; + int price; + String color; + double size; + + public void show(){ + String brand1 = "iphone";//局部变量 + System.out.println("品牌:"+brand+";颜色:"+color+";价格为:"+price+"的手机"); + } + + public void call(String number) { + System.out.println("给"+number+"打电话"); + } + + public void send(String number) { + System.out.println("给"+number+"发短信"); + } + + public void playApp() { + System.out.println("刷抖音"); + System.out.println("玩王者"); + } +} diff --git a/day06/src/com/inmind/member03/PhoneTest.java b/day06/src/com/inmind/member03/PhoneTest.java new file mode 100644 index 0000000..c3dda2a --- /dev/null +++ b/day06/src/com/inmind/member03/PhoneTest.java @@ -0,0 +1,12 @@ +package com.inmind.member03; + +public class PhoneTest { + public static void main(String[] args) { + //买一个小米手机 + Phone p = new Phone(); + p.brand = "小米"; + p.price = 2000; + p.color = "天空灰"; + p.show(); + } +} diff --git a/day06/src/com/inmind/object01/Student.java b/day06/src/com/inmind/object01/Student.java new file mode 100644 index 0000000..dd3d56b --- /dev/null +++ b/day06/src/com/inmind/object01/Student.java @@ -0,0 +1,60 @@ +package com.inmind.object01; +/* +2.使用类描述一个事物讲解(学生) +面向对象:在java中先有类,才有对象 + +如何使用类(class),描述生活中的事物 +一类事物是由特征和行为组成。 + +public class Student { +//特征 +姓名 +年龄 +学号 +成绩 +性别 + + + +//行为 +吃饭 +睡觉 +学习 + +} + +总结: + 1.在java中描述一类事物,由特征(成员变量)和行为(功能方法,不要使用static描述)组成 + 2.在类中,并不是都必须要主方法,如果一个类要运行,并得到一效果,那么就必须要主方法 + 在java中,一个类只是用来描述一类事物,就不要主方法 + */ +public class Student { + //特征(成员变量) +// 姓名 + String name; +// 年龄 + int age; +// 学号 + int id; +// 成绩 + double score; +// 性别 + String gender; + + + + //行为(功能方法) + //吃饭 + public void eat(String food) { + System.out.println("该学生在吃:"+food); + } + //睡觉 + public void sleep() { + System.out.println("该学生在睡觉"); + } + //学习 + public void study(String book) { + System.out.println("该学生在学习:"+book); + } + +} diff --git a/day06/src/com/inmind/object01/StudentTest.java b/day06/src/com/inmind/object01/StudentTest.java new file mode 100644 index 0000000..498327f --- /dev/null +++ b/day06/src/com/inmind/object01/StudentTest.java @@ -0,0 +1,45 @@ +package com.inmind.object01; +/* +3.面向对象给学生类属性赋值并调用学生类方法 + +类与对象的关系:类是抽象(设计图),对象是具体存在的实例(根据类创建的) + +一个类的成员变量和方法,都必须通过该类的对象来操作。 + +如何创建出对象??? +创建对象的格式: + 类型 对象名 = new 类名(); + Student s = new Student(); + + */ +public class StudentTest { + public static void main(String[] args) { + //创建出一个学生类的对象 + /* + Student:表示创建的对象的类型 + s:表示对象名,标识符的一种,s中保存的是真正的学生对象的地址 + new:在堆内存中创建的内容,(成员变量是有默认值) + Student():与之前的类型保持一致 + */ + Student s = new Student(); + //属性值的获取 + System.out.println(s.name);//null + System.out.println(s.age);//0 + System.out.println(s.gender);//null + System.out.println("---------------"); + //属性值的赋值 + s.name = "张三"; + s.age = 18; + s.gender = "男"; + System.out.println(s.name); + System.out.println(s.age); + System.out.println(s.gender); + + //使用学生的行为(调用学生功能) + s.eat("大排"); + s.sleep(); + s.study("java"); + + + } +} diff --git a/day06/src/com/inmind/object_test02/Phone.java b/day06/src/com/inmind/object_test02/Phone.java new file mode 100644 index 0000000..cfd22d2 --- /dev/null +++ b/day06/src/com/inmind/object_test02/Phone.java @@ -0,0 +1,42 @@ +package com.inmind.object_test02; +/* +4.对象内存图-面向对象的练习和内存图解(手机) + +该类描述一个手机 +属性(成员变量)和行为(功能方法) + +品牌 +价格 +颜色 +尺寸 + +行为: +打电话 +发短信 +玩app + + */ +public class Phone { + //成员变量 + String brand; + int price; + String color; + double size; + + public void show(){ + System.out.println("品牌:"+brand+";颜色:"+color+";价格为:"+price+"的手机"); + } + + public void call(String number) { + System.out.println("给"+number+"打电话"); + } + + public void send(String number) { + System.out.println("给"+number+"发短信"); + } + + public void playApp() { + System.out.println("刷抖音"); + System.out.println("玩王者"); + } +} diff --git a/day06/src/com/inmind/object_test02/PhoneTest.java b/day06/src/com/inmind/object_test02/PhoneTest.java new file mode 100644 index 0000000..fdc8a89 --- /dev/null +++ b/day06/src/com/inmind/object_test02/PhoneTest.java @@ -0,0 +1,37 @@ +package com.inmind.object_test02; + +public class PhoneTest { + public static void main(String[] args) { + //买一个黑色的苹果16 + //创建对象的语法 + Phone phone = new Phone(); + phone.brand = "Samsung"; + phone.color = "黑色"; + phone.price = 5000; + phone.size = 6.1; + /*System.out.println(phone.brand); + System.out.println(phone.color); + System.out.println(phone.price); + phone.show();*/ + printPhone(phone); + //再来一个华为手机 + Phone p2 = new Phone(); + p2.brand = "华为"; + p2.color = "白色"; + p2.price = 6000; + p2.size = 6.3; + /*System.out.println(p2.brand); + System.out.println(p2.color); + System.out.println(p2.price); + p2.show();*/ + printPhone(p2); + } + + //定义出一个将手机的属性和行为都打印输出的方法 + public static void printPhone(Phone p){ + System.out.println(p.brand); + System.out.println(p.color); + System.out.println(p.price); + p.show(); + } +} diff --git a/day06/src/com/inmind/object_test06/Coder.java b/day06/src/com/inmind/object_test06/Coder.java new file mode 100644 index 0000000..76b729b --- /dev/null +++ b/day06/src/com/inmind/object_test06/Coder.java @@ -0,0 +1,64 @@ +package com.inmind.object_test06; +/* +* Coder类: + - 属性:姓名,工号,薪资 + - 构造方法:无参构造方法,满参构造方法 + - 成员方法: + - get/set方法 + - intro方法:打印姓名,工号信息 + - showSalary方法:打印薪资信息 + - work方法:打印工作信息 + */ +public class Coder { + private String name; + private String id; + private int salary; + + public Coder() { + } + + public Coder(String name, String id, int salary) { + this.name = name; + this.id = id; + this.salary = salary; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public int getSalary() { + return salary; + } + + public void setSalary(int salary) { + this.salary = salary; + } + + //- intro方法:打印姓名,工号信息 + public void intro(){ + System.out.println("该程序员叫:"+this.name); + System.out.println("我的工号:"+this.id); + } + //- showSalary方法:打印薪资信息 + public void showSalary(){ + System.out.println("我的基本工资:"+this.salary); + } + //- work方法:打印工作信息 + public void work(){ + System.out.println("我在写代码"); + } + +} diff --git a/day06/src/com/inmind/object_test06/Manager.java b/day06/src/com/inmind/object_test06/Manager.java new file mode 100644 index 0000000..f3f4f60 --- /dev/null +++ b/day06/src/com/inmind/object_test06/Manager.java @@ -0,0 +1,65 @@ +package com.inmind.object_test06; +/* +Manager类: + - 属性:姓名,工号,薪资 + - 经理的薪资有两部分组成:基本工资+奖金 + - 构造方法:无参构造方法,满参构造方法 + - 成员方法: + - get/set方法 + - intro方法:打印姓名,工号信息 + - showSalary方法:打印薪资信息 + - work方法:打印工作信息 + */ +public class Manager { + private String name; + private String id; + private int[] salary; + + public Manager() { + } + + public Manager(String name, String id, int[] salary) { + this.name = name; + this.id = id; + this.salary = salary; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public int[] getSalary() { + return salary; + } + + public void setSalary(int[] salary) { + this.salary = salary; + } + + + //- intro方法:打印姓名,工号信息 + public void intro(){ + System.out.println("该项目经理叫:"+this.name); + System.out.println("我的工号:"+this.id); + } + //- showSalary方法:打印薪资信息 + public void showSalary(){ + System.out.println("我的基本工资:"+this.salary[0]+"项目奖金:"+this.salary[1]); + } + //- work方法:打印工作信息 + public void work(){ + System.out.println("我在进行管理工作:分配项目的功能模块,代码的检查,进度的把控"); + } +} diff --git a/day06/src/com/inmind/object_test06/Test06.java b/day06/src/com/inmind/object_test06/Test06.java new file mode 100644 index 0000000..f293b03 --- /dev/null +++ b/day06/src/com/inmind/object_test06/Test06.java @@ -0,0 +1,42 @@ +package com.inmind.object_test06; +/* +* 定义两个类,经理类Manager,程序员类Coder +* Coder类: + - 属性:姓名,工号,薪资 + - 构造方法:无参构造方法,满参构造方法 + - 成员方法: + - get/set方法 + - intro方法:打印姓名,工号信息 + - showSalary方法:打印薪资信息 + - work方法:打印工作信息 +* Manager类: + - 属性:姓名,工号,薪资 + - 经理的薪资有两部分组成:基本工资+奖金 + - 构造方法:无参构造方法,满参构造方法 + - 成员方法: + - get/set方法 + - intro方法:打印姓名,工号信息 + - showSalary方法:打印薪资信息 + - work方法:打印工作信息 +* 定义测试类,创建Manager对象,创建Coder对象,并测试。 + + + */ +public class Test06 { + public static void main(String[] args) { + //来一个项目经理 + int[] salaryArr = {12000,5000}; + Manager manager = new Manager("经理1", "S001", salaryArr); + manager.intro(); + manager.showSalary(); + manager.work(); + System.out.println("-------------------------"); + Coder coder = new Coder(); + coder.setName("程序员2"); + coder.setSalary(8000); + coder.setId("S005"); + coder.showSalary(); + coder.intro(); + coder.work(); + } +} diff --git a/day06/src/com/inmind/object_test07/Cat.java b/day06/src/com/inmind/object_test07/Cat.java new file mode 100644 index 0000000..2fbf4b2 --- /dev/null +++ b/day06/src/com/inmind/object_test07/Cat.java @@ -0,0 +1,44 @@ +package com.inmind.object_test07; + +/* +- 定义一个猫Cat类。 + + - 属性:年龄int类型,颜色char类型 + - 构造方法: + - 无参构造方法,满参构造方法 + - 成员方法: + - get/set方法 + - showMsg方法:打印猫的属性信息 + */ +public class Cat { + private int age; + private char color; + + public Cat(int age, char color) { + this.age = age; + this.color = color; + } + + public Cat() { + } + + public int getAge() { + return age; + } + + public void setAge(int age) { + this.age = age; + } + + public char getColor() { + return color; + } + + public void setColor(char color) { + this.color = color; + } + + public void showMsg(){ + System.out.println("这是一只"+this.age+"岁的"+this.color+"色的猫"); + } +} diff --git a/day06/src/com/inmind/object_test07/Test07.java b/day06/src/com/inmind/object_test07/Test07.java new file mode 100644 index 0000000..151d7fe --- /dev/null +++ b/day06/src/com/inmind/object_test07/Test07.java @@ -0,0 +1,44 @@ +package com.inmind.object_test07; +/* +- 判断两只猫的属性是否相同。 + +- 定义一个猫Cat类。 + + - 属性:年龄int类型,颜色char类型 + - 构造方法: + - 无参构造方法,满参构造方法 + - 成员方法: + - get/set方法 + - showMsg方法:打印猫的属性信息 + +- 定义测试类 + + - main方法中,使用满参构造方法,创建Cat对象。 + - 测试类中,定义比较方法,判断两只猫属性是否完全一样。属性完全相同返回true,一旦不同则返回false。 + */ +public class Test07 { + public static void main(String[] args) { + //满参创建2只猫 + Cat cat = new Cat(1, '黑'); + Cat cat1 = new Cat(1, '黑'); + //调用方法来判断2只猫是否相同 + boolean equal = isCatEqual(cat, cat1); + System.out.println("2只猫的属性是否相同??" + equal); + } + //定义比较方法,判断两只猫属性是否完全一样。属性完全相同返回true,一旦不同则返回false + public static boolean isCatEqual(Cat cat1, Cat cat2) { + boolean result = false; + int age1 = cat1.getAge(); + int age2 = cat2.getAge(); + char color1 = cat1.getColor(); + char color2 = cat2.getColor(); + /*if (age1 == age2 && color1 == color2) { + result = true; + } else { + result = false; + }*/ + result = (age1 == age2) && (color1 == color2); +// return result; + return (age1 == age2) && (color1 == color2); + } +} diff --git a/day06/src/com/inmind/object_test08/Book.java b/day06/src/com/inmind/object_test08/Book.java new file mode 100644 index 0000000..282af73 --- /dev/null +++ b/day06/src/com/inmind/object_test08/Book.java @@ -0,0 +1,68 @@ +package com.inmind.object_test08; + +/* +* 定义一个图书Book类。 + + - 属性:图书编号,书名,价格,出版日期 + - 构造方法: + - 无参构造方法,满参构造方法 + - 成员方法: + - get/set方法 + - showBook方法,输出图书信息 + */ +public class Book { + private String id; + private String name; + private double price; + private String bookDate; + + public Book() { + } + + public Book(String id, String name, double price, String bookDate) { + this.id = id; + this.name = name; + this.price = price; + this.bookDate = bookDate; + } + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public double getPrice() { + return price; + } + + public void setPrice(double price) { + this.price = price; + } + + public String getBookDate() { + return bookDate; + } + + public void setBookDate(String bookDate) { + this.bookDate = bookDate; + } + + public void showBook(){ + System.out.println("Book ID: " + id); + System.out.println("Book Name: " + name); + System.out.println("Book Price: " + price); + System.out.println("Book Date: " + bookDate); + } + +} diff --git a/day06/src/com/inmind/object_test08/Test08.java b/day06/src/com/inmind/object_test08/Test08.java new file mode 100644 index 0000000..eedecad --- /dev/null +++ b/day06/src/com/inmind/object_test08/Test08.java @@ -0,0 +1,55 @@ +package com.inmind.object_test08; + +/* +* 最贵的书。 + +* 定义一个图书Book类。 + + - 属性:图书编号,书名,价格,出版日期 + - 构造方法: + - 无参构造方法,满参构造方法 + - 成员方法: + - get/set方法 + - showBook方法,输出图书信息 + +* 定义测试类,使用满参构造方法,创建三(多)个Book对象,判断价格最贵的图书(存放书的数组的遍历),并输出图书信息。 + */ +public class Test08 { + public static void main(String[] args) { + Book book1 = new Book("b001", "java从入门到入土", 99.9, "2005-1-1"); + Book book2 = new Book("b002", "mysql从删库到跑路", 199.9, "2015-1-1"); + Book book3 = new Book("b003", "java设计思想", 299.9, "2025-1-1"); + + //将多本书放入的一个存放书的数组中 + Book[] books = {book1, book2, book3}; + + getMinBook(books); + } + + private static void getMinBook(Book[] books) { + //定义一个变量来记录最贵的书 + Book maxBook = books[0]; + for (int i = 0; i < books.length; i++) { + //每次遍历的书的对象 + Book temp = books[i]; + if (temp.getPrice() < maxBook.getPrice()) { + maxBook = temp; + } + } + maxBook.showBook(); + } + + //实现一 + private static void getMaxBook(Book book1, Book book2, Book book3) { + //定义出一个保存最贵的书 + Book maxBook = book1; + if (maxBook.getPrice() < book2.getPrice()) { + maxBook = book2; + } + + if (maxBook.getPrice() < book3.getPrice()) { + maxBook = book3; + } + maxBook.showBook(); + } +} diff --git a/day06/src/com/inmind/private04/PrivateTest.java b/day06/src/com/inmind/private04/PrivateTest.java new file mode 100644 index 0000000..8e54136 --- /dev/null +++ b/day06/src/com/inmind/private04/PrivateTest.java @@ -0,0 +1,22 @@ +package com.inmind.private04; + +public class PrivateTest { + public static void main(String[] args) { + //创建一个学生对象 + Student s = new Student(); + //属性被private修饰,不能直接访问,只能通过方法间接访问 + /*s.name = "李四"; + s.age = -18; + s.id = 1;*/ + System.out.println(s); + s.setName("李四"); + s.setAge(18); + s.setId(1); + System.out.println("--------------------------"); + Student s2 = new Student(); + System.out.println(s2); + s2.setName("王五"); + + s.study("java"); + } +} diff --git a/day06/src/com/inmind/private04/Student.java b/day06/src/com/inmind/private04/Student.java new file mode 100644 index 0000000..ae86133 --- /dev/null +++ b/day06/src/com/inmind/private04/Student.java @@ -0,0 +1,56 @@ +package com.inmind.private04; +/* +private:权限修饰符,最小一个权限,被它修饰的内容只能在本类中访问,private可以修饰 +成员方法和成员变量,表示私有化 + */ +public class Student { +// 姓名 + private String name; +// 年龄 + private int age; +// 学号 + private int id; + + //学习 + public void study(String book) { + System.out.println(name+"学生,今年"+age+"岁,学号:"+id+",正在学习"+book); + } + + //set方法:对成员变量进行赋值 + public void setName(String name) { + /* + 当前代码想要的效果:成员变量 = 局部变量 + 但当前的效果:局部变量 = 局部变量 + 如何解决当前重名的问题??? + 使用this:this.成员变量名,一定表示当前对象的成员变量 + this:表示一个对象,哪个对象调用了当前的方法,那么这个this就表示该对象 + */ + System.out.println("this:"+this); + this.name = name; + } + //get方法:对成员变量进行取值 + public String getName(){ + return this.name; + } + + public void setAge(int age) { + //增加一个年龄的判断功能 + if (age <= 0) { + System.out.println("传入的年龄有误"); + return;//提前结束方法 + } + + this.age = age; + } + public int getAge(){ + return this.age; + } + + + public void setId(int id) { + this.id = id; + } + public int getId(){ + return this.id; + } +} diff --git a/day07/src/com/inmind/arraylist03/Car.java b/day07/src/com/inmind/arraylist03/Car.java new file mode 100644 index 0000000..0dae2c9 --- /dev/null +++ b/day07/src/com/inmind/arraylist03/Car.java @@ -0,0 +1,42 @@ +package com.inmind.arraylist03; + +public class Car { + private String brand; + private double price; + private String color; + + //alt+insert + + public Car(String brand, double price, String color) { + this.brand = brand; + this.price = price; + this.color = color; + } + + public Car() { + } + + public String getBrand() { + return this.brand; + } + + public void setBrand(String brand) { + this.brand = brand; + } + + public double getPrice() { + return price; + } + + public void setPrice(double price) { + this.price = price; + } + + public String getColor() { + return this.color; + } + + public void setColor(String color) { + this.color = color; + } +} diff --git a/day07/src/com/inmind/arraylist03/Demo01.java b/day07/src/com/inmind/arraylist03/Demo01.java new file mode 100644 index 0000000..f5ff89f --- /dev/null +++ b/day07/src/com/inmind/arraylist03/Demo01.java @@ -0,0 +1,21 @@ +package com.inmind.arraylist03; +/* +arraylist的概述和引入 + */ +public class Demo01 { + public static void main(String[] args) { + //定义出一个保存车的容器 + Car[] carArr = new Car[3]; + carArr[0] = new Car("小米",45.0,"白色");//ctrl+P + carArr[1] = new Car("问界",55.0,"黑色");//ctrl+P + carArr[2] = new Car("蔚来",65.0,"灰色");//ctrl+P + for (int i = 0; i < carArr.length; i++) { + System.out.println(carArr[i]); + } + + //对象数组,还想添加2个车??不能,除非创建一个新的更长的数组 + //对象数组能直接删除一个车对象??不能,只能修改 + //为了解决以上的问题,有个更好的容器,ArrayList集合 + //ArrayList的好处:1.长度可变,2.可以增删改查 3.可以存放任意的引用类型 + } +} diff --git a/day07/src/com/inmind/arraylist03/Demo02.java b/day07/src/com/inmind/arraylist03/Demo02.java new file mode 100644 index 0000000..20cf688 --- /dev/null +++ b/day07/src/com/inmind/arraylist03/Demo02.java @@ -0,0 +1,27 @@ +package com.inmind.arraylist03; + +import java.util.ArrayList; +/* +注意:ArrayList在使用时,将同一种数据类型保存在一个容器,直接指定泛型 + */ + +public class Demo02 { + public static void main(String[] args) { + Car car = new Car(); + //创建集合对象 + ArrayList list = new ArrayList();//如果泛型不写,默认保存Object类型的数据,任意的引用类型的祖宗 + //boolean add(E e) 将指定的元素追加到此列表的末尾。 + list.add(1); + list.add(1.0); + list.add(' '); + list.add(car); + //定义出一个只保存字符串的集合 + ArrayList list1 = new ArrayList(); + list1.add("白鹿"); + list1.add("杨幂"); + list1.add("迪丽热巴"); + System.out.println(list1);//保存的是地址,但又由于底层源码实现,修改了输出效果(由于ArrayList底层重载了toString方法) + + + } +} diff --git a/day07/src/com/inmind/arraylist03/Demo03.java b/day07/src/com/inmind/arraylist03/Demo03.java new file mode 100644 index 0000000..72159ff --- /dev/null +++ b/day07/src/com/inmind/arraylist03/Demo03.java @@ -0,0 +1,109 @@ +package com.inmind.arraylist03; + +import java.util.ArrayList; + +/* +10.常用类-ArrayList-其他常用方法说明 +添加: +void add(int index, E element) 在此列表中的指定位置插入指定的元素 +public boolean add(E e):将指定的元素添加到此集合的尾部。 + +删除 +public E remove(int index) :移除此集合中指定位置上的元素。返回被删除的元素。 +boolean remove(Object o) 从列表中删除指定元素的第一个出现(如果存在)。 + +修改: +E set(int index, E element) 用指定的元素替换此列表中指定位置的元素。 + +查询 +public E get(int index) :返回此集合中指定位置上的元素。返回获取的元素。 + +public int size() :返回此集合中的元素数。遍历集合时,可以控制索引范围,防止越界。 +boolean contains(Object o) 如果此列表包含指定的元素,则返回 true + */ +public class Demo03 { + public static void main(String[] args) { + /* + 查询 + public E get(int index) :返回此集合中指定位置上的元素。返回获取的元素。 + */ + ArrayList list = new ArrayList<>(); + list.add("杨幂"); + list.add("王宝强"); + list.add("迪丽热巴"); + list.add("白鹿"); + list.add("王宝强"); + //获取热巴 + String name = list.get(2); + System.out.println(name); + System.out.println(list); + System.out.println(list.size());//5 + //boolean contains(Object o) 如果此列表包含指定的元素,则返回 true + System.out.println("-----------------"); + boolean isContains = list.contains("王宝宝"); + System.out.println(isContains); + isContains = list.contains("王宝强"); + System.out.println(isContains); + } + + private static void arrayList_Set() { + //修改: + //E set(int index, E element) 用指定的元素替换此列表中指定位置的元素。 + ArrayList list = new ArrayList<>(); + list.add("杨幂"); + list.add("王宝强"); + list.add("迪丽热巴"); + list.add("白鹿"); + list.add("王宝强"); + System.out.println(list); + //将第二个王宝强,修改为王宝宝 + String updatedValue = list.set(4, "王宝宝"); + System.out.println(updatedValue); + System.out.println(list); + } + + private static void arrayListRemove() { + /* + 删除 + public E remove(int index) :移除此集合中指定位置上的元素。返回被删除的元素。 + boolean remove(Object o) 从列表中删除指定元素的第一个出现(如果存在)。 + */ + ArrayList list = new ArrayList<>(); + list.add("杨幂"); + list.add("王宝强"); + list.add("迪丽热巴"); + list.add("白鹿"); + list.add("王宝强"); + System.out.println(list); + //将第一个王宝强删除 + //public E remove(int index) :移除此集合中指定位置上的元素。返回被删除的元素 + /*String removeName = list.remove(1); + System.out.println(removeName); + System.out.println(list);*/ + + //将第一个王宝强删除 + //boolean remove(Object o) 从集合中删除第一个相同的值 +// boolean result = list.remove("王宝强"); + boolean result = list.remove("宋丹丹"); + System.out.println(result); + System.out.println(list); + } + + private static void arrayList_Add() { + //定义一个保存字符串的集合 + ArrayList list = new ArrayList<>(); + //public boolean add(E e):将指定的元素添加到此集合的尾部。(排队) + list.add("杨幂"); + list.add("迪丽热巴"); + list.add("白鹿"); + System.out.println(list); + + //void add(int index, E element) 在此列表中的指定位置插入指定的元素(插队) + //让王宝强插队到白鹿的前面 +// list.add(2, "王宝强"); + //使用插队的add方法时,索引:0~集合长度的值 + //list.add(4, "王宝强");//IndexOutOfBoundsException: Index: 4, Size: 3 + + System.out.println(list); + } +} diff --git a/day07/src/com/inmind/arraylist03/Demo04.java b/day07/src/com/inmind/arraylist03/Demo04.java new file mode 100644 index 0000000..6c92e30 --- /dev/null +++ b/day07/src/com/inmind/arraylist03/Demo04.java @@ -0,0 +1,42 @@ +package com.inmind.arraylist03; + +import java.util.ArrayList; + +/* +11.常用类-ArrayList-基本类型的存储方式_转换为包装类 +自动装箱---int型的值,装箱成了引用数据类型Integer +自动拆箱---Integer类型对象,自动拆箱为基本数据类型int + +基本数据类型4类8种,都有对应的包装类型,特殊记忆int:Integer char:Character + + + */ +public class Demo04 { + public static void main(String[] args) { + //常用类ArrayList练习1_添加小数double + ArrayList doubleList = new ArrayList<>(); + doubleList.add(1.0); + doubleList.add(2.0); + doubleList.add(3.0); + System.out.println(doubleList); + //获取第3个值,进行计算 + Double v = doubleList.get(2); + System.out.println(v+1);//4.0 + } + + private static void addInt() { + //定义一个存放int型数据的集合 + ArrayList list = new ArrayList(); + //自动装箱:int型 1 ---->Integer + //list.add(new Integer(1)); + list.add(1); + list.add(2); + list.add(3); + System.out.println(list); + //获取list集合中第二个索引的值 + Integer i = list.get(1); + //自动拆箱:i是Integer对象,拆箱为int型的2的整数 + int sum = i+10; + System.out.println(sum);//12 + } +} diff --git a/day07/src/com/inmind/arraylist03/Demo05.java b/day07/src/com/inmind/arraylist03/Demo05.java new file mode 100644 index 0000000..cb6ea83 --- /dev/null +++ b/day07/src/com/inmind/arraylist03/Demo05.java @@ -0,0 +1,32 @@ +package com.inmind.arraylist03; + +import java.util.ArrayList; + +/* +13.常用类-ArrayList-练习2_添加对象 + */ +public class Demo05 { + public static void main(String[] args) { + Car c1 = new Car("小米", 45.0, "白色"); + Car c2 = new Car("问界", 55.0, "黑色"); + Car c3 = new Car("蔚来", 65.0, "灰色"); + + ArrayList cars = new ArrayList<>(); + cars.add(c1); + cars.add(c2); + cars.add(c3); + System.out.println(cars); + //遍历集合中的自定义对象,将对象的属性展示出来 + /*System.out.println(cars.get(0).getBrand()); + System.out.println(cars.get(1).getBrand()); + System.out.println(cars.get(2).getBrand());*/ + //采用遍历的方式来获取集合中每个对象的数据(size()) + for (int i = 0; i < cars.size(); i++) { + Car car = cars.get(i); + System.out.println(car.getBrand()); + System.out.println(car.getColor()); + System.out.println(car.getPrice()); + } + + } +} diff --git a/day07/src/com/inmind/arraylist03/Demo06.java b/day07/src/com/inmind/arraylist03/Demo06.java new file mode 100644 index 0000000..a9b0f8c --- /dev/null +++ b/day07/src/com/inmind/arraylist03/Demo06.java @@ -0,0 +1,32 @@ +package com.inmind.arraylist03; + +import java.util.ArrayList; + +//定义以指定格式打印集合的方法(ArrayList类型作为参数),使用@分隔每个元素。格式参照 [元素1@元素2@元素3]。 +public class Demo06 { + public static void main(String[] args) { + //定义出一个保存String的集合 + ArrayList list = new ArrayList(); + list.add("杨幂"); + list.add("王宝强"); + list.add("迪丽热巴"); + list.add("白鹿"); + printArrayList(list); + } + + private static void printArrayList(ArrayList list) { + //遍历集合中的内容,使用@拼接,前后[] + String result = "["; + for (int i = 0; i < list.size(); i++) { + String element = list.get(i); + //判断是否是最后一个索引,如果是则拼接element+] + if (i == (list.size() - 1)) { + result += element + "]"; + } else { + result += element + "@"; + } + } + + System.out.println(result); + } +} diff --git a/day07/src/com/inmind/arraylist03/Demo07.java b/day07/src/com/inmind/arraylist03/Demo07.java new file mode 100644 index 0000000..f80eb79 --- /dev/null +++ b/day07/src/com/inmind/arraylist03/Demo07.java @@ -0,0 +1,54 @@ +package com.inmind.arraylist03; + +import java.util.ArrayList; + +//有一个原本的集合,该集合中有正整数,1,3,4,5,8,9将集合中的偶数都取出来,保存,奇数不要 +public class Demo07 { + public static void main(String[] args) { + //在原有的集合上,进行奇数的删除 + /* + 删除 + public E remove(int index) :移除此集合中指定位置上的元素。返回被删除的元素。 + boolean remove(Object o) 从列表中删除指定元素的第一个出现(如果存在)。 + */ + ArrayList list = new ArrayList<>(); + list.add(1); + list.add(3); + list.add(4); + list.add(6); + list.add(7); + list.add(9); + System.out.println(list); + for (int i = 0; i < list.size(); i++) { + Integer element = list.get(i); + //判断是奇数就删除 + if (element % 2 != 0) { + list.remove(i); + i--;//注意点:集合遍历时,删除数据,索引前移,避免跳过数据 + } + } + + System.out.println(list); + } + + private static void getOuShu1() { + ArrayList list = new ArrayList<>(); + list.add(1); + list.add(3); + list.add(4); + list.add(6); + list.add(7); + list.add(9); + System.out.println(list); + //新建出一个新的集合,遍历旧的集合,是偶数则保存到新集合中 + ArrayList newList = new ArrayList<>(); + for (int i = 0; i < list.size(); i++) { + //获取每个元素,判断是否是偶数 + Integer elemet = list.get(i); + if (elemet % 2 == 0) { + newList.add(elemet); + } + } + System.out.println(newList); + } +} diff --git a/day07/src/com/inmind/arraylist03/test04/CarTest.java b/day07/src/com/inmind/arraylist03/test04/CarTest.java new file mode 100644 index 0000000..6e78ea6 --- /dev/null +++ b/day07/src/com/inmind/arraylist03/test04/CarTest.java @@ -0,0 +1,66 @@ +package com.inmind.arraylist03.test04; + +import java.util.ArrayList; +import java.util.Random; + +/* +随机生成扑克牌 + +- 使用集合保存所有的扑克牌对象。 +- 从所有牌中,随机移除n张牌,保存到新集合。 +- 判断n的值,不能超越一副扑克牌的范围。 + */ +public class CarTest { + public static void main(String[] args) { + //使用集合保存所有的扑克牌对象。 + ArrayList cards = getAllCards(); + //根据输入的张数,获取集合中随机的扑克牌 + int n = 3; + //定义出一个方法接收整数数量,返回随机的不同的n张牌 + ArrayList newList = getRandomCards(cards,n); + for (int i = 0; i < newList.size(); i++) { + newList.get(i).showCard(); + } + System.out.println("-------------------------"); + System.out.println(newList); + System.out.println(newList.size()); + System.out.println(cards); + System.out.println(cards.size()); + } + + private static ArrayList getRandomCards(ArrayList cards, int n) { + //数量的判断 + if (n <= 0 || n > 52) { + System.out.println("您输入的张数,超出范围"); + return null; + } + //获取随机的n张牌 + Random r = new Random(); + ArrayList newList = new ArrayList<>(); + for (int i = 0; i < n; i++) { + int removeIndex = r.nextInt(cards.size()); + Card removeCard = cards.remove(removeIndex); + newList.add(removeCard); + } + + return newList; + } + + //将所有的扑克牌对象创建并保存到集合中 + private static ArrayList getAllCards() { + ArrayList list = new ArrayList<>(); + + //定义出所有的花色 + String[] hs = {"黑桃","红桃","梅花","方块"}; + //定义出所有的点数 + String[] ds = {"A","2","3","4","5","6","7","8","9","10","J","Q","K"}; + //循环的嵌套创建出所有的牌对象 + for (int i = 0; i < hs.length; i++) { + for (int j = 0; j < ds.length; j++) { + Card card = new Card(ds[j], hs[i]); + list.add(card); + } + } + return list; + } +} diff --git a/day07/src/com/inmind/arraylist03/test04/Card.java b/day07/src/com/inmind/arraylist03/test04/Card.java new file mode 100644 index 0000000..fcf1e6c --- /dev/null +++ b/day07/src/com/inmind/arraylist03/test04/Card.java @@ -0,0 +1,41 @@ +package com.inmind.arraylist03.test04; +//扑克牌的类 +public class Card { + //点数 + String ds; + //花色 + String hs; + + public Card(String ds, String hs) { + this.ds = ds; + this.hs = hs; + } + + public String getDs() { + return ds; + } + + public void setDs(String ds) { + this.ds = ds; + } + + public String getHs() { + return hs; + } + + public void setHs(String hs) { + this.hs = hs; + } + //展示牌 + public void showCard() { + System.out.println(this.hs+this.ds+" "); + } + + @Override + public String toString() { + return "Card{" + + "ds='" + ds + '\'' + + ", hs='" + hs + '\'' + + '}'; + } +} diff --git a/day07/src/com/inmind/arraylist03/test05/Test05.java b/day07/src/com/inmind/arraylist03/test05/Test05.java new file mode 100644 index 0000000..93d83dd --- /dev/null +++ b/day07/src/com/inmind/arraylist03/test05/Test05.java @@ -0,0 +1,77 @@ +package com.inmind.arraylist03.test05; + +import java.util.ArrayList; +import java.util.Random; +import java.util.Scanner; + +/* +- 随机生成10个号码,范围1-50,作为乐透号码。 +- 键盘录入10个整数,不能重复。 +- 录入的整数与乐透号码对比,统计猜中了几个。 + */ +public class Test05 { + public static void main(String[] args) { + //- 随机生成10个号码,范围1-50,作为乐透号码。(不能重复) + ArrayList priveList = getPriveNumber(); + System.out.println(priveList); + //键盘录入10个整数,不能重复。 + ArrayList inputLists = getInputNumbers(); + //录入的整数与乐透号码对比,统计猜中了几个 + int count = countNumber(priveList,inputLists); + System.out.println("中奖号码有:"+count); + } + + private static int countNumber(ArrayList priveList, ArrayList inputLists) { + int count = 0; + for (int i = 0; i < inputLists.size(); i++) { + int inputNumber = inputLists.get(i); + if (priveList.contains(inputNumber)) { + count++; + } + } + return count; + } + + private static ArrayList getInputNumbers() { + Scanner sc = new Scanner(System.in); + ArrayList inputLists = new ArrayList<>(); + for (int i = 0; i < 5; i++) { + System.out.println("请输入第"+(i+1)+"位数字"); + int number = sc.nextInt(); + //数字的正确性的判断 + if (number <= 0 || number > 50) { + System.out.println("输入无效的数字,请重新输入"); + i--; + continue; + } + //数字的重复性判断 + if (inputLists.contains(number)) { + System.out.println("重复输入数字无效,请重新输入"); + i--; + continue; + } + + inputLists.add(number); + } + + return inputLists; + } + + private static ArrayList getPriveNumber() { + Random rand = new Random(); + ArrayList lists = new ArrayList<>(); + for (int i = 0; i < 5; i++) { + //随机获取1~50的值1~51 -1 ---》0~50 +1 + int num = rand.nextInt(50)+1; + //判断下集合中是否包含了当前的号码 + if (lists.contains(num)) { + i--; + continue; + } else { + lists.add(num);//自动装箱; + } + + } + return lists; + } +} diff --git a/day07/src/com/inmind/arraylist03/test06/Student.java b/day07/src/com/inmind/arraylist03/test06/Student.java new file mode 100644 index 0000000..819cf5b --- /dev/null +++ b/day07/src/com/inmind/arraylist03/test06/Student.java @@ -0,0 +1,55 @@ +package com.inmind.arraylist03.test06; + +//属性为姓名,年龄,地址,学号 +public class Student { + private String name; + private int age; + private int id; + private String address; + + public Student() { + } + + public Student(String name, int age, int id, String address) { + this.name = name; + this.age = age; + this.id = id; + this.address = address; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public int getAge() { + return age; + } + + public void setAge(int age) { + this.age = age; + } + + public int getId() { + return id; + } + + public void setId(int id) { + this.id = id; + } + + public String getAddress() { + return address; + } + + public void setAddress(String address) { + this.address = address; + } + + public void show(){ + System.out.println("学号为"+this.id+",姓名是"+this.name+",年龄为"+this.age+",地址是:"+this.address); + } +} diff --git a/day07/src/com/inmind/arraylist03/test06/Test06.java b/day07/src/com/inmind/arraylist03/test06/Test06.java new file mode 100644 index 0000000..44fa2b7 --- /dev/null +++ b/day07/src/com/inmind/arraylist03/test06/Test06.java @@ -0,0 +1,56 @@ +package com.inmind.arraylist03.test06; + +import java.util.ArrayList; +import java.util.Scanner; + +/* +键盘录入学生信息,保存到集合中。 + +* 循环录入的方式,1:表示继续录入,0:表示结束录入。 +* 定义学生类,属性为姓名,年龄,地址,学号使用学生对象保存录入数据。 +* 使用ArrayList集合,保存学生对象,录入结束后,遍历集合。 + */ +public class Test06 { + public static void main(String[] args) { + Scanner sc = new Scanner(System.in); + ArrayList students = new ArrayList<>(); + + //循环录入的方式,1:表示继续录入,0:表示结束录入。 + while (true) { + System.out.println("1:录入信息 0:退出"); + int choice = sc.nextInt(); + switch (choice) { + case 1: + //集输入的内容封装成学生对象保存到集合 + inputStudent(students,sc); + break; + case 0: + System.out.println("退出"); + break; + } + + if (choice == 0) { + break; + } + } + + for (int i = 0; i < students.size(); i++) { + students.get(i).show(); + } + } + + private static void inputStudent(ArrayList students, Scanner sc) { + System.out.println("请输入学号:"); + int id = sc.nextInt(); + System.out.println("请输入姓名:"); + sc.nextLine();//消耗换行符 + String name = sc.nextLine(); + System.out.println("请输入年龄:"); + int age = sc.nextInt(); + sc.nextLine();//消耗换行符 + System.out.println("请输入地址:"); + String address = sc.nextLine(); + Student student = new Student(name, age, id, address); + students.add(student); + } +} diff --git a/day07/src/com/inmind/arraylist03/test07/Student.java b/day07/src/com/inmind/arraylist03/test07/Student.java new file mode 100644 index 0000000..3606eaa --- /dev/null +++ b/day07/src/com/inmind/arraylist03/test07/Student.java @@ -0,0 +1,55 @@ +package com.inmind.arraylist03.test07; + +//属性为姓名,年龄,地址,学号 +public class Student { + private String name; + private int age; + private int id; + private String address; + + public Student() { + } + + public Student(String name, int age, int id, String address) { + this.name = name; + this.age = age; + this.id = id; + this.address = address; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public int getAge() { + return age; + } + + public void setAge(int age) { + this.age = age; + } + + public int getId() { + return id; + } + + public void setId(int id) { + this.id = id; + } + + public String getAddress() { + return address; + } + + public void setAddress(String address) { + this.address = address; + } + + public void show(){ + System.out.println("学号为"+this.id+",姓名是"+this.name+",年龄为"+this.age+",地址是:"+this.address); + } +} diff --git a/day07/src/com/inmind/arraylist03/test07/StudentManager.java b/day07/src/com/inmind/arraylist03/test07/StudentManager.java new file mode 100644 index 0000000..9291298 --- /dev/null +++ b/day07/src/com/inmind/arraylist03/test07/StudentManager.java @@ -0,0 +1,127 @@ +package com.inmind.arraylist03.test07; + +import java.util.ArrayList; +import java.util.Scanner; + +public class StudentManager { + //属性:学生集合 + private ArrayList students; + + + + //无参构造,对属性赋值 + public StudentManager() { + students = new ArrayList<>(); + } + + public ArrayList getStudents() { + return students; + } + + public void setStudents(ArrayList students) { + this.students = students; + } + + + + //功能方法,对学生的管理, + //添加 + public void addStudent(Student student) { + //判断学号是否存在,如果则反馈--学生已经存在 + for (int i = 0; i < students.size(); i++) { + Student s = students.get(i); + if (s.getId() == student.getId()) { + System.out.println("该学生已存在"); + return; + } + } + students.add(student); + System.out.println("学生添加成功"); + } + + //删除 + public void deleteStudent(int id) { + //定义一个要删除的学生 + Student removeStu = null; + for (int i = 0; i < students.size(); i++) { + Student s = students.get(i); + if (s.getId() == id) { + removeStu = s; + } + } + + if (removeStu != null) { + //删除 + students.remove(removeStu); + System.out.println("删除成功"); + } else { + //提示没有该学生 + System.out.println("未找到该学生"); + } + + + } + + //修改 + public void updateStudent(int id) { + + //定义一个要修改的学生 + Student updateStu = null; + for (int i = 0; i < students.size(); i++) { + Student s = students.get(i); + if (s.getId() == id) { + updateStu = s; + } + } + + //判断是否有该学生 + if (updateStu != null) { + //修改操作 + Scanner sc = new Scanner(System.in); + System.out.println("请输入新姓名(不修改请直接回车):"); + String name = sc.nextLine(); + if (name != "") { + updateStu.setName(name); + } + + System.out.println("请输入新地址(不修改请直接回车):"); + String address = sc.nextLine(); + if (address != "") { + updateStu.setAddress(address); + } + System.out.println("修改成功"); + }else{ + System.out.println("没有该学生!"); + } + + } + + //查询 + public void findStudent(int id) { + //定义一个要查找的学生 + Student stu = null; + for (int i = 0; i < students.size(); i++) { + Student s = students.get(i); + if (s.getId() == id) { + stu = s; + } + } + if (stu != null) { + stu.show(); + }else{ + System.out.println("未找到该学生"); + } + } + + + public void showAll() { + //展示容器中所有的学生 + if (students.size() > 0) { + for (int i = 0; i < students.size(); i++) { + students.get(i).show(); + } + }else{ + System.out.println("暂无学生信息!"); + } + } +} diff --git a/day07/src/com/inmind/arraylist03/test07/StudentManagerTest.java b/day07/src/com/inmind/arraylist03/test07/StudentManagerTest.java new file mode 100644 index 0000000..fefcf5f --- /dev/null +++ b/day07/src/com/inmind/arraylist03/test07/StudentManagerTest.java @@ -0,0 +1,107 @@ +package com.inmind.arraylist03.test07; + +import java.util.ArrayList; +import java.util.Scanner; + +/* +测试类:进行UI的展示 +自定义类:Student封装学生数据 +学生管理类:对学生数据进行管理操作(CRUD 增删改查) + */ +public class StudentManagerTest { + public static void main(String[] args) { + Scanner sc = new Scanner(System.in); + //学生管理对象对学生进行操作 + StudentManager manager = new StudentManager(); + while (true) { + System.out.println("===== 学生管理系统 ====="); + System.out.println("1. 添加学生"); + System.out.println("2. 删除学生"); + System.out.println("3. 修改学生信息"); + System.out.println("4. 查找学生"); + System.out.println("5. 显示所有学生"); + System.out.println("6. 退出系统"); + System.out.println("请输入你的选择"); + + int choice = sc.nextInt(); + switch (choice) { + case 1: + //添加学生 + addStudent(sc,manager); + break; + case 2: + //删除学生 + deleteStudent(sc,manager); + break; + case 3: + //修改学生 + updateStudent(sc,manager); + break; + case 4: + //查找学生 + findStudent(sc,manager); + break; + case 5: + //显示所有学生 + manager.showAll(); + break; + case 6: + System.out.println("退出系统"); + break; + default: + break; + } + + if (choice == 6) { + break; + } + } + + //展示学生管理中的学生数据 + ArrayList students = manager.getStudents(); + for (int i = 0; i < students.size(); i++) { + Student student = students.get(i); + student.show(); + } + } + + private static void findStudent(Scanner sc, StudentManager manager) { + System.out.println("=== 查找学生 ==="); + System.out.println("请输入要查找的学生ID:"); + int id = sc.nextInt(); + manager.findStudent(id); + } + + private static void updateStudent(Scanner sc, StudentManager manager) { + System.out.println("=== 修改学生信息 ==="); + System.out.println("请输入要修改的学生ID:"); + int id = sc.nextInt(); + //先查找是否有,才进行修改 + manager.updateStudent(id); + } + + //删除学生 + private static void deleteStudent(Scanner sc, StudentManager manager) { + System.out.println("=== 删除学生 ==="); + System.out.println("请输入要删除的学生ID:"); + int id = sc.nextInt(); + manager.deleteStudent(id); + } + + //添加学生的UI + private static void addStudent(Scanner sc, StudentManager manager) { + System.out.println("=== 添加学生 ==="); + System.out.println("请输入学号:"); + int id = sc.nextInt(); + System.out.println("请输入姓名:"); + sc.nextLine();//消耗换行符 + String name = sc.nextLine(); + System.out.println("请输入年龄:"); + int age = sc.nextInt(); + sc.nextLine();//消耗换行符 + System.out.println("请输入地址:"); + String address = sc.nextLine(); + Student student = new Student(name, age, id, address); + manager.addStudent(student); + } +} diff --git a/day07/src/com/inmind/random02/RandmoDemo01.java b/day07/src/com/inmind/random02/RandmoDemo01.java new file mode 100644 index 0000000..84741ef --- /dev/null +++ b/day07/src/com/inmind/random02/RandmoDemo01.java @@ -0,0 +1,28 @@ +package com.inmind.random02; + +import java.util.Random; + +/* +随机数 + */ +public class RandmoDemo01 { + public static void main(String[] args) { + //获取10个55~66范围内的随机值 (包含55和66)---->55~67 - 55---->0~12(包头不包尾) + Random random = new Random(); + for (int i = 0; i < 20; i++) { + int number = random.nextInt(12) + 55; + System.out.println(number); + } + } + + //ctrl+alt+M + private static void simpleApi() { + Random rand = new Random(); + //调用已经定义好的方法nextInt + for (int i = 0; i < 10; i++) { +// int number = rand.nextInt();//不传入参数,默认获取int的取值范围内的任意值 + int number = rand.nextInt(10);//真正的取值范围:0~9,在java中包头,不包尾 + System.out.println(number); + } + } +} diff --git a/day07/src/com/inmind/random02/RandomTest02.java b/day07/src/com/inmind/random02/RandomTest02.java new file mode 100644 index 0000000..49bea21 --- /dev/null +++ b/day07/src/com/inmind/random02/RandomTest02.java @@ -0,0 +1,44 @@ +package com.inmind.random02; + +import java.util.Random; +import java.util.Scanner; + +/* +7.常用类-Random-猜数字游戏(1~100) +分析:让系统生成一个随机值,由用户来猜,猜的过程要进行提示,大了,还是小了 +1.使用Random得到一个随机值1~100 +2.使用Scanner获取用户猜的整数 + a.将用户输入的值与生成的值,进行比较,如果大了提示大了 + b.将用户输入的值与生成的值,进行比较,如果大了提示小了 + c.将用户输入的值与生成的值,进行比较,如果相等,提示恭喜,结束游戏 + + */ +public class RandomTest02 { + public static void main(String[] args) { + //1.使用Random得到一个随机值1~100 + Random random = new Random();//1~100 -1--->0~99 --->100 + int randomValue = random.nextInt(100)+1; + //2.使用Scanner获取用户猜的整数 + Scanner sc = new Scanner(System.in); + while (true) { + System.out.println("请输入您所猜的值:"); + int guessNumber = sc.nextInt(); + /* + a.将用户输入的值与生成的值,进行比较,如果大了提示大了 + b.将用户输入的值与生成的值,进行比较,如果大了提示小了 + c.将用户输入的值与生成的值,进行比较,如果相等,提示恭喜,结束游戏 + */ + if (guessNumber > randomValue) { + System.out.println("您猜的值"+guessNumber+"大了!!"); + }else if(guessNumber < randomValue) { + System.out.println("您猜的值"+guessNumber+"小了!!"); + }else { + System.out.println("恭喜您猜对了"); + //结束循环 + break; + } + } + + + } +} diff --git a/day07/src/com/inmind/random02/RandomTest03.java b/day07/src/com/inmind/random02/RandomTest03.java new file mode 100644 index 0000000..4cc7180 --- /dev/null +++ b/day07/src/com/inmind/random02/RandomTest03.java @@ -0,0 +1,102 @@ +package com.inmind.random02; + +import java.util.Random; +import java.util.Scanner; + +/* +数组 随机 scanner的抽奖案例 +1.动态定义出参与抽奖的人数和姓名 + 接收输入的参与抽奖的人数 + 数组保存输入的人的名字 + +2.动态定义奖品内容 + 接收输入的奖品的个数 + 分别输入每个奖品的内容,保存到数组 +3.随机对奖品进行抽奖,并输出对应奖品的获奖者,以及未获奖的名单 + 根据奖品的个数,抽随机的人的标识(索引),记录哪些人中奖了什么奖品,哪些人没中奖 + */ +public class RandomTest03 { + public static void main(String[] args) { + /*1.动态定义出参与抽奖的人数和姓名 + 接收输入的参与抽奖的人数 + 数组保存输入的人的名字*/ + Scanner sc = new Scanner(System.in); + Random random = new Random(); + + //提示输入参与者的信息 + System.out.println("请输入参与抽奖的人数"); + //使用sc.nextInt方法时候,读取整数,系统缓冲区中会用户输入的换行符(enter),被下方的nextLine获取 + int cyCount = sc.nextInt(); + sc.nextLine();//消耗换行符,避免后期输入 + //动态创建保存参与者的姓名的数组 + String[] cyArr = new String[cyCount]; + //循环读取参与抽奖的人 + for (int i = 0; i < cyCount; i++) { + System.out.println("请输入第"+(i+1)+"位参与者的姓名:"); + String name = sc.nextLine(); + cyArr[i] = name; + } + /* + 2.动态定义奖品内容 + 接收输入的奖品的个数 + 分别输入每个奖品的内容,保存到数组 + */ + //提示用户输入奖品的数量 + System.out.println("请输入奖品的数量:"); + int prizeCount = sc.nextInt(); + sc.nextLine(); + //创建出一个数组保存奖品,循环输入奖品的内容 + String[] prizeArr = new String[prizeCount]; + for (int i = 0; i < prizeCount; i++) { + //提示输入奖品的名称 + System.out.println("请输入第"+(i+1)+"个奖品的名称"); + String name = sc.nextLine(); + prizeArr[i] = name; + } + /* + 3.随机对奖品进行抽奖,并输出对应奖品的获奖者,以及未获奖的名单 + 根据奖品的个数,抽随机的人的标识(索引),记录哪些人中奖了什么奖品,哪些人没中奖 + */ + System.out.println("======开始抽奖======="); + //标记数组,记录每个参与者的中奖状态(true,false) + boolean[] isWinnerArr = new boolean[cyCount]; + + //存储获奖者的数组 + String[] winnerArr = new String[prizeCount]; + + //循环抽取每个奖项的获奖者,奖品有几个,就要循环出几个获奖者 + for (int i = 0; i < prizeCount; i++) { + //随机获取中奖者,随机索引 + int winnerIndex; + //不停地抽,直到抽到未中奖的人 + do{ + //生成0~参与者人数-1之间的随机值 + winnerIndex = random.nextInt(cyCount); + }while(isWinnerArr[winnerIndex]); + + //记录中奖的状态 + isWinnerArr[winnerIndex] = true; + //记录中奖者的名字 + winnerArr[i] = cyArr[winnerIndex]; + + System.out.println("恭喜"+winnerArr[i]+"获得了第"+(i+1)+"个奖品:"+prizeArr[i]); + } + + //查看中奖名单 + System.out.println("=====中奖名单======"); + for (int i = 0; i < winnerArr.length; i++) { + System.out.println(prizeArr[i]+"奖品的得主:"+winnerArr[i]); + } + + //未中奖者,遍历每个参与者的抽奖的状态输出结果 + System.out.println("=====未中奖名单======"); + for (int i = 0; i < cyArr.length; i++) { + if (!isWinnerArr[i]) { + System.out.println(cyArr[i]); + } + } + + + System.out.println("程序结束"); + } +} diff --git a/day07/src/com/inmind/scanner01/Book.java b/day07/src/com/inmind/scanner01/Book.java new file mode 100644 index 0000000..d87f854 --- /dev/null +++ b/day07/src/com/inmind/scanner01/Book.java @@ -0,0 +1,68 @@ +package com.inmind.scanner01; + +/* +* 定义一个图书Book类。 + + - 属性:图书编号,书名,价格,出版日期 + - 构造方法: + - 无参构造方法,满参构造方法 + - 成员方法: + - get/set方法 + - showBook方法,输出图书信息 + */ +public class Book { + private String id; + private String name; + private double price; + private String bookDate; + + public Book() { + } + + public Book(String id, String name, double price, String bookDate) { + this.id = id; + this.name = name; + this.price = price; + this.bookDate = bookDate; + } + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public double getPrice() { + return price; + } + + public void setPrice(double price) { + this.price = price; + } + + public String getBookDate() { + return bookDate; + } + + public void setBookDate(String bookDate) { + this.bookDate = bookDate; + } + + public void showBook(){ + System.out.println("Book ID: " + id); + System.out.println("Book Name: " + name); + System.out.println("Book Price: " + price); + System.out.println("Book Date: " + bookDate); + } + +} diff --git a/day07/src/com/inmind/scanner01/NoNameDemo04.java b/day07/src/com/inmind/scanner01/NoNameDemo04.java new file mode 100644 index 0000000..d80faf5 --- /dev/null +++ b/day07/src/com/inmind/scanner01/NoNameDemo04.java @@ -0,0 +1,21 @@ +package com.inmind.scanner01; + +import java.util.Scanner; + +/* +匿名对象:没有名字的对象 +匿名对象的使用场景:当一个对象只要被使用一次,可以使用匿名对象来简单实现 + */ +public class NoNameDemo04 { + public static void main(String[] args) { + //来一本书 + new Book("b007", "java的算法", 66.6, "2022"); + //只要接收一个整数 + /*Scanner sc = new Scanner(System.in); + int i = sc.nextInt();*/ + int i = new Scanner(System.in).nextInt(); + System.out.println(i); + double d = new Scanner(System.in).nextDouble(); + System.out.println(d); + } +} diff --git a/day07/src/com/inmind/scanner01/ScannerTest.java b/day07/src/com/inmind/scanner01/ScannerTest.java new file mode 100644 index 0000000..ba145f9 --- /dev/null +++ b/day07/src/com/inmind/scanner01/ScannerTest.java @@ -0,0 +1,27 @@ +package com.inmind.scanner01; + +import java.util.Scanner; +/* +该类学习Scanner类的使用: +步骤: +1.导包 import java.util.Scanner; +2.通过构造方法创建对象 +3.通过scanner已经定义好的方法,使用该类的对象来调用,获取键盘输入的内容 + */ +public class ScannerTest { + public static void main(String[] args) { + /* + System.out:系统的输出方法,在控制台输出内容 + System.in:系统的输入方法,获取键盘输入的内容 + */ + Scanner sc = new Scanner(System.in); + //通过scanner已经定义好的方法,使用该类的对象来调用,获取键盘输入的内容 + int result = sc.nextInt(); + System.out.println(result); + double d = sc.nextDouble(); + System.out.println(d); + String s = sc.nextLine(); + System.out.println(s); + System.out.println("程序结束"); + } +} diff --git a/day07/src/com/inmind/scanner01/Test02.java b/day07/src/com/inmind/scanner01/Test02.java new file mode 100644 index 0000000..5d215e7 --- /dev/null +++ b/day07/src/com/inmind/scanner01/Test02.java @@ -0,0 +1,17 @@ +package com.inmind.scanner01; + +import java.util.Scanner; + +//3.常用类-Scanner-练习1-录入两个整数求和 +public class Test02 { + public static void main(String[] args) { + Scanner sc = new Scanner(System.in); + //提示一下 + System.out.println("请输入第一个整数:"); + int a = sc.nextInt();//java.util.InputMismatchException + System.out.println("请输入第二个整数:"); + int b = sc.nextInt(); + //求和 + System.out.println("两数相加之和:"+(a+b)); + } +} diff --git a/day07/src/com/inmind/scanner01/Test03.java b/day07/src/com/inmind/scanner01/Test03.java new file mode 100644 index 0000000..5b950f2 --- /dev/null +++ b/day07/src/com/inmind/scanner01/Test03.java @@ -0,0 +1,52 @@ +package com.inmind.scanner01; + +import java.util.Scanner; + +//.常用类-Scanner-练习2_录入三个整数求最大值 +public class Test03 { + public static void main(String[] args) { + //自定义要输入的整数的个数 + Scanner sc = new Scanner(System.in); + //提示要输入的整数个数 + System.out.println("请输入的要计算的整数个数:"); + int count = sc.nextInt(); + //首先要定义出一个容器,来接收接下来用户输入的内容 + int[] arr = new int[count]; + for (int i = 0; i < count; i++) { + //提示一下 + System.out.println("请输入第"+(i+1)+"个整数:"); + int a = sc.nextInt(); + arr[i] = a; + } + + //计算数组中多个数据的最大值 + int max = arr[0]; + for (int i = 0; i < arr.length; i++) { + int temp = arr[i]; + if (temp > max) { + max = temp; + } + } + System.out.println("您输入的"+count+"个整数的最大值为:"+max); + } + + private static void simpleGetMax() { + Scanner sc = new Scanner(System.in); + //提示一下 + System.out.println("请输入第一个整数:"); + int a = sc.nextInt(); + System.out.println("请输入第二个整数:"); + int b = sc.nextInt(); + System.out.println("请输入第三个整数:"); + int c = sc.nextInt(); + + //先用三元运算符得出一个比较大的值 + int temp = a>b?a:b; + //再用if判断流程的出最大的值 + if (temp > c) { + System.out.println("当前最大的整数:" + temp); + } else { + System.out.println("当前最大的整数:" + c); + } + } +} diff --git a/day08/src/com/inmind/arrays_03/ArraysDemo01.java b/day08/src/com/inmind/arrays_03/ArraysDemo01.java new file mode 100644 index 0000000..6f18222 --- /dev/null +++ b/day08/src/com/inmind/arrays_03/ArraysDemo01.java @@ -0,0 +1,30 @@ +package com.inmind.arrays_03; + +import java.util.Arrays; + +/* +public static String toString(int[] a) :返回指定数组内容的字符串表示形式。 + +public static void sort(int[] a) :对指定的 int 型数组按数字升序进行排序。 + */ +public class ArraysDemo01 { + public static void main(String[] args) { + //public static void sort(int[] a) :对指定的 int 型数组按数字升序进行排序。 + int[] arr = {44,22,35,21,66,54}; + System.out.println(Arrays.toString(arr)); + Arrays.sort(arr); + System.out.println(Arrays.toString(arr)); + } + + private static void toStringDemo01() { + int[] arr = {1,2,3,4,5}; + System.out.println(arr); + + /*for (int i = 0; i < arr.length; i++) { + System.out.println(arr[i]); + }*/ + //public static String toString(int[] a) :返回指定数组内容的字符串表示形式。 + String str = Arrays.toString(arr); + System.out.println(str); + } +} diff --git a/day08/src/com/inmind/arrays_03/ArraysTest.java b/day08/src/com/inmind/arrays_03/ArraysTest.java new file mode 100644 index 0000000..a33c1d4 --- /dev/null +++ b/day08/src/com/inmind/arrays_03/ArraysTest.java @@ -0,0 +1,23 @@ +package com.inmind.arrays_03; + +import java.util.Arrays; + +/* +Arrays练习:字符串倒序排列 +将一个随机字符串中的所有字符升序排列,并倒序打印。 + */ +public class ArraysTest { + public static void main(String[] args) { + //1.定义一个乱序的字符串 + String str = "andvxiscd"; + //2.字符串转字符数组 + char[] charArray = str.toCharArray(); + //3.Arrays.sort对指定的数组进行升序排序 + Arrays.sort(charArray); + System.out.println(Arrays.toString(charArray)); + //4.倒序打印 + for (int i = charArray.length - 1; i >= 0; i--) { + System.out.println(charArray[i]); + } + } +} diff --git a/day08/src/com/inmind/math_04/MathDemo.java b/day08/src/com/inmind/math_04/MathDemo.java new file mode 100644 index 0000000..73bd580 --- /dev/null +++ b/day08/src/com/inmind/math_04/MathDemo.java @@ -0,0 +1,24 @@ +package com.inmind.math_04; +/* +Math +public static double abs(double a) :返回 double 值的绝对值。 +public static double ceil(double a) :返回大于等于参数的最小的整数。 +public static double floor(double a) :返回小于等于参数最大的整数。 +public static long round(double a) :返回最接近参数的 long。(相当于四舍五入方法) + */ +public class MathDemo { + public static void main(String[] args) { + //public static double abs(double a) :返回 double 值的绝对值。 + System.out.println(Math.abs(-2));//2 + System.out.println(Math.abs(-2.2));//2.2 + //public static double ceil(double a) :返回大于等于参数的最小的整数。(向上取整) + System.out.println(Math.ceil(6.1));//7.0 + System.out.println(Math.ceil(-3.6));//-3.0 + //public static double floor(double a) :返回小于等于参数最大的整数。(向下取整) + System.out.println(Math.floor(3.1));//3.0 + System.out.println(Math.floor(-4.4));//-5.0 + //public static long round(double a) :返回最接近参数的 long。(相当于四舍五入方法) + System.out.println(Math.round(-4.4));//-4 + System.out.println(Math.round(4.6));//5 + } +} diff --git a/day08/src/com/inmind/math_04/MathTest.java b/day08/src/com/inmind/math_04/MathTest.java new file mode 100644 index 0000000..0ce06be --- /dev/null +++ b/day08/src/com/inmind/math_04/MathTest.java @@ -0,0 +1,27 @@ +package com.inmind.math_04; +/* +计算在 -10.8 到5.9 之间,绝对值大于6 或者小于2.1 的整数有多少个? +分析: +取值范围: -10.8 ~5.9 +条件>6||<2.1 +定义一个变量来计数 + */ +public class MathTest { + public static void main(String[] args) { + //在 -10.8 到5.9 之间 + double start = -10.8; + double end = 5.9; + + //区间内,绝对值大于6 或者小于2.1 的整数有多少个 + int count = 0; + for (double i = Math.ceil(start); i < end; i++) { + //每个i就是我们要统计的是否符合的整数 + double abs = Math.abs(i); + if (abs > 6|| abs <2.1) { + count++; + System.out.println(i); + } + } + System.out.println("符合条件的整数:"+count); + } +} diff --git a/day08/src/com/inmind/static_02/LoginTest03.java b/day08/src/com/inmind/static_02/LoginTest03.java new file mode 100644 index 0000000..0f0e864 --- /dev/null +++ b/day08/src/com/inmind/static_02/LoginTest03.java @@ -0,0 +1,57 @@ +package com.inmind.static_02; + +import java.util.ArrayList; +import java.util.Scanner; + + +/* +模拟用户登录。 + +* 定义用户类,属性为用户名和密码。 +* 使用集合存储多个用户对象。 +* 录入用户和密码,对比用户信息,匹配成功登录成功,否则登录失败。 +* 登录失败时,当用户名错误,提示没有该用户。 +* 登录失败时,当密码错误时,提示密码有误。 + */ +public class LoginTest03 { + static ArrayList users = new ArrayList(); + //使用集合存储多个用户对象。 + static{ + users.add(new User("张三", "123456")); + users.add(new User("李四", "123456")); + users.add(new User("王五", "123456")); + } + + public static void main(String[] args) { + //录入用户和密码,对比用户信息,匹配成功登录成功,否则登录失败。 + Scanner sc = new Scanner(System.in); + System.out.println("请输入用户名:"); + String username = sc.nextLine(); + System.out.println("请输入密码:"); + String password = sc.nextLine(); + User user = new User(username, password); + //定义一个接收一个用户的方法,返回登录状态结果 + boolean result = login(user); + System.out.println("是否登录成功:"+result); + } + + private static boolean login(User user) { + String username = user.getUsername(); + String password = user.getPassword(); + boolean result = false; + for (int i = 0; i < users.size(); i++) { + User u = users.get(i); + if (u.getUsername().equals(username)) { + if(u.getPassword().equals(password)) { + result = true; + }else{ + System.out.println("密码不正确"); + } + } else { + continue; + } + } + + return result; + } +} diff --git a/day08/src/com/inmind/static_02/StaticDemo01.java b/day08/src/com/inmind/static_02/StaticDemo01.java new file mode 100644 index 0000000..b65426d --- /dev/null +++ b/day08/src/com/inmind/static_02/StaticDemo01.java @@ -0,0 +1,35 @@ +package com.inmind.static_02; +/* + 静态static关键字修饰成员变量 + static关键字可以修饰成员变量和成员方法 + 1.使用static修饰成员变量,该变量只跟类有关,跟对象无关了,并且该类的所有的对象都共享该静态变量 + 静态成员变量的使用方式: + a.对象名.静态变量名(不推荐) + b.类名.静态变量名(推荐) + static关键字可以修饰成员方法:该方法只跟类有关,跟对象无关了,并且该类的所有的对象能调用该静态方法 + 静态成员变量的使用方式: + a.对象名.静态方法名(不推荐) + b.类名.静态方法名(推荐) + + 静态方法的作用:调用起来非常方便,不需要创建对象,常用于对应工具类的抽取,在一个项目中有可能有特定的 + 功能代码,到处要使用到,可以定义成静态方法,直接通过类名.静态方法名,直接使用 + */ +public class StaticDemo01 { + public static void main(String[] args) { + //创建出2个学生对象 + Student s1 = new Student("张三",20); + Student s2 = new Student("李四",21); + Student s3 = new Student("王五",22); + //将学生的教师定义为209教室 +// s1.classRoom = "209教室"; + Student.classRoom = "209教室"; + //问一下2位同学上课的位置 + s1.show(); + s2.show(); + s3.show(); + //校领导问s1班级有多少同学啦?? +// s1.showCount(); +// s2.showCount(); + Student.showCount(); + } +} diff --git a/day08/src/com/inmind/static_02/StaticDemo02.java b/day08/src/com/inmind/static_02/StaticDemo02.java new file mode 100644 index 0000000..53733c0 --- /dev/null +++ b/day08/src/com/inmind/static_02/StaticDemo02.java @@ -0,0 +1,29 @@ +package com.inmind.static_02; + +import java.util.ArrayList; + +/* +静态代码块:给静态变量进行初始化值的 +定义位置:类中方法外 +执行:随这类的加载而执行一次,优先于main方法和构造方法的执行 + + */ +public class StaticDemo02 { + + String name; + int age; + static int num; + static ArrayList list; + + + static{ + System.out.println("类加载了,静态代码块执行了"); + //添加一些java代码,进行配置文件的加载的 + num = 10;//给静态变量初始化值 + list = new ArrayList<>(); + } + + public static void main(String[] args) { + System.out.println("main方法执行,程序结束了"); + } +} diff --git a/day08/src/com/inmind/static_02/Student.java b/day08/src/com/inmind/static_02/Student.java new file mode 100644 index 0000000..50ad1b1 --- /dev/null +++ b/day08/src/com/inmind/static_02/Student.java @@ -0,0 +1,38 @@ +package com.inmind.static_02; + +//属性为姓名,年龄,地址,学号 +public class Student { + String name; + int age; + int id; + + static String classRoom;//只跟类有关,与对象无关,并且每个对象都共享它 + static int studentCount;//该静态变量,可以用来统计学生的数量 + + + public Student(String name, int age) { + this.name = name; + this.age = age; + studentCount++;//表示学生总数+1 + this.id = studentCount; + } + + //成员方法 + public void show() { + //成员方法可以直接访问静态方法和变量 + /*showCount(); + System.out.println(classRoom); + System.out.println(studentCount);*/ + System.out.println("我叫"+this.name+",年龄"+this.age+"学号是"+this.id+",在那个"+classRoom+"上课"); + } + + //static修饰成员方法 + public static void showCount(){ + /*System.out.println(name);//不能直接访问成员变量 + show();//不能直接访问成员方法*/ + System.out.println(classRoom+"教室有"+studentCount+"学生"); +// System.out.println(this.name); + } + + private static void xxx(){} +} diff --git a/day08/src/com/inmind/static_02/User.java b/day08/src/com/inmind/static_02/User.java new file mode 100644 index 0000000..345c390 --- /dev/null +++ b/day08/src/com/inmind/static_02/User.java @@ -0,0 +1,28 @@ +package com.inmind.static_02; + +public class User { + private String username; + private String password; + + public User(String username, String password) { + this.username = username; + this.password = password; + } + + public String getUsername() { + return username; + } + + public void setUsername(String username) { + this.username = username; + } + + public String getPassword() { + return password; + } + + public void setPassword(String password) { + this.password = password; + } + +} diff --git a/day08/src/com/inmind/string_01/StringDemo01.java b/day08/src/com/inmind/string_01/StringDemo01.java new file mode 100644 index 0000000..833eb73 --- /dev/null +++ b/day08/src/com/inmind/string_01/StringDemo01.java @@ -0,0 +1,22 @@ +package com.inmind.string_01; +/* +String类代表字符串。 Java程序中的所有字符串文字(例如"abc" )都被实现为此类的实例。 +字符串不变; 它们的值在创建后不能被更改。 因为String对象是不可变的,它们可以被共享。 + */ +public class StringDemo01 { + public static void main(String[] args) { + //定义出2个学生对象 + Student s1 = new Student(); + Student s2 = new Student(); + System.out.println(s1); + System.out.println(s1 == s2);//false + //定义出一个String的对象 + String str1 = "abc";//str1中保存的都是地址 + //str1保存的是地址,由于println的重载方法,导致String类的对象输出的是内容 + System.out.println(str1); + String str2 = "abc"; + System.out.println(str1 == str2);//true + str1 = "123"; + System.out.println(str1); + } +} diff --git a/day08/src/com/inmind/string_01/StringDemo02.java b/day08/src/com/inmind/string_01/StringDemo02.java new file mode 100644 index 0000000..df0c07e --- /dev/null +++ b/day08/src/com/inmind/string_01/StringDemo02.java @@ -0,0 +1,37 @@ +package com.inmind.string_01; +/* + String的构造方法的作用:将其他类型的数据,转换成String + String(String original) 初始化新创建的String对象,使其表示与参数相同的字符序列; 换句话说,新创建的字符串是参数字符串的副本 + public String(char[] value) :通过当前参数中的字符数组来构造新的String。 + public String(byte[] bytes) :通过使用平台的默认字符集解码当前参数中的字节数组来 + */ +public class StringDemo02 { + public static void main(String[] args) { + //String(String original) 初始化新创建的String对象,使其表示与参数相同的字符序列; 换句话说,新创建的字符串是参数字符串的副本 + String str1 = "abcd"; + String str2 = new String(str1); + System.out.println(str1);//abcd + System.out.println(str2);//abcd + System.out.println(str1 == str2);//false + } + + private static void byteArrDemo() { + //public String(byte[] bytes) :通过使用平台的默认字符集解码当前参数中的字节数组来 + //定义出一个字节数组 + byte[] bytes = {97,98,99,100};//在ascii码表中,'a'---97 '0'----48 + //通过构造方法,将字符数组转成字符串 + //将字节数组的内容拼成新的字符串(根据编码方式,将对应的十进制的值编码成字符内容再拼接) + String str = new String(bytes); + System.out.println(str);//abcd + } + + private static void charArrDemo01() { + //public String(char[] value) :通过当前参数中的字符数组来构造新的String。 + //字符串其实就是一串字符(底层就是字符数组实现) + //定义出一个字符数组 + char[] chars = {'a', 'b', 'c', 'd'}; + //通过构造方法,将字符数组转成字符串 + String str = new String(chars); + System.out.println(str);//abcd + } +} diff --git a/day08/src/com/inmind/string_01/StringDemo03.java b/day08/src/com/inmind/string_01/StringDemo03.java new file mode 100644 index 0000000..e6d1054 --- /dev/null +++ b/day08/src/com/inmind/string_01/StringDemo03.java @@ -0,0 +1,24 @@ +package com.inmind.string_01; +/* +常用类-String-的比较的方法_equals_equalsIgnoreCase + +public boolean equals (Object anObject) :将此字符串与指定对象进行比较。 + +public boolean equalsIgnoreCase (String anotherString) :将此字符串与指定对象进行比较,忽略大小写。 + */ +public class StringDemo03 { + public static void main(String[] args) { + String str1 = "abc"; + String str2 = new String("abc"); + System.out.println(str1 == str2);//== 针对基本类型比较大小,针对引用类型比较地址的,比较地址,没有意义,主要比较内容 + //public boolean equals (Object anObject) :将此字符串与指定对象进行比较内容 + System.out.println(str1.equals(str2));//true,比较的是地址指向的内容 + System.out.println("-----------------"); + String str3 = "abcd"; + String str4 = new String("AbCd"); + System.out.println(str3); + System.out.println(str4); + System.out.println(str3.equals(str4));//false + System.out.println(str3.equalsIgnoreCase(str4));//true + } +} diff --git a/day08/src/com/inmind/string_01/StringDemo04.java b/day08/src/com/inmind/string_01/StringDemo04.java new file mode 100644 index 0000000..1efdb64 --- /dev/null +++ b/day08/src/com/inmind/string_01/StringDemo04.java @@ -0,0 +1,80 @@ +package com.inmind.string_01; +/* +4.常用类-String-的获取方法_length_concat_charAt_indexOf_subString + +public int length () :返回此字符串的长度。 + +public String concat (String str) :将指定的字符串连接到该字符串的末尾。 + +public char charAt (int index) :返回指定索引处的 char值。 + +public int indexOf (String str) :返回指定子字符串第一次出现在该字符串内的索引。 + +public String substring (int beginIndex) :返回一个子字符串,从beginIndex开始截取字符串到字符串结尾。 + +public String substring (int beginIndex, int endIndex) :返回一个子字符串,从beginIndex到endIndex截取字符串。含beginIndex,不含endIndex。 + + */ +public class StringDemo04 { + public static void main(String[] args) { + //public String substring (int beginIndex) :返回一个子字符串,从beginIndex开始截取字符串到字符串结尾。 + String str = "helloworld"; + //获取world,java中包头不包尾 + String newStr = str.substring(5);//从5索引开始截取到末尾,生成一个新字符串 + System.out.println(str);//subString不会破坏原本的字符串 + System.out.println(newStr); + System.out.println("----------------"); + //public String substring (int beginIndex, int endIndex) :返回一个子字符串,从beginIndex到endIndex截取字符串。含beginIndex,不含endIndex。 + //我要截取low字符串 + String newStr1 = str.substring(3, 6); + System.out.println(newStr1); + } + + private static void indexOfDemo04() { + //public int indexOf (String str) :返回指定子字符串第一次出现在该字符串内的索引。 + String str = "123java321java54321"; + //获取第一个j的索引 + int jIndex = str.indexOf("j"); + System.out.println(jIndex);//3 + //获取第一个java的索引,获取第一个java的第一个字符的索引 + System.out.println(str.indexOf("java"));//3 + System.out.println("-------------------------------"); + //获取第二个java的索引 + //int indexOf(String str, int fromIndex) 返回指定子串的第一次出现的字符串中的索引,从指定的索引开始。 +// int java2Index = str.indexOf("java", 4); + int java2Index = str.indexOf("java", jIndex+1); + System.out.println(java2Index);//10 + } + + private static void charAtDemo03() { + //public char charAt (int index) :返回指定索引处的 char值。 + String str = "hello world"; + //获取空字符 + char c1 = str.charAt(5); + //获取r字符 + char c2 = str.charAt(8); + System.out.println("------------"); + System.out.println(c1); + System.out.println(c2); + System.out.println("------------"); + //遍历字符串 + for (int i = 0; i < str.length(); i++) { + char c = str.charAt(i); + System.out.println(c); + } + } + + private static void concatDemo02() { + //public String concat (String str) :将指定的字符串连接到该字符串的末尾 + String str1 = "Hello"; + String newStr = str1.concat("World");//str1拼接上world,生成一个新的字符串返回 + System.out.println(str1);//concat方法,拼接之后,不会修改原本的字符串对象str1 + System.out.println(newStr); + } + + private static void lengthDemo01() { + //public int length () :返回此字符串的长度。(可以对字符串遍历) + String str = "123456"; + System.out.println(str.length());//6 + } +} diff --git a/day08/src/com/inmind/string_01/StringDemo07.java b/day08/src/com/inmind/string_01/StringDemo07.java new file mode 100644 index 0000000..bc15c47 --- /dev/null +++ b/day08/src/com/inmind/string_01/StringDemo07.java @@ -0,0 +1,38 @@ +package com.inmind.string_01; +/* +5.常用类-String-的转换方法_replace_toCharArray_getBytes + +public char[] toCharArray () :将此字符串转换为新的字符数组。 +public byte[] getBytes () :使用平台的默认字符集将该 String编码转换为新的字节数组。 +public String replace (CharSequence target, CharSequence replacement) :将与target匹配的字符串使用replacement字符串替换。 + */ +public class StringDemo07 { + public static void main(String[] args) { + //public String replace (CharSequence target, CharSequence replacement) :将与target匹配的字符串使用replacement字符串替换。 + String str = "今天,天气很好,我很高兴"; + //想吧所有的天替换成* + String newStr = str.replace("天", "*"); + System.out.println(str);//替换之后,原字符串内容不变 + System.out.println(newStr); + String newStr1 = str.replace("天", "***"); + System.out.println(newStr1); + } + + private static void getBytesDemo02() { + //public byte[] getBytes () :使用平台的默认字符集将该 String编码转换为新的字节数组。 + String str = "abc"; + byte[] bytes = str.getBytes();//常用于后期的IO流操作,字节数据 + System.out.println(bytes); + } + + private static void toCharArrayDemo01() { + //public char[] toCharArray () :将此字符串转换为新的字符数组 + String str1 = "Hello World"; + //得到字符串的每个字符 + char[] charArray = str1.toCharArray(); + System.out.println(charArray); + for (int i = 0; i < charArray.length; i++) { + System.out.println(charArray[i]); + } + } +} diff --git a/day08/src/com/inmind/string_01/StringDemo09.java b/day08/src/com/inmind/string_01/StringDemo09.java new file mode 100644 index 0000000..1d4aaf8 --- /dev/null +++ b/day08/src/com/inmind/string_01/StringDemo09.java @@ -0,0 +1,17 @@ +package com.inmind.string_01; +/* +public String[] split(String regex) :将此字符串按照给定的regex(规则)拆分为字符串数组。 + */ +public class StringDemo09 { + public static void main(String[] args) { + //定义字符串 + String studentStr = "张三,18,28,常州"; + //将字符串转换为学生对象 + //按,分隔,注意:按什么切割,该字符串就不会再出现 + String[] strings = studentStr.split(","); + System.out.println(studentStr); + for (int i = 0; i < strings.length; i++) { + System.out.println(strings[i]); + } + } +} diff --git a/day08/src/com/inmind/string_01/StringTest05.java b/day08/src/com/inmind/string_01/StringTest05.java new file mode 100644 index 0000000..ad0419b --- /dev/null +++ b/day08/src/com/inmind/string_01/StringTest05.java @@ -0,0 +1,56 @@ +package com.inmind.string_01; + +import java.util.Scanner; + +/* +键盘录入QQ号码,验证格式的正确性。 +* 必须是5—12位数字。 +* 0不能开头。 + */ +public class StringTest05 { + public static void main(String[] args) { + //1.键盘输入一个qq号码 + Scanner sc = new Scanner(System.in); + System.out.println("请输入一个QQ号码:"); + String qq = sc.nextLine(); + //2.调用checkQQ(qq),返回是否符合结果 + boolean result = checkQQ(qq); + //3.打印验证结果 + System.out.println("你输入的qq号:"+qq+",是否合格:"+result); + } + + /** + * + * @param qq 要验证的qq + * @return 是否符合 + */ + private static boolean checkQQ(String qq) { + /* + * 必须是5—12位数字。 + * 0不能开头。 + */ + //判断长度 + if (!(qq.length() >= 5 && qq.length() <= 12)) { + System.out.println("你输入的qq号码,长度不符合"); + return false; + } + + //判断首字符不能为0 + if (qq.charAt(0) == '0') { + System.out.println("你输入的qq号码,首字符不能为0"); + return false; + } + + //判断qq号码的每个字符都必须是'0'~'9'之间 + for (int i = 0; i < qq.length(); i++) { + char c = qq.charAt(i); + if (c < '0' || c > '9') { + System.out.println("你输入的qq号码,只能包含数字"); + return false; + } + } + + //之前所有条件都符合,则是个合格的QQ号码 + return true; + } +} diff --git a/day08/src/com/inmind/string_01/StringTest06.java b/day08/src/com/inmind/string_01/StringTest06.java new file mode 100644 index 0000000..1c98885 --- /dev/null +++ b/day08/src/com/inmind/string_01/StringTest06.java @@ -0,0 +1,47 @@ +package com.inmind.string_01; + +import java.util.Scanner; + +/* +字符串查找。 +* 键盘录入一个大字符串,再录入一个小字符串。 +* 统计小字符串在大字符串中出现的次数。 + */ +public class StringTest06 { + public static void main(String[] args) { + /* + 1.键盘输入2个字符串 + 2.统计第二个短的字符串在第一个长字符串中出现的次数(indexOf) + 3.打印结果 + */ + //1.键盘输入2个字符串 + Scanner sc = new Scanner(System.in); + System.out.println("请输入第一个长字符串:"); + String str = sc.nextLine(); + System.out.println("请输入第二个短字符串:"); + String small = sc.nextLine(); + + //2.统计第二个短的字符串在第一个长字符串中出现的次数(indexOf) + int count = getCount(str,small); + //3.打印结果 + System.out.println("短字符串"+small+",在长字符串"+str+"中一共出现了"+count+"次"); + } + + /** + * 方法功能:统计短字符串出现的次数 + * @param str 代表长字符串 + * @param small 代表短字符串 + * @return 出现的次数 + */ + private static int getCount(String str, String small) { + //循环查找indexOf,直到返回-1才结束 + int count = 0;//记录出现的次数 + int index = 0;//记录每次查找到内容的索引,便于下一次查找 + while((index = (str.indexOf(small,index))) != -1){//重点理解 + count++;//次数+1 + index ++; + } + + return count; + } +} diff --git a/day08/src/com/inmind/string_01/StringTest08.java b/day08/src/com/inmind/string_01/StringTest08.java new file mode 100644 index 0000000..afa259f --- /dev/null +++ b/day08/src/com/inmind/string_01/StringTest08.java @@ -0,0 +1,56 @@ +package com.inmind.string_01; +/* +校验密码是否合法。 + +- 必须至少8个字符。 +- 必须至少2个大写字符。 +- 必须只有字母和数字。 + */ +public class StringTest08 { + public static void main(String[] args) { + //1.定义出一个密码 + String password = "AAbb123456!"; + //2.检验密码是否合法 + boolean result = checkPassWord(password); + //3.输出结果 + System.out.println("该密码"+password+"是否合法:"+result); + } + + private static boolean checkPassWord(String password) { + /* + - 必须至少8个字符。 + - 必须至少2个大写字符。 + - 必须只有字母和数字。 + */ + + if (password.length() < 0) { + System.out.println("密码长度不够,不少于8个字符"); + return false; + } + //定义出大写字符的个数 + int countA = 0; + char[] charArray = password.toCharArray(); + for (int i = 0; i < charArray.length; i++) { + char ch = charArray[i]; + //大写字符的数量 + if (ch >= 'A' && ch <= 'Z') { + countA++; + } + + //字母,数字的审核 + if((ch<'0'||ch>'9')&&(ch < 'A'||ch > 'Z')&&(ch<'a'||ch>'z')){ + System.out.println("密码只能包含字母和数字"); + return false; + } + } + + //判断大写字符的数量 + if (countA < 2) { + System.out.println("密码必须包含2个大写字母"); + return false; + } + + + return true; + } +} diff --git a/day08/src/com/inmind/string_01/StringTest10.java b/day08/src/com/inmind/string_01/StringTest10.java new file mode 100644 index 0000000..409faad --- /dev/null +++ b/day08/src/com/inmind/string_01/StringTest10.java @@ -0,0 +1,23 @@ +package com.inmind.string_01; +/* +常用类_String的练习_拼接字符串 +定义一个方法,把字符串“1,2,3”按照指定个格式拼接成一个字符串。格式参照如下:[word1#word2#word3]。 + */ +public class StringTest10 { + public static void main(String[] args) { + String str = "张三,18,上海"; + //切割得到新数组 + String[] strings = str.split(","); + //数组的遍历,拼接新字符串 + String newStr = "["; + for (int i = 0; i < strings.length; i++) { + String s = strings[i]; + if (i == strings.length - 1) { + newStr += s+"]"; + }else{ + newStr += s+"#"; + } + } + System.out.println(newStr); + } +} diff --git a/day08/src/com/inmind/string_01/StringTest11.java b/day08/src/com/inmind/string_01/StringTest11.java new file mode 100644 index 0000000..5db08ac --- /dev/null +++ b/day08/src/com/inmind/string_01/StringTest11.java @@ -0,0 +1,37 @@ +package com.inmind.string_01; + +import java.util.Scanner; + +/* +8.常用类_String的练习_统计字符个数 +键盘录入一个字符串,统计字符串中大小写字母及数字字符个数 + */ +public class StringTest11 { + public static void main(String[] args) { + //1.接收输入的字符串 + Scanner sc = new Scanner(System.in); + System.out.println("请输入一个字符串:"); + String str = sc.nextLine(); + //2.转换为字符数组 + char[] charArray = str.toCharArray(); + //3.遍历字符串数组a-z A-Z 0-9 + int numCount = 0; + int bigCount = 0; + int smallCount = 0; + + for (int i = 0; i < charArray.length; i++) { + char c = charArray[i]; + if (c >= 'A' && c <= 'Z') { + bigCount++; + } else if (c >= 'a' && c <= 'z') { + smallCount++; + }else if(c >= '0' && c <= '9'){ + numCount++; + } + } + System.out.println("大写的字符:"+bigCount); + System.out.println("小写的字符:"+smallCount); + System.out.println("数字的字符:"+numCount); + + } +} diff --git a/day08/src/com/inmind/string_01/Student.java b/day08/src/com/inmind/string_01/Student.java new file mode 100644 index 0000000..62825e8 --- /dev/null +++ b/day08/src/com/inmind/string_01/Student.java @@ -0,0 +1,32 @@ +package com.inmind.string_01; + +//属性为姓名,年龄,地址,学号 +public class Student { + private String name; + private int age; + + public Student() { + } + + public Student(String name, int age) { + this.name = name; + this.age = age; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public int getAge() { + return age; + } + + public void setAge(int age) { + this.age = age; + } + +} diff --git a/day09/src/com/inmind/abstract_06/Animal.java b/day09/src/com/inmind/abstract_06/Animal.java new file mode 100644 index 0000000..bb5c763 --- /dev/null +++ b/day09/src/com/inmind/abstract_06/Animal.java @@ -0,0 +1,18 @@ +package com.inmind.abstract_06; + +public abstract class Animal { + int age; + String name; + + public Animal() { + System.out.println("抽象父类内容初始化了"); + } + + public Animal(int age, String name) { + this.age = age; + this.name = name; + } + + public abstract void eat(); +// public abstract void sleep(); +} diff --git a/day09/src/com/inmind/abstract_06/Cat.java b/day09/src/com/inmind/abstract_06/Cat.java new file mode 100644 index 0000000..9b40005 --- /dev/null +++ b/day09/src/com/inmind/abstract_06/Cat.java @@ -0,0 +1,8 @@ +package com.inmind.abstract_06; + +public class Cat extends Animal{ + @Override + public void eat() { + System.out.println("猫吃鱼"); + } +} diff --git a/day09/src/com/inmind/abstract_06/Demo02.java b/day09/src/com/inmind/abstract_06/Demo02.java new file mode 100644 index 0000000..7fcad70 --- /dev/null +++ b/day09/src/com/inmind/abstract_06/Demo02.java @@ -0,0 +1,24 @@ +package com.inmind.abstract_06; +/* +如何使用抽象类和抽象方法??? +1.抽象类不能被创建对象的,只能通过子类创建对象 +2.非抽象的子类,必须实现重写抽象类中的抽象方法 +3.创建子类对象,调用对应方法 + +注意事项: +1.抽象类不能创建对象,如果创建,编译无法通过而报错。只能创建其非抽象子类的对象。 +2.抽象类中,可以有构造方法,是供子类创建对象时,初始化父类成员使用的。 +3.抽象类中,不一定包含抽象方法,但是有抽象方法的类必定是抽象类。 +4.抽象类的子类,必须重写抽象父类中所有的抽象方法,否则,编译无法通过而报错。除非该子类也是抽象类。 + +抽象的意义: +1.抽象方法,必定会被重写,对某一类事物的功能添加了约束,必须实现 +2.普通继承的重写:选择性地沿用父类的功能,选择性扩展父类功能 + */ +public class Demo02 { + public static void main(String[] args) { + //Animal animal = new Animal(); + Tiger tiger = new Tiger(); + tiger.eat(); + } +} diff --git a/day09/src/com/inmind/abstract_06/Dog.java b/day09/src/com/inmind/abstract_06/Dog.java new file mode 100644 index 0000000..124020f --- /dev/null +++ b/day09/src/com/inmind/abstract_06/Dog.java @@ -0,0 +1,8 @@ +package com.inmind.abstract_06; + +public abstract class Dog extends Animal{ + @Override + public void eat() { + System.out.println("狗吃骨头"); + } +} diff --git a/day09/src/com/inmind/abstract_06/GoldDog.java b/day09/src/com/inmind/abstract_06/GoldDog.java new file mode 100644 index 0000000..1a328f1 --- /dev/null +++ b/day09/src/com/inmind/abstract_06/GoldDog.java @@ -0,0 +1,7 @@ +package com.inmind.abstract_06; +//金毛 +public class GoldDog extends Dog{ + public void sleep() { + System.out.println("呼呼地睡觉"); + } +} diff --git a/day09/src/com/inmind/abstract_06/HaDog.java b/day09/src/com/inmind/abstract_06/HaDog.java new file mode 100644 index 0000000..6903044 --- /dev/null +++ b/day09/src/com/inmind/abstract_06/HaDog.java @@ -0,0 +1,7 @@ +package com.inmind.abstract_06; + +public class HaDog extends Dog{ + public void sleep() { + System.out.println("嘿嘿地睡"); + } +} diff --git a/day09/src/com/inmind/abstract_06/Test.java b/day09/src/com/inmind/abstract_06/Test.java new file mode 100644 index 0000000..513b593 --- /dev/null +++ b/day09/src/com/inmind/abstract_06/Test.java @@ -0,0 +1,22 @@ +package com.inmind.abstract_06; +/* + 当一个方法的具体功能,我们无法实现,那么就不要写方法体,abstract修饰,就是抽象方法 + 拥有抽象方法的类,也就是一个抽象类 + + 抽象类的格式: + public abstract class 类名{ + public abstract void 方法名(参数列表); + } + */ +public class Test { + public static void main(String[] args) { + //来一只动物 + /*Animal animal = new Animal(); + animal.eat();*/ + //来一只猫 + Cat cat = new Cat(); + cat.eat(); + /*Dog dog = new Dog(); + dog.eat();*/ + } +} diff --git a/day09/src/com/inmind/abstract_06/Tiger.java b/day09/src/com/inmind/abstract_06/Tiger.java new file mode 100644 index 0000000..69860f8 --- /dev/null +++ b/day09/src/com/inmind/abstract_06/Tiger.java @@ -0,0 +1,8 @@ +package com.inmind.abstract_06; + +public class Tiger extends Animal{ + @Override + public void eat() { + System.out.println("老虎吃兔子"); + } +} diff --git a/day09/src/com/inmind/abstract_test07/Circle.java b/day09/src/com/inmind/abstract_test07/Circle.java new file mode 100644 index 0000000..7cdaa62 --- /dev/null +++ b/day09/src/com/inmind/abstract_test07/Circle.java @@ -0,0 +1,21 @@ +package com.inmind.abstract_test07; + +public class Circle extends Shape{ + public Circle(int r) { + this(0,0,r); + } + + private Circle(int chang, int kuan, int r) { + super(chang,kuan,r); + } + + @Override + public double getArea() { + return Math.PI*getR()*getR(); + } + + @Override + public double getZC() { + return 2*Math.PI*getR(); + } +} diff --git a/day09/src/com/inmind/abstract_test07/Rectangle.java b/day09/src/com/inmind/abstract_test07/Rectangle.java new file mode 100644 index 0000000..3c61935 --- /dev/null +++ b/day09/src/com/inmind/abstract_test07/Rectangle.java @@ -0,0 +1,18 @@ +package com.inmind.abstract_test07; + +public class Rectangle extends Shape{ + public Rectangle(int chang,int kuan) { + //将创建矩形时的长宽参数,交给父类属性来处理 + super(chang,kuan,0); + } + + @Override + public double getArea() { + return getChang()*getKuan(); + } + + @Override + public double getZC() { + return 2*(getChang()+getKuan()); + } +} diff --git a/day09/src/com/inmind/abstract_test07/Shape.java b/day09/src/com/inmind/abstract_test07/Shape.java new file mode 100644 index 0000000..aee6293 --- /dev/null +++ b/day09/src/com/inmind/abstract_test07/Shape.java @@ -0,0 +1,44 @@ +package com.inmind.abstract_test07; + +public abstract class Shape { + //定义共性的属性:涵盖大部分形状的属性 + private int chang; + private int kuan; + private int r; + + + public Shape(int chang, int kuan, int r) { + this.chang = chang; + this.kuan = kuan; + this.r = r; + } + + public int getChang() { + return chang; + } + + public void setChang(int chang) { + this.chang = chang; + } + + public int getKuan() { + return kuan; + } + + public void setKuan(int kuan) { + this.kuan = kuan; + } + + public int getR() { + return r; + } + + public void setR(int r) { + this.r = r; + } + + //计算面积的方法 + public abstract double getArea(); + //计算周长的方法 + public abstract double getZC(); +} diff --git a/day09/src/com/inmind/abstract_test07/Square.java b/day09/src/com/inmind/abstract_test07/Square.java new file mode 100644 index 0000000..f412639 --- /dev/null +++ b/day09/src/com/inmind/abstract_test07/Square.java @@ -0,0 +1,11 @@ +package com.inmind.abstract_test07; + +public class Square extends Rectangle{ + public Square(int bc) { + this(bc, bc); + } + + private Square(int chang, int kuan) { + super(chang, kuan); + } +} diff --git a/day09/src/com/inmind/abstract_test07/Test.java b/day09/src/com/inmind/abstract_test07/Test.java new file mode 100644 index 0000000..35ab3a2 --- /dev/null +++ b/day09/src/com/inmind/abstract_test07/Test.java @@ -0,0 +1,26 @@ +package com.inmind.abstract_test07; +/* +- 定义形状抽象类Shape,矩形Rectangle和圆形Circle继承Shape类。 +- 圆形只能通过指定半径的方式,创建Circle对象。 +- 矩形只能通过指定长,宽的方法,创建Rectangle对象。 + +并且计算出各自的面积和周长 + */ +public class Test { + public static void main(String[] args) { + //创建长方形对象 + Rectangle rectangle = new Rectangle(4, 2); + System.out.println("长方形的周长:"+rectangle.getZC()); + System.out.println("长方形的面积:"+rectangle.getArea()); + + //创建一个圆对象 + Circle circle = new Circle(2); + System.out.println("圆的周长:"+circle.getZC()); + System.out.println("圆的面积:"+circle.getArea()); + + //如何快速定义出一个正方型的类,还不用自己实现周长和面积的方法 + Square square = new Square(4); + System.out.println("正方形的周长:"+square.getZC()); + System.out.println("正方形的面积:"+square.getArea()); + } +} diff --git a/day09/src/com/inmind/abstract_test08/Designer.java b/day09/src/com/inmind/abstract_test08/Designer.java new file mode 100644 index 0000000..1bafc63 --- /dev/null +++ b/day09/src/com/inmind/abstract_test08/Designer.java @@ -0,0 +1,29 @@ +package com.inmind.abstract_test08; +//设计人员,根据设计工具计算工资 +public class Designer extends Employee{ + private String designTool; + + public Designer(String name, String employeeId, double baseSalary,String designTool) { + super(name, employeeId, baseSalary); + this.designTool = designTool; + } + + //根据设计的工具不同,UI/UX那就+1200,否则800 + @Override + public double calSalary() { + return getBaseSalary()+(this.designTool.equals("UX")?1200:800); + } + + @Override + public void performWork() { + System.out.println(super.getName()+"在使用"+this.designTool+"工具,进行设计"); + } + + public String getDesignTool() { + return designTool; + } + + public void setDesignTool(String designTool) { + this.designTool = designTool; + } +} diff --git a/day09/src/com/inmind/abstract_test08/Developer.java b/day09/src/com/inmind/abstract_test08/Developer.java new file mode 100644 index 0000000..44d3d75 --- /dev/null +++ b/day09/src/com/inmind/abstract_test08/Developer.java @@ -0,0 +1,30 @@ +package com.inmind.abstract_test08; +//- `Developer`:开发人员,根据编程语言计算工资 +public class Developer extends Employee{ + private String programmingLanguage; + + public Developer(String name, String employeeId, double baseSalary,String programmingLanguage) { + super(name, employeeId, baseSalary); + this.programmingLanguage = programmingLanguage; + } + + public String getProgrammingLanguage() { + return programmingLanguage; + } + + public void setProgrammingLanguage(String programmingLanguage) { + this.programmingLanguage = programmingLanguage; + } + + //根据编程语言计算工资,开发人员的工资(基本工资+技术津贴) + @Override + public double calSalary() { + return getBaseSalary()+(this.programmingLanguage.equals("java")?2000:1500); + } + + //使用语言开发功能 + @Override + public void performWork() { + System.out.println(super.getName()+"在使用"+this.programmingLanguage+"语言,进行编写代码"); + } +} diff --git a/day09/src/com/inmind/abstract_test08/Employee.java b/day09/src/com/inmind/abstract_test08/Employee.java new file mode 100644 index 0000000..537ec11 --- /dev/null +++ b/day09/src/com/inmind/abstract_test08/Employee.java @@ -0,0 +1,52 @@ +package com.inmind.abstract_test08; +/* +1. 抽象类 `Employee`:定义了员工的基本属性和行为 + - 抽象方法 `calSalary()`:由不同职位的员工子类具体实现 + - 抽象方法 `performWork()`:展示员工具体工作内容 + + 定义3个属性 姓名 工号 基本工资 + */ +public abstract class Employee { + private String name; + private String employeeId; + private double baseSalary; + + public Employee(String name, String employeeId, double baseSalary) { + this.name = name; + this.employeeId = employeeId; + this.baseSalary = baseSalary; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getEmployeeId() { + return employeeId; + } + + public void setEmployeeId(String employeeId) { + this.employeeId = employeeId; + } + + public double getBaseSalary() { + return baseSalary; + } + + public void setBaseSalary(double baseSalary) { + this.baseSalary = baseSalary; + } + //抽象方法:计算盐工的工资,由具体职位决定 + public abstract double calSalary(); + + //抽象方法:执行工作,由具体职位决定 + public abstract void performWork(); + + public void show(){ + System.out.println("我叫"+this.name+",我的工号是"+this.employeeId); + } +} diff --git a/day09/src/com/inmind/abstract_test08/EmployeeManager.java b/day09/src/com/inmind/abstract_test08/EmployeeManager.java new file mode 100644 index 0000000..9da6bf9 --- /dev/null +++ b/day09/src/com/inmind/abstract_test08/EmployeeManager.java @@ -0,0 +1,49 @@ +package com.inmind.abstract_test08; + +import java.util.ArrayList; + +/* +3. 员工管理类 `EmployeeManager`: + - 添加员工 + - 显示员工信息 + - 计算总工资 + - 分配项目任务 + */ +public class EmployeeManager { + //员工的管理容器 + private ArrayList employees = new ArrayList(); + + //- 添加员工 + public void addEmployee(Employee emp) { + employees.add(emp); + } + //- 显示员工信息 + public void showEmployees() { + for (int i = 0; i < employees.size(); i++) { + employees.get(i).show(); + } + } + + //-- 展示每月要发多少工资 + public double getAllSalary() { + double salary = 0; + for (int i = 0; i < employees.size(); i++) { + Employee employee = employees.get(i); + salary += employee.calSalary(); + } + return salary; + } + + //- 分配项目任务 + public void sendTask(Project project) { + System.out.println("项目名称:"+project.getProjectName()); + System.out.println("项目起始日期:"+project.getStartDate()); + System.out.println("项目结束日期:"+project.getEndDate()); + + //让每个员工开始工作即可 + for (int i = 0; i < employees.size(); i++) { + Employee employee = employees.get(i); + employee.performWork(); + } + } +} diff --git a/day09/src/com/inmind/abstract_test08/Project.java b/day09/src/com/inmind/abstract_test08/Project.java new file mode 100644 index 0000000..88047c2 --- /dev/null +++ b/day09/src/com/inmind/abstract_test08/Project.java @@ -0,0 +1,37 @@ +package com.inmind.abstract_test08; + +public class Project { + private String projectName; + private String startDate; + private String endDate; + + public Project(String projectName, String startDate, String endDate) { + this.projectName = projectName; + this.startDate = startDate; + this.endDate = endDate; + } + + public String getProjectName() { + return projectName; + } + + public void setProjectName(String projectName) { + this.projectName = projectName; + } + + public String getStartDate() { + return startDate; + } + + public void setStartDate(String startDate) { + this.startDate = startDate; + } + + public String getEndDate() { + return endDate; + } + + public void setEndDate(String endDate) { + this.endDate = endDate; + } +} diff --git a/day09/src/com/inmind/abstract_test08/Test.java b/day09/src/com/inmind/abstract_test08/Test.java new file mode 100644 index 0000000..8e76976 --- /dev/null +++ b/day09/src/com/inmind/abstract_test08/Test.java @@ -0,0 +1,43 @@ +package com.inmind.abstract_test08; +/* +**需求**:模拟了一个软件开发公司的员工管理系统,包含以下部分: +1. 抽象类 `Employee`:定义了员工的基本属性和行为 + - 抽象方法 `calSalary()`:由不同职位的员工子类具体实现 + - 抽象方法 `performWork()`:展示员工具体工作内容 +2. 具体子类: + - `Developer`:开发人员,根据编程语言计算工资 + - `Designer`:设计人员,根据设计工具计算工资 + - `Tester`:测试人员,根据测试方法计算工资 +3. 员工管理类 `EmployeeManager`: + - 添加员工 + - 显示员工信息 + - 计算总工资 + - 分配项目任务 +4. 项目类 `Project`:定义项目基本信息 + +主程序模拟了一个简单的员工管理系统,包括添加员工、显示员工信息、计算总工资和分配项目任务等功能 + + */ +public class Test { + public static void main(String[] args) { + //创建出管理类对象 + EmployeeManager employeeManager = new EmployeeManager(); + + //添加不同的员工 + Developer developer = new Developer("开发员1", "K001", 11000, "java"); + Designer designer = new Designer("设计员", "S005", 9000, "UX"); + Tester tester = new Tester("测试员", "T009", 10000, "手动测试"); + employeeManager.addEmployee(developer); + employeeManager.addEmployee(designer); + employeeManager.addEmployee(tester); + + //展示公司的信息,一个月发多少工资,创建开发任务给大家去工作 + System.out.println("XXX科技公司,每月开支工资:"); + System.out.println(employeeManager.getAllSalary()); + employeeManager.showEmployees(); + + //创建一个项目 + Project project = new Project("康养开发项目", "25-7-7", "25-9-25"); + employeeManager.sendTask(project); + } +} diff --git a/day09/src/com/inmind/abstract_test08/Tester.java b/day09/src/com/inmind/abstract_test08/Tester.java new file mode 100644 index 0000000..699c273 --- /dev/null +++ b/day09/src/com/inmind/abstract_test08/Tester.java @@ -0,0 +1,28 @@ +package com.inmind.abstract_test08; +//`Tester`:测试人员,根据测试方法计算工资 +public class Tester extends Employee{ + private String testMethod; + + public Tester(String name, String employeeId, double baseSalary,String testMethod) { + super(name, employeeId, baseSalary); + this.testMethod = testMethod; + } + + public String getTestMethod() { + return testMethod; + } + + public void setTestMethod(String testMethod) { + this.testMethod = testMethod; + } + + @Override + public double calSalary() { + return getBaseSalary()+(this.testMethod.equals("自动化测试")?1000:500); + } + + @Override + public void performWork() { + System.out.println(super.getName()+"在使用"+this.testMethod+"方法进行测试"); + } +} diff --git a/day09/src/com/inmind/constructor_04/Demo.java b/day09/src/com/inmind/constructor_04/Demo.java new file mode 100644 index 0000000..41e8694 --- /dev/null +++ b/day09/src/com/inmind/constructor_04/Demo.java @@ -0,0 +1,14 @@ +package com.inmind.constructor_04; +/* +继承中构造方法的访问特点: +1.创建子类对象时,一定会先调用父类的构造方法 +2.super调用父类的构造方法时,必须在子类构造方法的第一行 +3.super可以调用父类的有参,无参构造方法,但必须在子类构造方法的第一行调用 + */ + +public class Demo { + public static void main(String[] args) { +// Fu fu = new Fu(); + Zi zi = new Zi(); + } +} diff --git a/day09/src/com/inmind/constructor_04/Demo02.java b/day09/src/com/inmind/constructor_04/Demo02.java new file mode 100644 index 0000000..2d8304c --- /dev/null +++ b/day09/src/com/inmind/constructor_04/Demo02.java @@ -0,0 +1,26 @@ +package com.inmind.constructor_04; +/* +super关键字的作用: +1.super,可以在子类的成员方法中,访问父类的成员变量,格式:super.父类成员变量名 +2.super,可以在子类,的成员方法中,访问父类的成员变量,格式:super.父类成员方法名 +3.super,可以在子类的构造方法中,访问父类的构造方法,但是只能在第一行,格式:super(参数列表) + +super:表示父类的对象 + + +this关键字的作用: +1.this,可以区分当前类中的局部变量和成员变量 +2.this,可以在本类中调用其他的成员方法 +3.this,可以在本类的构造方法中,调用其他的重载的构造方法 + 关于第三点的注意事项: + a.this必须在第一行,不能自己调用自己 + b.this和super在调用构造方法时,都必须在第一行,所以在同一个构造方法中,不能同时出现的 + c.this可以调用其他的重载的构造方法,不能相互调用 + */ +public class Demo02 { + public static void main(String[] args) { + Zi zi = new Zi(); +// Zi zi = new Zi(1); + + } +} diff --git a/day09/src/com/inmind/constructor_04/Fu.java b/day09/src/com/inmind/constructor_04/Fu.java new file mode 100644 index 0000000..8c3de58 --- /dev/null +++ b/day09/src/com/inmind/constructor_04/Fu.java @@ -0,0 +1,15 @@ +package com.inmind.constructor_04; + +public class Fu { + public Fu() { + System.out.println("父类的无参构造方法执行了"); + } + + public Fu(int i) { + System.out.println("父类的有参构造方法执行了"); + } + + public void method(){ + System.out.println("父类的method方法"); + } +} diff --git a/day09/src/com/inmind/constructor_04/Zi.java b/day09/src/com/inmind/constructor_04/Zi.java new file mode 100644 index 0000000..e89588e --- /dev/null +++ b/day09/src/com/inmind/constructor_04/Zi.java @@ -0,0 +1,35 @@ +package com.inmind.constructor_04; + +public class Zi extends Fu { + + int num ; + + public Zi() { + //此处优先创建了父类的对象 + //super();//如果不写这行代码,编译器也会默认添加,super()调用父类的无参构造方法 + + //System.out.println("子类的无参构造方法执行了"); + this(10); + +// System.out.println("子类中固定的相同的操作"); + } + + public Zi(int num) { + super(); + this.num = num; + + System.out.println("子类中固定的相同的操作"); + } + + + @Override//注解:检测当前是否是重写,如果是不报错,否则报错 + public void method(){ + System.out.println("子类的method方法"); + } + + + public void method1(){ + this.method(); + System.out.println("子类的method方法"); + } +} diff --git a/day09/src/com/inmind/extends_01/Assistant.java b/day09/src/com/inmind/extends_01/Assistant.java new file mode 100644 index 0000000..08ddf47 --- /dev/null +++ b/day09/src/com/inmind/extends_01/Assistant.java @@ -0,0 +1,8 @@ +package com.inmind.extends_01; + +public class Assistant extends Employee{ + + public void help(){ + System.out.println("助教会帮助学生"); + } +} diff --git a/day09/src/com/inmind/extends_01/BanZhuRen.java b/day09/src/com/inmind/extends_01/BanZhuRen.java new file mode 100644 index 0000000..ae53c35 --- /dev/null +++ b/day09/src/com/inmind/extends_01/BanZhuRen.java @@ -0,0 +1,10 @@ +package com.inmind.extends_01; + +public class BanZhuRen extends Employee{ + String name; + int age; + + public void guanxin(){ + System.out.println("班主任会关心学生"); + } +} diff --git a/day09/src/com/inmind/extends_01/Demo01.java b/day09/src/com/inmind/extends_01/Demo01.java new file mode 100644 index 0000000..a0d66da --- /dev/null +++ b/day09/src/com/inmind/extends_01/Demo01.java @@ -0,0 +1,30 @@ +package com.inmind.extends_01; +/* +继承的格式和基本使用 +public class Fu{ + 同类事物统一属性和行为 +} + +public class Zi extends Fu{ + +} + +继承的特点:子类拥有父类的所有内容,除了被private修饰的和构造方法 +继承的好处:实现多个类的相同属性行为的复用,子类可以实现各自的不同的功能需求 + */ +public class Demo01 { + public static void main(String[] args) { + //来几个员工 + Teacher t = new Teacher(); + t.name = "张三"; + t.age = 25; + t.show(); + t.teach(); + Assistant a = new Assistant(); + a.name = "李四"; + a.age = 26; + a.show(); + a.help(); + } + +} diff --git a/day09/src/com/inmind/extends_01/Employee.java b/day09/src/com/inmind/extends_01/Employee.java new file mode 100644 index 0000000..f92ae4c --- /dev/null +++ b/day09/src/com/inmind/extends_01/Employee.java @@ -0,0 +1,10 @@ +package com.inmind.extends_01; + +public class Employee { + String name; + int age; + + public void show(){ + System.out.println("展示自己"); + } +} diff --git a/day09/src/com/inmind/extends_01/Teacher.java b/day09/src/com/inmind/extends_01/Teacher.java new file mode 100644 index 0000000..f8f10ef --- /dev/null +++ b/day09/src/com/inmind/extends_01/Teacher.java @@ -0,0 +1,9 @@ +package com.inmind.extends_01; + +public class Teacher extends Employee{ + + + public void teach() { + System.out.println("老师在上课"); + } +} diff --git a/day09/src/com/inmind/extends_test05/Clerk.java b/day09/src/com/inmind/extends_test05/Clerk.java new file mode 100644 index 0000000..ba4ee65 --- /dev/null +++ b/day09/src/com/inmind/extends_test05/Clerk.java @@ -0,0 +1,30 @@ +package com.inmind.extends_test05; + +//3. 定义职员Clerk类继承Employee类,包含属性:经理,重写show方法,在父类实现基础之上增加展示经理信息。 +public class Clerk extends Employee { + private Manager manager; + + public Clerk() { + } + + public Clerk(String name, int id, String department,Manager manager) { + super(name, id, department); + this.manager = manager; + } + + public Manager getManager() { + return manager; + } + + public void setManager(Manager manager) { + this.manager = manager; + } + + @Override + public void show() { + //重写show方法,在父类实现基础之上增加展示经理信息 + super.show(); + System.out.println("我的经理:"); + System.out.println(this.manager.getName()); + } +} diff --git a/day09/src/com/inmind/extends_test05/Employee.java b/day09/src/com/inmind/extends_test05/Employee.java new file mode 100644 index 0000000..48d87d4 --- /dev/null +++ b/day09/src/com/inmind/extends_test05/Employee.java @@ -0,0 +1,44 @@ +package com.inmind.extends_test05; +//定义员工Employee类。包含属性:姓名,工号,部门,成员方法show,方法内展示员工信息。 +public class Employee { + private String name; + private int id; + private String department; + + public Employee() { + } + + public Employee(String name, int id, String department) { + this.name = name; + this.id = id; + this.department = department; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public int getId() { + return id; + } + + public void setId(int id) { + this.id = id; + } + + public String getDepartment() { + return department; + } + + public void setDepartment(String department) { + this.department = department; + } + + public void show(){ + System.out.println("我叫"+this.name+",我的工号是"+this.id+",是"+this.department+"部门的"); + } +} diff --git a/day09/src/com/inmind/extends_test05/Manager.java b/day09/src/com/inmind/extends_test05/Manager.java new file mode 100644 index 0000000..132a1c5 --- /dev/null +++ b/day09/src/com/inmind/extends_test05/Manager.java @@ -0,0 +1,36 @@ +package com.inmind.extends_test05; + +import java.util.ArrayList; + +//. 定义经理Manager类继承Employee类,包含属性:职员,重写show方法,在父类实现基础之上增加展示职员信息。 +public class Manager extends Employee{ + //职员属性 +// Clerk[] clerk; + private ArrayList clerklist; + + public Manager() { + super(); + } + public Manager(String name, int id, String department) { + super(name, id, department); + } + + public ArrayList getClerklist() { + return clerklist; + } + + public void setClerklist(ArrayList clerklist) { + this.clerklist = clerklist; + } + + @Override + public void show() { + //在父类实现基础之上增加展示职员信息 + super.show(); + //扩展的展示职员的公共 + System.out.println("我的职员有:"); + for (int i = 0; i < clerklist.size(); i++) { + System.out.println(clerklist.get(i).getName()); + } + } +} diff --git a/day09/src/com/inmind/extends_test05/Test.java b/day09/src/com/inmind/extends_test05/Test.java new file mode 100644 index 0000000..a1065c8 --- /dev/null +++ b/day09/src/com/inmind/extends_test05/Test.java @@ -0,0 +1,31 @@ +package com.inmind.extends_test05; + +import java.util.ArrayList; + +/* +编写步骤: +1. 定义员工Employee类。包含属性:姓名,工号,部门,成员方法show,方法内展示员工信息。 +2. 定义经理Manager类继承Employee类,包含属性:职员,重写show方法,在父类实现基础之上增加展示职员信息。 +3. 定义职员Clerk类继承Employee类,包含属性:经理,重写show方法,在父类实现基础之上增加展示经理信息。 + */ +public class Test { + public static void main(String[] args) { + //创建一个经理 + Manager manager = new Manager("张三",1,"开发部"); + //创建3个职员 + Clerk clerk1 = new Clerk("李四",10,"开发部",manager); + Clerk clerk2 = new Clerk("王五",11,"开发部",manager); + Clerk clerk3 = new Clerk("赵六",12,"开发部",manager); + //创建出职员集合 + ArrayList clerks = new ArrayList<>(); + clerks.add(clerk1); + clerks.add(clerk2); + clerks.add(clerk3); + manager.setClerklist(clerks); + + //经理展示下自己的信息 + manager.show(); + //员工也展示下自己的信息 + clerk1.show(); + } +} diff --git a/day09/src/com/inmind/member_variable_02/Demo01.java b/day09/src/com/inmind/member_variable_02/Demo01.java new file mode 100644 index 0000000..8152c54 --- /dev/null +++ b/day09/src/com/inmind/member_variable_02/Demo01.java @@ -0,0 +1,24 @@ +package com.inmind.member_variable_02; +/* +继承中成员变量的访问特点 +1.直接通过对象名去访问,看对象创建语句 = 左边的内容,是谁,就优先使用谁的成员变量,如果没有则向上找 +2.间接访问对象调用成员方法区访问,调用时,方法属于谁,就优先使用谁的成员变量,如果没有则向上找 + +继承中成员方法的访问特点:创建语句中,new的是谁,就优先使用谁的成员方法,如果没有则向上(为多态做准备) + */ +public class Demo01 { + public static void main(String[] args) { + //直接创建子类对象 + Zi zi = new Zi(); + System.out.println(zi.numZi);//10 + System.out.println(zi.numFu);//20 + zi.methodZi(); + zi.methodFu(); + System.out.println("------------"); + zi.numberTest(); + System.out.println("---------------------"); + zi.methodZi(); + zi.methodFu(); + zi.method(); + } +} diff --git a/day09/src/com/inmind/member_variable_02/Fu.java b/day09/src/com/inmind/member_variable_02/Fu.java new file mode 100644 index 0000000..67e1694 --- /dev/null +++ b/day09/src/com/inmind/member_variable_02/Fu.java @@ -0,0 +1,15 @@ +package com.inmind.member_variable_02; + +public class Fu { + int numFu = 20; + int number = 200;//fu类的成员变量 + + public void methodFu() { +// System.out.println(numFu); + System.out.println("父类的methodFu方法"); + } + + public void method(){ + System.out.println("父类的method方法"); + } +} diff --git a/day09/src/com/inmind/member_variable_02/Zi.java b/day09/src/com/inmind/member_variable_02/Zi.java new file mode 100644 index 0000000..062c13f --- /dev/null +++ b/day09/src/com/inmind/member_variable_02/Zi.java @@ -0,0 +1,23 @@ +package com.inmind.member_variable_02; + +public class Zi extends Fu{ + int numZi = 10; + int number = 100;//子类的成员变量 + + public void methodZi() { +// System.out.println(numZi); + System.out.println("子类的methodZi方法"); + } + + public void method(){ + System.out.println("子类的method方法"); + } + + public void numberTest(){ + int number = 50;//局部变量 + //将父子类中重名的成员变量与局部变量打印输出 + System.out.println(number);//50,就近原则 + System.out.println(this.number);//100 本类的成员变量 + System.out.println(super.number);// 200父类的成员变量,super比较父类对象 + } +} diff --git a/day09/src/com/inmind/override_03/Demo01.java b/day09/src/com/inmind/override_03/Demo01.java new file mode 100644 index 0000000..10c7984 --- /dev/null +++ b/day09/src/com/inmind/override_03/Demo01.java @@ -0,0 +1,26 @@ +package com.inmind.override_03; +/* +重载(overload) :在同一个类中,方法名相同,参数列表不同(类型,数量,顺序) +重写(override) :在父子类中,方法名相同,参数列表相同 + +java中的4种权限:public > protected>(default)不写就是默认权限>private + +重写的注意事项: +1.子类方法重写父类方法时,必须保证权限大于等于父类的权限 +2.private的内容不能继承的,也就不能重写 +3.返回值类型,方法名和参数列表保持一致 + +重写的作用:对父类的方法进行选择性的扩展 + */ +public class Demo01 { + public static void main(String[] args) { + Phone phone = new Phone(); + phone.call(); + phone.sendMsg(); + phone.getAddress(); + NewPhone newPhone = new NewPhone(); + newPhone.call(); + newPhone.sendMsg(); + newPhone.getAddress(); + } +} diff --git a/day09/src/com/inmind/override_03/Fu.java b/day09/src/com/inmind/override_03/Fu.java new file mode 100644 index 0000000..0804e42 --- /dev/null +++ b/day09/src/com/inmind/override_03/Fu.java @@ -0,0 +1,8 @@ +package com.inmind.override_03; + +public class Fu { + + public void method(){ + System.out.println("父类的method方法"); + } +} diff --git a/day09/src/com/inmind/override_03/NewPhone.java b/day09/src/com/inmind/override_03/NewPhone.java new file mode 100644 index 0000000..d28076e --- /dev/null +++ b/day09/src/com/inmind/override_03/NewPhone.java @@ -0,0 +1,14 @@ +package com.inmind.override_03; + +public class NewPhone extends Phone{ + + @Override + public void getAddress() { + //沿用父类的基础功能 + //System.out.println("显示电话号码"); + super.getAddress(); + //在新的子类中扩展功能 + System.out.println("显示头像"); + System.out.println("显示归属地"); + } +} diff --git a/day09/src/com/inmind/override_03/Phone.java b/day09/src/com/inmind/override_03/Phone.java new file mode 100644 index 0000000..be33a47 --- /dev/null +++ b/day09/src/com/inmind/override_03/Phone.java @@ -0,0 +1,15 @@ +package com.inmind.override_03; + +public class Phone { + public void call() { + System.out.println("手机打电话"); + } + + public void sendMsg() { + System.out.println("手机发短信"); + } + + public void getAddress() { + System.out.println("显示电话号码"); + } +} diff --git a/day09/src/com/inmind/override_03/Zi.java b/day09/src/com/inmind/override_03/Zi.java new file mode 100644 index 0000000..eed0799 --- /dev/null +++ b/day09/src/com/inmind/override_03/Zi.java @@ -0,0 +1,10 @@ +package com.inmind.override_03; + +public class Zi extends Fu { + + @Override//注解:检测当前是否是重写,如果是不报错,否则报错 + public void method(){ + System.out.println("子类的method方法"); + } + +} diff --git a/day10/src/com/inmind/default_02/Demo.java b/day10/src/com/inmind/default_02/Demo.java new file mode 100644 index 0000000..b396333 --- /dev/null +++ b/day10/src/com/inmind/default_02/Demo.java @@ -0,0 +1,22 @@ +package com.inmind.default_02; +/* +JDK8时提供,接口的默认方法 + +接口的抽象方法的使用步骤: +1.接口不能创建对象的,它没有构造方法 +2.定义一个实现类,实现该接口,并实现接口中的所有的抽象方法 + public class MyInterfaceImpl(实现类) implements MyInterface(接口){ +3.创建该接口的实现类的对象,调用接口的默认方法 +4.在接口的实现类中,可以根据对应的需求,选择性重写,或不重写接口中的默认方法,也可以沿用功能(接口.super.默认方法名)(重点) + */ +public class Demo { + public static void main(String[] args) { + MyInterfaceImpl1 myInterfaceImpl1 = new MyInterfaceImpl1();//创建一个实现类对象1 + myInterfaceImpl1.myMethod();//调用抽象方法 + myInterfaceImpl1.newMethod();//调用默认方法 + System.out.println("------"); + MyInterfaceImpl2 myInterfaceImpl2 = new MyInterfaceImpl2(); + myInterfaceImpl2.myMethod(); + myInterfaceImpl2.newMethod();//这里调用了实现类的重写之后的功能(包含沿用父接口的默认功能) + } +} diff --git a/day10/src/com/inmind/default_02/MyInterface.java b/day10/src/com/inmind/default_02/MyInterface.java new file mode 100644 index 0000000..da7e613 --- /dev/null +++ b/day10/src/com/inmind/default_02/MyInterface.java @@ -0,0 +1,22 @@ +package com.inmind.default_02; +/* + 第一个版本的规则,有一个固定功能myMethod + 第二个版本中,需要增加功能 + + 接口是可以升级的,添加新功能,之前添加功能只能通过抽象方法,导致所有的实现类都报错,这样非常麻烦。 + 为了解决该问题,jdk8提供了默认方法来解决 + + 接口中的默认方法的定义格式: + public default 返回值类型 方法名(参数列表){ + 默认实现 + } + + */ +public interface MyInterface { + public abstract void myMethod(); + + //接口中的默认方法 + public default void newMethod(){ + System.out.println("New Method 的默认实现"); + }; +} diff --git a/day10/src/com/inmind/default_02/MyInterfaceImpl1.java b/day10/src/com/inmind/default_02/MyInterfaceImpl1.java new file mode 100644 index 0000000..6adbedd --- /dev/null +++ b/day10/src/com/inmind/default_02/MyInterfaceImpl1.java @@ -0,0 +1,8 @@ +package com.inmind.default_02; + +public class MyInterfaceImpl1 implements MyInterface{ + @Override + public void myMethod() { + System.out.println("My Method"); + } +} diff --git a/day10/src/com/inmind/default_02/MyInterfaceImpl2.java b/day10/src/com/inmind/default_02/MyInterfaceImpl2.java new file mode 100644 index 0000000..1e9e49d --- /dev/null +++ b/day10/src/com/inmind/default_02/MyInterfaceImpl2.java @@ -0,0 +1,17 @@ +package com.inmind.default_02; + +public class MyInterfaceImpl2 implements MyInterface{ + @Override + public void myMethod() { + System.out.println("My Method 2"); + } + + //重写接口的默认方法 + @Override + public void newMethod() { + //沿用父接口的默认功能 + MyInterface.super.newMethod(); + //新增了新的功能实现 + System.out.println("我是重写之后的newMethod功能"); + } +} diff --git a/day10/src/com/inmind/duotai_09/Demo01.java b/day10/src/com/inmind/duotai_09/Demo01.java new file mode 100644 index 0000000..ce46e3a --- /dev/null +++ b/day10/src/com/inmind/duotai_09/Demo01.java @@ -0,0 +1,31 @@ +package com.inmind.duotai_09; +/* +多态的格式和使用 + +多态的前提:【重点】 +继承或者实现【二选一】 +方法的重写【意义体现:不重写,无意义】 +父类引用指向子类对象【格式体现】 +----------------------------------------- +多态中成员变量和成员方法的访问特点 +在多态中的成员变量的访问特点: +1.通过对象直接访问成员变量,对象创建时,=左边是谁,就优先使用谁的成员变量,如果没有向上找 +2.通过对象调用成员方法,间接操作成员变量,方法属于谁,就优先使用谁的方法,如果没有向上找 + +编译看左边,运行看右边!!!! + + */ +public class Demo01 { + public static void main(String[] args) { + Zi zi = new Zi();//不是多态,只是简单创建对象 + System.out.println(zi.numFu); + System.out.println(zi.numZi); + System.out.println("------------------"); + Fu fu = new Zi();//多态的写法 + System.out.println(fu.numFu);//10 + fu.methodFu(); + //fu.methodZi(); + //fu.numZi找不到 访问成员变量,编译看左边,运行看右边,左边是Fu类,Fu类中没有numZi的变量,所以编译报错 + fu.method();//20 + } +} diff --git a/day10/src/com/inmind/duotai_09/Fu.java b/day10/src/com/inmind/duotai_09/Fu.java new file mode 100644 index 0000000..decaf77 --- /dev/null +++ b/day10/src/com/inmind/duotai_09/Fu.java @@ -0,0 +1,13 @@ +package com.inmind.duotai_09; + +public class Fu { + int numFu = 10; + + public void methodFu(){ + System.out.println(numFu); + } + + public void method(){ + System.out.println(numFu); + } +} diff --git a/day10/src/com/inmind/duotai_09/Zi.java b/day10/src/com/inmind/duotai_09/Zi.java new file mode 100644 index 0000000..44849b7 --- /dev/null +++ b/day10/src/com/inmind/duotai_09/Zi.java @@ -0,0 +1,14 @@ +package com.inmind.duotai_09; + +public class Zi extends Fu{ + int numZi = 20; + + public void methodZi(){ + System.out.println(numZi); + } + + @Override + public void method(){ + System.out.println(numZi); + } +} diff --git a/day10/src/com/inmind/extendses_07/Demo.java b/day10/src/com/inmind/extendses_07/Demo.java new file mode 100644 index 0000000..8166b98 --- /dev/null +++ b/day10/src/com/inmind/extendses_07/Demo.java @@ -0,0 +1,10 @@ +package com.inmind.extendses_07; +/* +接口的多继承 + */ +public class Demo { + public static void main(String[] args) { + MyInterface1.staticMethod1(); + MyInterface2.staticMethod2(); + } +} diff --git a/day10/src/com/inmind/extendses_07/MyInterface1.java b/day10/src/com/inmind/extendses_07/MyInterface1.java new file mode 100644 index 0000000..89820fa --- /dev/null +++ b/day10/src/com/inmind/extendses_07/MyInterface1.java @@ -0,0 +1,10 @@ +package com.inmind.extendses_07; + +public interface MyInterface1 { + void method1(); + void method(); + + public static void staticMethod1() { + System.out.println("父接口1的静态方法"); + } +} diff --git a/day10/src/com/inmind/extendses_07/MyInterface2.java b/day10/src/com/inmind/extendses_07/MyInterface2.java new file mode 100644 index 0000000..cf1de2c --- /dev/null +++ b/day10/src/com/inmind/extendses_07/MyInterface2.java @@ -0,0 +1,10 @@ +package com.inmind.extendses_07; + +public interface MyInterface2 { + void method2(); + void method(); + + public static void staticMethod2() { + System.out.println("父接口2的静态方法"); + } +} diff --git a/day10/src/com/inmind/extendses_07/MyInterfaceZi.java b/day10/src/com/inmind/extendses_07/MyInterfaceZi.java new file mode 100644 index 0000000..2bced3d --- /dev/null +++ b/day10/src/com/inmind/extendses_07/MyInterfaceZi.java @@ -0,0 +1,15 @@ +package com.inmind.extendses_07; +/* +类的继承:单继承,一个类永远只有一个父类 + +接口的继承:接口是多继承的,接口可以有多个直接的父接口 +接口的多继承的注意事项: +1.如果是继承,子接口继承所有的父接口的抽象方法,子接口的实现类必须实现所有的抽象方法 +2.如果是继承的父接口中有同名的抽象方法,子接口只会继承一个抽象方法,子接口的实现类也只需要实现一次同名的抽象方法 +3.接口的静态方法不能通过对象调用 +4.接口的静态方法只跟本接口相关,只能通过本接口名.静态方法来调用 +5.常量也类似 + + */ +public interface MyInterfaceZi extends MyInterface1, MyInterface2 { +} diff --git a/day10/src/com/inmind/extendses_07/MyInterfaceZiImpl.java b/day10/src/com/inmind/extendses_07/MyInterfaceZiImpl.java new file mode 100644 index 0000000..7c84682 --- /dev/null +++ b/day10/src/com/inmind/extendses_07/MyInterfaceZiImpl.java @@ -0,0 +1,18 @@ +package com.inmind.extendses_07; + +public class MyInterfaceZiImpl implements MyInterfaceZi { + @Override + public void method1() { + + } + + @Override + public void method() { + + } + + @Override + public void method2() { + + } +} diff --git a/day10/src/com/inmind/impls_06/Demo.java b/day10/src/com/inmind/impls_06/Demo.java new file mode 100644 index 0000000..8129be5 --- /dev/null +++ b/day10/src/com/inmind/impls_06/Demo.java @@ -0,0 +1,12 @@ +package com.inmind.impls_06; +/* +接口的多实现 +12.继承父类并实现多个接口 + + */ +public class Demo { + public static void main(String[] args) { + Zi zi = new Zi(); + zi.method(); + } +} diff --git a/day10/src/com/inmind/impls_06/Fu.java b/day10/src/com/inmind/impls_06/Fu.java new file mode 100644 index 0000000..9016e22 --- /dev/null +++ b/day10/src/com/inmind/impls_06/Fu.java @@ -0,0 +1,9 @@ +package com.inmind.impls_06; + +public abstract class Fu { + abstract void methodFu(); + + public void method(){ + System.out.println("抽象父类中,与接口重名的普通method方法"); + }; +} diff --git a/day10/src/com/inmind/impls_06/MyInterface1.java b/day10/src/com/inmind/impls_06/MyInterface1.java new file mode 100644 index 0000000..e8ad616 --- /dev/null +++ b/day10/src/com/inmind/impls_06/MyInterface1.java @@ -0,0 +1,6 @@ +package com.inmind.impls_06; + +public interface MyInterface1 { + void method1();//抽象方法 + void method(); +} diff --git a/day10/src/com/inmind/impls_06/MyInterface2.java b/day10/src/com/inmind/impls_06/MyInterface2.java new file mode 100644 index 0000000..21be2f2 --- /dev/null +++ b/day10/src/com/inmind/impls_06/MyInterface2.java @@ -0,0 +1,6 @@ +package com.inmind.impls_06; + +public interface MyInterface2 { + void method2();//抽象方法 + void method(); +} diff --git a/day10/src/com/inmind/impls_06/Zi.java b/day10/src/com/inmind/impls_06/Zi.java new file mode 100644 index 0000000..96eb02b --- /dev/null +++ b/day10/src/com/inmind/impls_06/Zi.java @@ -0,0 +1,34 @@ +package com.inmind.impls_06; +/* +单继承多实现的注意事项: +1.非抽象的子类实现类必须重写所有的抽象方法 +2.如果有抽象方法未实现,那么子类实现类必须是抽象类 +3.如果多个接口中有相同的抽象方法,那么非抽象的子类只需要实现一次即可 +4.如果多个接口和抽象父类中有相同的抽象方法,那么非抽象的子类也只需要实现一次即可 +5.如果抽象父类中拥有一个与多个接口中抽象方法,相同的普通方法,那么子类实现类, + 就可以选择性地重写或不重写该抽象方法,类的方法优先于接口的 + + */ +public class Zi extends Fu implements MyInterface1, MyInterface2 { + @Override + public void method1() { + + } + + + @Override + public void method() { + super.method(); + System.out.println("扩展一下method方法"); + } + + @Override + public void method2() { + + } + + @Override + void methodFu() { + + } +} diff --git a/day10/src/com/inmind/interface_01/Demo.java b/day10/src/com/inmind/interface_01/Demo.java new file mode 100644 index 0000000..b33c79b --- /dev/null +++ b/day10/src/com/inmind/interface_01/Demo.java @@ -0,0 +1,16 @@ +package com.inmind.interface_01; +/* +接口的抽象方法的使用步骤: +1.接口不能创建对象的,它没有构造方法 +2.定义一个实现类,实现该接口,并实现接口中的所有的抽象方法 + public class MyInterfaceImpl(实现类) implements MyInterface(接口){ +3.创建该接口的实现类的对象,调用接口的方法 + */ +public class Demo { + public static void main(String[] args) { +// MyInterface myInterface = new MyInterface(); + MyInterfaceImpl myInterface = new MyInterfaceImpl(); + myInterface.method(); + myInterface.method1(); + } +} diff --git a/day10/src/com/inmind/interface_01/MyInterface.java b/day10/src/com/inmind/interface_01/MyInterface.java new file mode 100644 index 0000000..0a8c89c --- /dev/null +++ b/day10/src/com/inmind/interface_01/MyInterface.java @@ -0,0 +1,20 @@ +package com.inmind.interface_01; +/* +接口就是生活中的规范,规则 +定义格式 +public interface 接口名 { +} + +jdk7之前:抽象方法,常量 +jdk8:默认方法,静态方法 +jdk9:私有方法 + +接口中抽象方法定义: +public abstract 返回值类型 抽象方法名(); +但凡在接口中定义一个没有方法体{}的方法,就是public abstract修饰;暂时不省略 + + */ +public interface MyInterface { + public abstract void method(); + void method1();//编译器,前面会自动加上 public abstract +} diff --git a/day10/src/com/inmind/interface_01/MyInterfaceImpl.java b/day10/src/com/inmind/interface_01/MyInterfaceImpl.java new file mode 100644 index 0000000..02fbe27 --- /dev/null +++ b/day10/src/com/inmind/interface_01/MyInterfaceImpl.java @@ -0,0 +1,13 @@ +package com.inmind.interface_01; + +public class MyInterfaceImpl implements MyInterface{ + @Override + public void method() { + System.out.println("MyInterfaceImpl method"); + } + + @Override + public void method1() { + System.out.println("MyInterfaceImpl method1"); + } +} diff --git a/day10/src/com/inmind/interface_duotai11/Demo.java b/day10/src/com/inmind/interface_duotai11/Demo.java new file mode 100644 index 0000000..118c3c3 --- /dev/null +++ b/day10/src/com/inmind/interface_duotai11/Demo.java @@ -0,0 +1,22 @@ +package com.inmind.interface_duotai11; +/* +多态的前提: +1.继承或实现,二选一 +2.要有重写 +3.父类引用指向子类对象 + +接口的多态: +父类类型 对象名 = new 子类类型(); +接口类型 对象名 = new 该接口的实现类对象(); + */ +public class Demo { + public static void main(String[] args) { + //普通的实现类对象创建 + MyInterfaceImpl myInterface = new MyInterfaceImpl(); + + //多态的写法 + MyInterface myInter = new MyInterfaceImpl(); + myInter.show();//运行看右边 + //myInter.method();//编译看左边 + } +} diff --git a/day10/src/com/inmind/interface_duotai11/MyInterface.java b/day10/src/com/inmind/interface_duotai11/MyInterface.java new file mode 100644 index 0000000..bc2dd86 --- /dev/null +++ b/day10/src/com/inmind/interface_duotai11/MyInterface.java @@ -0,0 +1,5 @@ +package com.inmind.interface_duotai11; + +public interface MyInterface { + void show(); +} diff --git a/day10/src/com/inmind/interface_duotai11/MyInterfaceImpl.java b/day10/src/com/inmind/interface_duotai11/MyInterfaceImpl.java new file mode 100644 index 0000000..682a10f --- /dev/null +++ b/day10/src/com/inmind/interface_duotai11/MyInterfaceImpl.java @@ -0,0 +1,11 @@ +package com.inmind.interface_duotai11; + +public class MyInterfaceImpl implements MyInterface{ + @Override + public void show() { + System.out.println("实现类的show方法"); + } + public void method() { + System.out.println("method"); + } +} diff --git a/day10/src/com/inmind/interface_test08/CameraAble.java b/day10/src/com/inmind/interface_test08/CameraAble.java new file mode 100644 index 0000000..456ba0f --- /dev/null +++ b/day10/src/com/inmind/interface_test08/CameraAble.java @@ -0,0 +1,7 @@ +package com.inmind.interface_test08; +/* +扩展拍照的功能 + */ +public interface CameraAble { + void takePicture(); +} diff --git a/day10/src/com/inmind/interface_test08/NetWorkable.java b/day10/src/com/inmind/interface_test08/NetWorkable.java new file mode 100644 index 0000000..dff20f1 --- /dev/null +++ b/day10/src/com/inmind/interface_test08/NetWorkable.java @@ -0,0 +1,6 @@ +package com.inmind.interface_test08; + +//定义一个联网功能 +public interface NetWorkable { + void connectWifi(String wifi); +} diff --git a/day10/src/com/inmind/interface_test08/Powerable.java b/day10/src/com/inmind/interface_test08/Powerable.java new file mode 100644 index 0000000..764c6fa --- /dev/null +++ b/day10/src/com/inmind/interface_test08/Powerable.java @@ -0,0 +1,9 @@ +package com.inmind.interface_test08; + +/* + 基础功能(开机、关机) + */ +public interface Powerable { + void powerOn();//开机 + void powerOff();//关机 +} diff --git a/day10/src/com/inmind/interface_test08/SmartDevice.java b/day10/src/com/inmind/interface_test08/SmartDevice.java new file mode 100644 index 0000000..9796afd --- /dev/null +++ b/day10/src/com/inmind/interface_test08/SmartDevice.java @@ -0,0 +1,7 @@ +package com.inmind.interface_test08; +/* +智能设备的功能集合(接口的多继承的体现) + */ +public interface SmartDevice extends Powerable,NetWorkable { + void checkSystemVersion(); +} diff --git a/day10/src/com/inmind/interface_test08/SmartSpeaker.java b/day10/src/com/inmind/interface_test08/SmartSpeaker.java new file mode 100644 index 0000000..423002c --- /dev/null +++ b/day10/src/com/inmind/interface_test08/SmartSpeaker.java @@ -0,0 +1,33 @@ +package com.inmind.interface_test08; + +public class SmartSpeaker implements SmartDevice{ + private String name; + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + @Override + public void checkSystemVersion() { + System.out.println(this.name+"的系统版本为:2.2"); + } + + @Override + public void connectWifi(String wifi) { + System.out.println(this.name +"音响连接到了"+wifi); + } + + @Override + public void powerOn() { + System.out.println(this.name +"音响开机了"); + } + + @Override + public void powerOff() { + System.out.println(this.name +"音响关机了"); + } +} diff --git a/day10/src/com/inmind/interface_test08/SmartWatch.java b/day10/src/com/inmind/interface_test08/SmartWatch.java new file mode 100644 index 0000000..c194473 --- /dev/null +++ b/day10/src/com/inmind/interface_test08/SmartWatch.java @@ -0,0 +1,40 @@ +package com.inmind.interface_test08; + +//一个智能手表既有智能设备的功能,还有自己独有的功能 +public class SmartWatch implements SmartDevice,CameraAble { + private String name; + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + @Override + public void checkSystemVersion() { + System.out.println(this.name+"的系统版本为:3.2"); + } + + @Override + public void connectWifi(String wifi) { + System.out.println(this.name +"手表连接到了"+wifi); + } + + @Override + public void powerOn() { + System.out.println(this.name +"开机了"); + } + + @Override + public void powerOff() { + System.out.println(this.name +"关机了"); + } + + //手表拥有特殊的功能 + @Override + public void takePicture() { + System.out.println(this.name +"手表拍了照片"); + } +} diff --git a/day10/src/com/inmind/interface_test08/Test.java b/day10/src/com/inmind/interface_test08/Test.java new file mode 100644 index 0000000..8fdb1fd --- /dev/null +++ b/day10/src/com/inmind/interface_test08/Test.java @@ -0,0 +1,27 @@ +package com.inmind.interface_test08; +/* +模拟 “智能设备功能管理” 场景,需设计不同智能设备(智能手表、智能音箱)的功能规范,体现: + +- 基础功能(开机、关机、联网)需抽象为通用接口。 +- 复合功能接口需整合基础接口(接口多继承)。 +- 不同设备根据自身特性实现不同接口组合(类的多实现)。 + */ +public class Test { + public static void main(String[] args) { + //直接创建具体的智能设备 + SmartWatch sw = new SmartWatch(); + sw.setName("apple"); + //手表的智能业务 + sw.powerOn(); + sw.connectWifi("inmind-guest"); + sw.takePicture(); + sw.powerOff(); + + SmartSpeaker sp = new SmartSpeaker(); + sp.setName("小米"); + sp.powerOn(); + sp.checkSystemVersion(); + sp.connectWifi("inmind-guest"); + sp.powerOff(); + } +} diff --git a/day10/src/com/inmind/member_05/Demo.java b/day10/src/com/inmind/member_05/Demo.java new file mode 100644 index 0000000..66d63b2 --- /dev/null +++ b/day10/src/com/inmind/member_05/Demo.java @@ -0,0 +1,10 @@ +package com.inmind.member_05; + +public class Demo { + public static void main(String[] args) { + MyInterfaceImpl myInterface = new MyInterfaceImpl(); +// myInterface.i;接口中的常量只能通过接口名.常量名来调用 + System.out.println(MyInterface.i); + //MyInterface.i = 20;//错误,常量不能改 + } +} diff --git a/day10/src/com/inmind/member_05/MyInterface.java b/day10/src/com/inmind/member_05/MyInterface.java new file mode 100644 index 0000000..27f09e3 --- /dev/null +++ b/day10/src/com/inmind/member_05/MyInterface.java @@ -0,0 +1,10 @@ +package com.inmind.member_05; +/* +接口中定义"成员属性",其实是一个常量,编译器会在成员属性前,默认加上【public static final】 +final:最终,被它修饰的内容就不能更改 +接口中的常量的作用:为接口的行为规范,提供配套的固定值 +接口中的常量如何使用:接口名.常量名来调用 + */ +public interface MyInterface { + public static final int i = 10; +} diff --git a/day10/src/com/inmind/member_05/MyInterfaceImpl.java b/day10/src/com/inmind/member_05/MyInterfaceImpl.java new file mode 100644 index 0000000..cfbd29d --- /dev/null +++ b/day10/src/com/inmind/member_05/MyInterfaceImpl.java @@ -0,0 +1,5 @@ +package com.inmind.member_05; + +public class MyInterfaceImpl implements MyInterface { + +} diff --git a/day10/src/com/inmind/object_cast10/Animal.java b/day10/src/com/inmind/object_cast10/Animal.java new file mode 100644 index 0000000..d42cd3c --- /dev/null +++ b/day10/src/com/inmind/object_cast10/Animal.java @@ -0,0 +1,4 @@ +package com.inmind.object_cast10; +public abstract class Animal { + public abstract void eat(); +} diff --git a/day10/src/com/inmind/object_cast10/Cat.java b/day10/src/com/inmind/object_cast10/Cat.java new file mode 100644 index 0000000..2314930 --- /dev/null +++ b/day10/src/com/inmind/object_cast10/Cat.java @@ -0,0 +1,13 @@ +package com.inmind.object_cast10; + +public class Cat extends Animal { + + @Override + public void eat() { + System.out.println("猫吃鱼"); + } + + public void catchMouse(){ + System.out.println("猫会抓老鼠"); + } +} diff --git a/day10/src/com/inmind/object_cast10/Demo.java b/day10/src/com/inmind/object_cast10/Demo.java new file mode 100644 index 0000000..87f5306 --- /dev/null +++ b/day10/src/com/inmind/object_cast10/Demo.java @@ -0,0 +1,24 @@ +package com.inmind.object_cast10; +/* +对象的向上转型和向下转型:就是引用数据类型的类型转换 + +注意:多态的向下转型,一定要是对应的类型才能转换,否则就报ClassCastException(类型转换异常) + */ +public class Demo { + public static void main(String[] args) { + //使用多态来描述一只猫(父类引用指向子类对象) + Animal animal = new Cat();//对象的向上转型(小范围的数据类型赋值给大范围的数据类型,非常安全) + animal.eat();//编译看左边,运行看右边 + + Animal animal2 = new Dog(); + animal2.eat(); + System.out.println("-------------就要看下猫抓老鼠,狗看门----------------"); + //使用对象的向下转型来获取子类的功能 + Cat cat = (Cat) animal; + cat.catchMouse(); + + //让animal看门 + Dog dog = (Dog) animal2; + dog.watchDoor(); + } +} diff --git a/day10/src/com/inmind/object_cast10/Demo01.java b/day10/src/com/inmind/object_cast10/Demo01.java new file mode 100644 index 0000000..50dc553 --- /dev/null +++ b/day10/src/com/inmind/object_cast10/Demo01.java @@ -0,0 +1,49 @@ +package com.inmind.object_cast10; +/* +如何在代码中判断出当前多态父类类型是不是对应的子类类型呢?? +instanceOf 关键字返回一个boolean + true:就是该类型 (animal是一只猫) + false:不是(animal不是一只狗) + + */ +public class Demo01 { + public static void main(String[] args) { + //来一个猫 + Cat cat = new Cat(); + eat(cat); + //来一个狗 + Dog dog = new Dog(); + eat(dog); + //定义一个动物吃东西的方法 + + } + //使用多态进行了功能的简化(多态的好处的体现) + public static void eat(Animal animal) { + System.out.println("开饭了"); + animal.eat(); + //每个动物吃完,就要执行各自特殊的功能了 + + //---------判断父类引用是否是指定的子类类型-------- + if (animal instanceof Cat) { + Cat cat = (Cat) animal; + cat.catchMouse(); + } + + if (animal instanceof Dog) { + Dog dog = (Dog) animal; + dog.watchDoor(); + } + } + + + /* public static void eat(Cat cat) { + System.out.println("开饭了"); + cat.eat(); + } + + public static void eat(Dog dog) { + System.out.println("开饭了"); + dog.eat(); + }*/ + +} diff --git a/day10/src/com/inmind/object_cast10/Dog.java b/day10/src/com/inmind/object_cast10/Dog.java new file mode 100644 index 0000000..5693c24 --- /dev/null +++ b/day10/src/com/inmind/object_cast10/Dog.java @@ -0,0 +1,12 @@ +package com.inmind.object_cast10; + +public class Dog extends Animal{ + @Override + public void eat() { + System.out.println("狗吃骨头"); + } + + public void watchDoor() { + System.out.println("狗会看门"); + } +} diff --git a/day10/src/com/inmind/private_04/Demo.java b/day10/src/com/inmind/private_04/Demo.java new file mode 100644 index 0000000..e0c761a --- /dev/null +++ b/day10/src/com/inmind/private_04/Demo.java @@ -0,0 +1,7 @@ +package com.inmind.private_04; +/* +jdk9提供的接口中的私有方法 +private + */ +public class Demo { +} diff --git a/day10/src/com/inmind/private_04/Myinterface.java b/day10/src/com/inmind/private_04/Myinterface.java new file mode 100644 index 0000000..ebb48dd --- /dev/null +++ b/day10/src/com/inmind/private_04/Myinterface.java @@ -0,0 +1,54 @@ +package com.inmind.private_04; + +import java.sql.SQLOutput; + +/* +既有默认方法,和静态方法,有可能出来在一个接口中有很多这些方法 + +接口的私有方法的作用:对接口中默认方法来调用的,可以将相同的重复的功能代码进行抽取优化,也可以对静态方法进行抽取 + +私有方法的定义格式: + private (static) 返回值类型 方法名(参数列表) { + java方法体 + } + */ +public interface Myinterface { + public default void defaultMethod1() { + commonMethod(); + + System.out.println("defaultMethod1的功能"); + } + + public default void defaultMethod2() { + commonMethod(); + + System.out.println("defaultMethod2的功能"); + } + + //jdk9中的私有方法 + private void commonMethod() { + //功能实现 + System.out.println("hello"); + System.out.println("world"); + System.out.println("java"); + } + //---------------------------------------------- + public static void staticMethod1() { + commonStaticMethod(); + System.out.println("staticMethod1实现1"); + } + + public static void staticMethod2() { + commonStaticMethod(); + System.out.println("staticMethod2实现2"); + } + + //jdk9中的私有静态方法 + private static void commonStaticMethod() { + //功能实现 + System.out.println("hello"); + System.out.println("world"); + System.out.println("java"); + } + +} diff --git a/day10/src/com/inmind/static_03/Demo.java b/day10/src/com/inmind/static_03/Demo.java new file mode 100644 index 0000000..1bb7cc4 --- /dev/null +++ b/day10/src/com/inmind/static_03/Demo.java @@ -0,0 +1,24 @@ +package com.inmind.static_03; +/* +jdk8提供的接口中的静态方法 +接口中的静态方法的作用:封装接口相关的通用的功能,给相关实现类作为辅助工具的方法 + +类中的静态:只跟类有关,跟对象无关 +类中的静态调用: + 1.对象名.静态内容(不推荐) + 2.类名.静态内容(推荐) + +接口的静态方法 +1.是否通过对象调用静态方法的形式来操作???不能 +2.只能通过接口名.静态方法来调用 + 接口的静态方法不能通过实现类对象调用或操作,由于接口的多继承导致 + */ +public class Demo { + public static void main(String[] args) { + MyInterfaceImpl1 myInterfaceImpl1 = new MyInterfaceImpl1(); + //通过接口实现类调用接口的静态方法, + // myInterfaceImpl1.staticMethod();错误 + //MyInterfaceImpl1.staticMethod();错误 + MyInterface.staticMethod(); + } +} diff --git a/day10/src/com/inmind/static_03/MyInterface.java b/day10/src/com/inmind/static_03/MyInterface.java new file mode 100644 index 0000000..cad1f29 --- /dev/null +++ b/day10/src/com/inmind/static_03/MyInterface.java @@ -0,0 +1,16 @@ +package com.inmind.static_03; +/* + 定义静态方法格式 + public static 返回值类型 方法名(参数列表){ + 方法体 + }; + + */ +public interface MyInterface { + public abstract void myMethod(); + + //接口中的静态方法 + public static void staticMethod(){ + System.out.println("MyInterface接口中的静态方法"); + }; +} diff --git a/day10/src/com/inmind/static_03/MyInterfaceImpl1.java b/day10/src/com/inmind/static_03/MyInterfaceImpl1.java new file mode 100644 index 0000000..875264e --- /dev/null +++ b/day10/src/com/inmind/static_03/MyInterfaceImpl1.java @@ -0,0 +1,8 @@ +package com.inmind.static_03; + +public class MyInterfaceImpl1 implements MyInterface { + @Override + public void myMethod() { + System.out.println("实现类1的My Method"); + } +} diff --git a/day10/src/com/inmind/text_12/Chargeable.java b/day10/src/com/inmind/text_12/Chargeable.java new file mode 100644 index 0000000..042fca0 --- /dev/null +++ b/day10/src/com/inmind/text_12/Chargeable.java @@ -0,0 +1,28 @@ +package com.inmind.text_12; +/* +可充电接口 + */ +public interface Chargeable { + //充电方法 + void charge(int minutes); + //获取剩余电量 + int getChargeLeft(); + + //私有的静态方法:电量检查 + private static boolean isBatteryOk(int chargeLeft){ + return chargeLeft >=1 && chargeLeft <= 100; + } + + //默认方法:显示电量 + default void showBatteryStatus() { + int chargeLeft = getChargeLeft(); + //电量的判断,1~100正常显示,否则电量数据异常 + boolean isOk = isBatteryOk(chargeLeft); + if (isOk) { + System.out.println("当前的电量:"+chargeLeft+"%"); + }else { + System.out.println("电量数据异常"); + } + + } +} diff --git a/day10/src/com/inmind/text_12/Device.java b/day10/src/com/inmind/text_12/Device.java new file mode 100644 index 0000000..2976c1a --- /dev/null +++ b/day10/src/com/inmind/text_12/Device.java @@ -0,0 +1,81 @@ +package com.inmind.text_12; +/* +- 所有设备均有基础属性:品牌(brand)、型号(model)、价格(price)、电源状态(开机 / 关机) + */ +public abstract class Device { + private String brand; + private String model; + private Double price; + private boolean isPowerOn; + + private static int totalDevices = 0; + + public Device(String brand, String model, Double price) { + this.brand = brand; + this.model = model; + this.price = price; + this.isPowerOn = false; + totalDevices++; + } + + + //显示设备信息(showInfo) + public abstract void showInfo(); + + //开机的方法 + public void powerOn() { + if (!this.isPowerOn) {//当前关机 + this.isPowerOn = true; + System.out.println(this.brand+" "+this.model+"开机了"); + }else{ + System.out.println(this.brand+" "+this.model+"已经是开机状态了"); + } + } + + //开机的方法 + public void powerOff() { + if (this.isPowerOn) {//当前关机 + this.isPowerOn = false; + System.out.println(this.brand+" "+this.model+"关机了"); + }else{ + System.out.println(this.brand+" "+this.model+"已经是关机状态了"); + } + } + + //获取设备总数 + public static int getTotalDevices() { + return totalDevices; + } + + 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 Double getPrice() { + return price; + } + + public void setPrice(Double price) { + this.price = price; + } + + public boolean isPowerOn() { + return isPowerOn; + } + + public void setPowerOn(boolean powerOn) { + isPowerOn = powerOn; + } +} diff --git a/day10/src/com/inmind/text_12/DeviceManager.java b/day10/src/com/inmind/text_12/DeviceManager.java new file mode 100644 index 0000000..26971ba --- /dev/null +++ b/day10/src/com/inmind/text_12/DeviceManager.java @@ -0,0 +1,77 @@ +package com.inmind.text_12; + +import java.util.ArrayList; + +/* +3. **管理功能** + - 设备添加:将新设备加入系统 + - 设备查询:按品牌筛选设备、按类型筛选设备 + - 批量操作:统一开机、统一关机、为所有可充电设备充电 + - 统计功能:实时显示系统中设备的总数量 + */ +public class DeviceManager { + private ArrayList devices; + public DeviceManager() { + devices = new ArrayList<>();; + } + + //添加设备 + public void addDevice(Device device) {//多态!!!! + devices.add(device); + } + + //显示所有设备 + public void showAllDevices() { + for (int i = 0; i < devices.size(); i++) { + Device device = devices.get(i); + device.showInfo();//多态,父类引用指向子类对象 + } + } + //批量操作:统一开机、统一关机、为所有可充电设备充电 + public void poweronAllDevices(){ + for (int i = 0; i < devices.size(); i++) { + Device device = devices.get(i); + device.powerOn(); + } + } + + public void poweroffAllDevices(){ + for (int i = 0; i < devices.size(); i++) { + Device device = devices.get(i); + device.powerOff(); + } + } + + //充电方法 + public void chargerAllDevices(int minutes){ + for (int i = 0; i < devices.size(); i++) { + Device device = devices.get(i); + //判断下该设备是不是充电设备类型如果是,则转为充电设备后,再调用充电功能 + if (device instanceof Chargeable) {//接口的多态 + Chargeable chargeableDevice = (Chargeable) device;//多态!!!!重点 + chargeableDevice.charge(minutes); + System.out.println("当前设备的电量"+chargeableDevice.getChargeLeft()); + } + } + } + + //显示所有的充电 + public void showChargerDevices(){ + System.out.println("==========充电设备============"); + boolean hasChargeDevice = false; + for (int i = 0; i < devices.size(); i++) { + Device device = devices.get(i); + //判断下该设备是不是充电设备类型如果是,则转为充电设备后,再调用充电功能 + if (device instanceof Chargeable) { + hasChargeDevice = true; + device.showInfo(); + } + } + + if (!hasChargeDevice) { + System.out.println("没有可充电的设备"); + } + } + + +} diff --git a/day10/src/com/inmind/text_12/Laptop.java b/day10/src/com/inmind/text_12/Laptop.java new file mode 100644 index 0000000..6dcc614 --- /dev/null +++ b/day10/src/com/inmind/text_12/Laptop.java @@ -0,0 +1,56 @@ +package com.inmind.text_12; +//笔记本类有充电,联网的功能 +public class Laptop extends Device implements NetWorkable,Chargeable{ + private int batteryLevel;//电量 + private int ramSize;//内存大小(GB) + + public Laptop(String brand, String model, Double price,int ramSize) { + super(brand, model, price); + this.ramSize = ramSize; + this.batteryLevel = 70; + } + + @Override + public void showInfo() { + System.out.println("这是一台品牌为"+this.getBrand()+",型号为"+super.getModel()+"的笔记本电脑,价格:"+super.getPrice()+",内存为"+this.ramSize+"的设备"); + } + + @Override + public void charge(int minutes) { + if (minutes <= 0) { + System.out.println("充电时间必须大于0"); + return; + } + System.out.println(getBrand()+" "+getModel()+"充了"+minutes+"电"); + //每5分钟充1% + int chargeValue = minutes/5; + this.batteryLevel += chargeValue; + + if (this.batteryLevel >= 100) { + this.batteryLevel = 100; + } + + } + + @Override + public int getChargeLeft() { + return this.batteryLevel; + } + + @Override + public void connectToNetwork(String wifi) { + //是否开机状态,是否是网络可用状态 + if (isPowerOn() && NetWorkable.isNetWorkAvailable()) { + System.out.println(getBrand()+" "+getModel()+"已连接"+wifi); + } else if (!isPowerOn()) { + System.out.println("请先开机,再连网络"); + }else { + System.out.println("网络不可用,无法连接到"+wifi); + } + } + + @Override + public void disconnectFromNetwork() { + System.out.println(getBrand()+" "+getModel()+"已断开网络连接"); + } +} diff --git a/day10/src/com/inmind/text_12/NetWorkable.java b/day10/src/com/inmind/text_12/NetWorkable.java new file mode 100644 index 0000000..7720417 --- /dev/null +++ b/day10/src/com/inmind/text_12/NetWorkable.java @@ -0,0 +1,17 @@ +package com.inmind.text_12; + +import java.util.Random; + +//可联网接口 +public interface NetWorkable { + //连接网络 + void connectToNetwork(String wifi); + //断开网络 + void disconnectFromNetwork(); + //检查网络可用性的工具类方法 + static boolean isNetWorkAvailable() { + //模拟网络检查 + //0~1表示信号,>0.2那就表示网络可用 + return Math.random() > 0.2; + } +} diff --git a/day10/src/com/inmind/text_12/SmartPhone.java b/day10/src/com/inmind/text_12/SmartPhone.java new file mode 100644 index 0000000..963c3ae --- /dev/null +++ b/day10/src/com/inmind/text_12/SmartPhone.java @@ -0,0 +1,55 @@ +package com.inmind.text_12; +//能手机(Smartphone):可联网、可充电,支持拍照功能 +public class SmartPhone extends Device implements NetWorkable,Chargeable{ + private int batteryLevel;//电量 + private int ramSize;//内存大小(GB) + + public SmartPhone(String brand, String model, Double price,int ramSize) { + super(brand, model, price); + this.ramSize = ramSize; + this.batteryLevel = 80; + } + + @Override + public void charge(int minutes) { + if (minutes <= 0) { + System.out.println("充电时间必须大于0"); + return; + } + System.out.println(getBrand()+" "+getModel()+"充了"+minutes+"电"); + //每5分钟充1% + int chargeValue = minutes/2; + this.batteryLevel += chargeValue; + + if (this.batteryLevel >= 100) { + this.batteryLevel = 100; + } + } + + @Override + public int getChargeLeft() { + return this.batteryLevel; + } + + @Override + public void showInfo() { + System.out.println("这是一台品牌为"+this.getBrand()+",型号为"+super.getModel()+"的智能手机,价格:"+super.getPrice()+",内存为"+this.ramSize+"的设备"); + } + + @Override + public void connectToNetwork(String wifi) { + //是否开机状态,是否是网络可用状态 + if (isPowerOn() && NetWorkable.isNetWorkAvailable()) { + System.out.println(getBrand()+" "+getModel()+"已连接"+wifi); + } else if (!isPowerOn()) { + System.out.println("请先开机,再连网络"); + }else { + System.out.println("网络不可用,无法连接到"+wifi); + } + } + + @Override + public void disconnectFromNetwork() { + System.out.println(getBrand()+" "+getModel()+"已断开网络连接"); + } +} diff --git a/day10/src/com/inmind/text_12/Test.java b/day10/src/com/inmind/text_12/Test.java new file mode 100644 index 0000000..1bafe52 --- /dev/null +++ b/day10/src/com/inmind/text_12/Test.java @@ -0,0 +1,51 @@ +package com.inmind.text_12; +/* + 一、项目背景 + +随着智能设备的普及,学校实验室需要一套简单的设备管理系统,用于统一管理各类电子设备(如智能手机、笔记本电脑、智能电视等)。 +该系统需支持设备的添加、查询、状态管理等功能,同时能体现面向对象编程的核心思想。 + + 二、核心需求 +1. **设备类型管理** + 系统需支持 3 类设备: + - 智能手机(Smartphone):可联网、可充电,支持拍照功能 + - 笔记本电脑(Laptop):可联网、可充电,支持文件存储功能 + - 智能电视(SmartTV):可联网,支持显示屏幕尺寸属性 +2. **设备共性与个性** + - 所有设备均有基础属性:品牌(brand)、型号(model)、价格(price)、电源状态(开机 / 关机) + - 所有设备需实现基础操作:开机(powerOn)、关机(powerOff)、显示设备信息(showInfo) + - 特殊功能通过接口实现: + - 可联网设备:支持连接网络(connectToNetwork)、断开网络(disconnectFromNetwork) + - 可充电设备:支持充电(charge)、显示电量(showBatteryStatus) +3. **管理功能** + - 设备添加:将新设备加入系统 + - 设备查询:按品牌筛选设备、按类型筛选设备 + - 批量操作:统一开机、统一关机、为所有可充电设备充电 + - 统计功能:实时显示系统中设备的总数量 + */ +public class Test { + public static void main(String[] args) { + //创建出设备管理对象 + DeviceManager deviceManager = new DeviceManager(); + + //添加设备 + deviceManager.addDevice(new Laptop("联想","XLL",5999.9,32)); + deviceManager.addDevice(new Laptop("联想222","XLXX",6999.9,64)); + deviceManager.addDevice(new SmartPhone("apple","16proMax",16999.9,512)); + + //显示所有设备 + deviceManager.showAllDevices(); + + //开机所有设备 + deviceManager.poweronAllDevices(); + + //为所有设备充电60分钟 + deviceManager.chargerAllDevices(60); + + //显示所有的充电设备 + deviceManager.showChargerDevices(); + + //关机 + deviceManager.poweroffAllDevices(); + } +} diff --git a/day11/src/com/inmind/class_test09/Armor.java b/day11/src/com/inmind/class_test09/Armor.java new file mode 100644 index 0000000..c1e8cfe --- /dev/null +++ b/day11/src/com/inmind/class_test09/Armor.java @@ -0,0 +1,29 @@ +package com.inmind.class_test09; + +public class Armor { + //防御装的名称 + private String name; + //防御值 + private int protectNumber; + + public Armor(String name, int protectNumber) { + this.name = name; + this.protectNumber = protectNumber; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public int getProtectNumber() { + return protectNumber; + } + + public void setProtectNumber(int protectNumber) { + this.protectNumber = protectNumber; + } +} diff --git a/day11/src/com/inmind/class_test09/Hero.java b/day11/src/com/inmind/class_test09/Hero.java new file mode 100644 index 0000000..1d76f36 --- /dev/null +++ b/day11/src/com/inmind/class_test09/Hero.java @@ -0,0 +1,60 @@ +package com.inmind.class_test09; + +public class Hero { + //英雄角色名 + private String name; + private Weapon weapon; + private Armor armor; + + private Skill skill; + + public Hero() { + } + + public Hero(String name, Weapon weapon, Armor armor) { + this.name = name; + this.weapon = weapon; + this.armor = armor; + } + + //攻击方法 + public void attack(){ + System.out.println(this.name+"英雄,使用了"+this.weapon.getName()+"武器,输出了"+this.weapon.getHurt()+"伤害"); + } + //受保护的功能 + public void protect(){ + System.out.println(this.name+"英雄,使用了"+this.armor.getName()+"护具,防御了"+this.armor.getProtectNumber()+"伤害"); + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public Weapon getWeapon() { + return weapon; + } + + public void setWeapon(Weapon weapon) { + this.weapon = weapon; + } + + public Armor getArmor() { + return armor; + } + + public void setArmor(Armor armor) { + this.armor = armor; + } + + public Skill getSkill() { + return skill; + } + + public void setSkill(Skill skill) { + this.skill = skill; + } +} diff --git a/day11/src/com/inmind/class_test09/Skill.java b/day11/src/com/inmind/class_test09/Skill.java new file mode 100644 index 0000000..1605b28 --- /dev/null +++ b/day11/src/com/inmind/class_test09/Skill.java @@ -0,0 +1,5 @@ +package com.inmind.class_test09; +//定义 了一个技能接口 +public interface Skill { + void outSkill(); +} diff --git a/day11/src/com/inmind/class_test09/Test.java b/day11/src/com/inmind/class_test09/Test.java new file mode 100644 index 0000000..7dd70d6 --- /dev/null +++ b/day11/src/com/inmind/class_test09/Test.java @@ -0,0 +1,40 @@ +package com.inmind.class_test09; +/* +类作为成员变量类型(hero,weapon,armor) +案例:英雄角色,获取武器,获取防御装,闯关 + */ +public class Test { + public static void main(String[] args) { + //开始游戏 + //选择一个英雄 + Hero hero = new Hero(); + hero.setName("德玛西亚"); + + //打开箱子,获取一把武器,屠龙刀 + Weapon weapon = new Weapon("屠龙刀", 10000); + hero.setWeapon(weapon); + //打开箱子,获取一个护具,复活甲 + Armor armor = new Armor("复活甲", 8000); + hero.setArmor(armor); + + //遇到boss + hero.attack(); + + //boss攻击英雄 + hero.protect(); + //boss,掉落了技能书Skill===野火燎原 + System.out.println("boss掉落技能书。。。。。"); + Skill skill = new Skill(){ + + @Override + public void outSkill() { + System.out.println("释放野火燎原,刀刀暴击"); + } + }; + + hero.setSkill(skill); + //释放技能 + Skill heroSkill = hero.getSkill(); + heroSkill.outSkill(); + } +} diff --git a/day11/src/com/inmind/class_test09/Weapon.java b/day11/src/com/inmind/class_test09/Weapon.java new file mode 100644 index 0000000..32df61e --- /dev/null +++ b/day11/src/com/inmind/class_test09/Weapon.java @@ -0,0 +1,29 @@ +package com.inmind.class_test09; + +public class Weapon { + //武器名称 + private String name; + //伤害值 + private int hurt; + + public Weapon(String name, int hurt) { + this.name = name; + this.hurt = hurt; + } + + public int getHurt() { + return hurt; + } + + public void setHurt(int hurt) { + this.hurt = hurt; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } +} diff --git a/day11/src/com/inmind/final_class01/FinalClassDemo.java b/day11/src/com/inmind/final_class01/FinalClassDemo.java new file mode 100644 index 0000000..319f22f --- /dev/null +++ b/day11/src/com/inmind/final_class01/FinalClassDemo.java @@ -0,0 +1,12 @@ +package com.inmind.final_class01; +/* +final关键字用于修饰类:该类不能被继承 +abstract 和final是相互冲突 +被final修饰的类,叫“太监类”或者“最终类" + */ +public final class FinalClassDemo { + String ss; + + void method() { + } +} diff --git a/day11/src/com/inmind/final_class01/ZiClassDemo.java b/day11/src/com/inmind/final_class01/ZiClassDemo.java new file mode 100644 index 0000000..2eb07f7 --- /dev/null +++ b/day11/src/com/inmind/final_class01/ZiClassDemo.java @@ -0,0 +1,4 @@ +package com.inmind.final_class01; + +public class ZiClassDemo { +} diff --git a/day11/src/com/inmind/final_local_var03/Demo.java b/day11/src/com/inmind/final_local_var03/Demo.java new file mode 100644 index 0000000..543b818 --- /dev/null +++ b/day11/src/com/inmind/final_local_var03/Demo.java @@ -0,0 +1,39 @@ +package com.inmind.final_local_var03; + +import java.util.Arrays; + +/* +final关键字用于修饰局部变量 +局部变量: +1.基本数据类型:保存的值是真正的值,表示该值被赋值后,不能被修改 +2.引用数据类型:保存的是地址值,表示引用数据类型地址不能改变,但是地址指向的内容可以修改的 + */ +public class Demo { + public static void main(String[] args) { + method(); + } + + public static void method(){ + final int i = 10;//局部变量被final修饰,不可改变 + //i = 20; + final int j; + j = 30;//被final修饰,变量的定义与赋值分开,那么也只能赋值一次 + //j = 40; + System.out.println(i); + System.out.println(j); + System.out.println("-----------------------------------"); + //final修饰引用数据类型 + final int [] arr = {1,2,3}; + System.out.println(Arrays.toString(arr)); + //修改arr数组中第二个空间的值呢???可以修改,arr中地址0x003没有改变的,改变的是0x003引用着的对内存中的数据空间的值 + arr[1] = 20; + System.out.println(Arrays.toString(arr)); + //arr = new int[10];//这里是新开辟的空间,地址发生了改变,不允许 + System.out.println("---------------------------"); + final Student student = new Student(); + student.name = "张三"; + student.age = 20; + //student = new Student(); + } + +} diff --git a/day11/src/com/inmind/final_local_var03/Student.java b/day11/src/com/inmind/final_local_var03/Student.java new file mode 100644 index 0000000..1d43207 --- /dev/null +++ b/day11/src/com/inmind/final_local_var03/Student.java @@ -0,0 +1,6 @@ +package com.inmind.final_local_var03; + +public class Student { + String name; + int age; +} diff --git a/day11/src/com/inmind/final_member_var04/Demo.java b/day11/src/com/inmind/final_member_var04/Demo.java new file mode 100644 index 0000000..a8d8a1f --- /dev/null +++ b/day11/src/com/inmind/final_member_var04/Demo.java @@ -0,0 +1,19 @@ +package com.inmind.final_member_var04; +/* +final关键字用于修饰成员变量 +成员变量:类中方法外 + */ +public class Demo { + final int i = 10; + final int j;//成员变量是有默认值,就相当于赋值操作 + + public Demo() { + j = 100;//注意点:构造方法中,可以给被final修饰的未赋值的成员变量进行赋值,仅限一次 + } + + public void method() { + + System.out.println(this.i); + //this.i = 20 ; + } +} diff --git a/day11/src/com/inmind/final_method02/Demo01.java b/day11/src/com/inmind/final_method02/Demo01.java new file mode 100644 index 0000000..22c2290 --- /dev/null +++ b/day11/src/com/inmind/final_method02/Demo01.java @@ -0,0 +1,6 @@ +package com.inmind.final_method02; +/* +3.final关键字用于修饰方法:该方法就不能被子类重写 + */ +public class Demo01 { +} diff --git a/day11/src/com/inmind/final_method02/Fu.java b/day11/src/com/inmind/final_method02/Fu.java new file mode 100644 index 0000000..73cb36e --- /dev/null +++ b/day11/src/com/inmind/final_method02/Fu.java @@ -0,0 +1,11 @@ +package com.inmind.final_method02; +//3.final关键字用于修饰方法:该方法就不能被子类重写 +public class Fu { + public final void finalMethod() { + + } + + public void method1(){ + + }; +} diff --git a/day11/src/com/inmind/final_method02/Zi.java b/day11/src/com/inmind/final_method02/Zi.java new file mode 100644 index 0000000..83c6ccb --- /dev/null +++ b/day11/src/com/inmind/final_method02/Zi.java @@ -0,0 +1,13 @@ +package com.inmind.final_method02; + +public class Zi extends Fu{ + /*@Override + public void finalMethod() { + super.finalMethod(); + }*/ + + @Override + public void method1() { + super.method1(); + } +} diff --git a/day11/src/com/inmind/interface_fanhui_var_10/Demo.java b/day11/src/com/inmind/interface_fanhui_var_10/Demo.java new file mode 100644 index 0000000..ad8e814 --- /dev/null +++ b/day11/src/com/inmind/interface_fanhui_var_10/Demo.java @@ -0,0 +1,57 @@ +package com.inmind.interface_fanhui_var_10; +/* +16.接口作为方法的参数和或返回值 + */ +public class Demo { + public static void main(String[] args) { + //来一个人的多态 + Interface_Alive p = new Person(); + /*System.out.println("hello"); + System.out.println("world"); + System.out.println("java"); + p.keepAlive();*/ + keepAlive(p); + + //来一个狗的多态 + Interface_Alive d = new Dog(); + /*System.out.println("hello"); + System.out.println("world"); + System.out.println("java"); + d.keepAlive();*/ + keepAlive(d); + System.out.println("------------------------------"); + getAlive(1).keepAlive(); + getAlive(10).keepAlive(); + } + + public static void keepAlive(Interface_Alive alive) {//接口作为参数列表,一定是多态,接口是不能创建对象的,只能传入实现类对象 + System.out.println("hello"); + System.out.println("world"); + System.out.println("java"); + alive.keepAlive(); + System.out.println("----------------------"); + + } + + //定义出一个方法,返回值类型是一个接口,根据类型返回指定的实现类对象,1:人 2:狗 + public static Interface_Alive getAlive(int type) { + switch (type) { + case 1: + return new Person(); +// break; + case 2: + return new Dog(); +// break; + default: + return new Interface_Alive(){ + + @Override + public void keepAlive() { + System.out.println("默认的存活方法"); + } + }; +// break; + } + } + +} diff --git a/day11/src/com/inmind/interface_fanhui_var_10/Dog.java b/day11/src/com/inmind/interface_fanhui_var_10/Dog.java new file mode 100644 index 0000000..be80f24 --- /dev/null +++ b/day11/src/com/inmind/interface_fanhui_var_10/Dog.java @@ -0,0 +1,8 @@ +package com.inmind.interface_fanhui_var_10; + +public class Dog implements Interface_Alive{ + @Override + public void keepAlive() { + System.out.println("狗要吃粮"); + } +} diff --git a/day11/src/com/inmind/interface_fanhui_var_10/Interface_Alive.java b/day11/src/com/inmind/interface_fanhui_var_10/Interface_Alive.java new file mode 100644 index 0000000..42d8a25 --- /dev/null +++ b/day11/src/com/inmind/interface_fanhui_var_10/Interface_Alive.java @@ -0,0 +1,5 @@ +package com.inmind.interface_fanhui_var_10; + +public interface Interface_Alive { + void keepAlive(); +} diff --git a/day11/src/com/inmind/interface_fanhui_var_10/Person.java b/day11/src/com/inmind/interface_fanhui_var_10/Person.java new file mode 100644 index 0000000..0409af5 --- /dev/null +++ b/day11/src/com/inmind/interface_fanhui_var_10/Person.java @@ -0,0 +1,8 @@ +package com.inmind.interface_fanhui_var_10; + +public class Person implements Interface_Alive{ + @Override + public void keepAlive() { + System.out.println("吃饭 睡觉 打豆豆"); + } +} diff --git a/day11/src/com/inmind/limit_05/Demo.java b/day11/src/com/inmind/limit_05/Demo.java new file mode 100644 index 0000000..4facc96 --- /dev/null +++ b/day11/src/com/inmind/limit_05/Demo.java @@ -0,0 +1,29 @@ +package com.inmind.limit_05; +/* +6.四种权限修饰符:可以用来修饰类,方法,成员变量 + public > protected > (default) > private +同一个类中 YES YES YES YES +同一个包 YES YES YES NO +在不同包(父子关系) YES YES NO NO +在不同包(非父子关系) YES NO NO NO + + */ +public class Demo { + private static int num = 10; + static int num1 = 20; + protected static int num2 = 30; + public static int num3 = 40; + + public static void main(String[] args) { + method(); + } + + public static void method() { + System.out.println(num); + System.out.println(num1); + System.out.println(num2); + System.out.println(num3); + } + + +} diff --git a/day11/src/com/inmind/limit_05/Demo1.java b/day11/src/com/inmind/limit_05/Demo1.java new file mode 100644 index 0000000..9e5be66 --- /dev/null +++ b/day11/src/com/inmind/limit_05/Demo1.java @@ -0,0 +1,10 @@ +package com.inmind.limit_05; + +public class Demo1 { + public static void main(String[] args) { +// System.out.println(Demo.num);//private不能访问,只能自己访问 + System.out.println(Demo.num1); + System.out.println(Demo.num2); + System.out.println(Demo.num3); + } +} diff --git a/day11/src/com/inmind/limit_05/sub/Demo2.java b/day11/src/com/inmind/limit_05/sub/Demo2.java new file mode 100644 index 0000000..ec114f3 --- /dev/null +++ b/day11/src/com/inmind/limit_05/sub/Demo2.java @@ -0,0 +1,12 @@ +package com.inmind.limit_05.sub; + +import com.inmind.limit_05.Demo; + +public class Demo2 extends Demo { + public static void main(String[] args) { + //System.out.println(Demo.num);//private不能访问 + //System.out.println(Demo.num1);//默认不能访问 + System.out.println(Demo.num2); + System.out.println(Demo.num3); + } +} diff --git a/day11/src/com/inmind/limit_05/sub/Demo3.java b/day11/src/com/inmind/limit_05/sub/Demo3.java new file mode 100644 index 0000000..d81a0fa --- /dev/null +++ b/day11/src/com/inmind/limit_05/sub/Demo3.java @@ -0,0 +1,12 @@ +package com.inmind.limit_05.sub; + +import com.inmind.limit_05.Demo; + +public class Demo3 { + public static void main(String[] args) { + //System.out.println(Demo.num);//private不能访问 + //System.out.println(Demo.num1);//默认不能访问 + //System.out.println(Demo.num2);//非子类的也不能访问 + System.out.println(Demo.num3); + } +} diff --git a/day11/src/com/inmind/local_inner_class07/Demo.java b/day11/src/com/inmind/local_inner_class07/Demo.java new file mode 100644 index 0000000..b8091ab --- /dev/null +++ b/day11/src/com/inmind/local_inner_class07/Demo.java @@ -0,0 +1,8 @@ +package com.inmind.local_inner_class07; + +public class Demo { + public static void main(String[] args) { + OuterClass outerClass = new OuterClass(); + outerClass.method(); + } +} diff --git a/day11/src/com/inmind/local_inner_class07/OuterClass.java b/day11/src/com/inmind/local_inner_class07/OuterClass.java new file mode 100644 index 0000000..283c624 --- /dev/null +++ b/day11/src/com/inmind/local_inner_class07/OuterClass.java @@ -0,0 +1,44 @@ +package com.inmind.local_inner_class07; +/* +局部内部类:定义方法中 +局部内部类的定义格式: +public class 外部类名{ + + 修饰符 返回值类型 成员方法名(参数列表){ + 方法体 + class 局部内部类名{ + 属性 + 行为 + } + } +} + +注意:局部内部类定义在方法中,随方法的加载而加载,它在定义该类的方法外不能使用 + */ +public class OuterClass { + int outerFiled = 20;//外部类的成员变量 + static int outerFiledS = 30;//外部类的静态变量 + + public void method(){ + int i = 10;//局部变量 + System.out.println(i); + class InnerClass {//类的权限都不能使用,private,protected,pulbic都不能使用,只能默认 + int j = 10;//内部类的成员变量 + public void innerMethod() { + System.out.println(j); + System.out.println(i); + System.out.println(outerFiled); + System.out.println(outerFiledS); + } + } + + InnerClass innerClass = new InnerClass();//创建出一个局部内部类对象 + innerClass.innerMethod(); + } + + + public void method2() { + // 局部内部类定义在方法中,随方法的加载而加载,它在定义该类的方法外不能使用 + //InnerClass innerClass = new InnerClass(); + } +} diff --git a/day11/src/com/inmind/local_inner_class07/OuterClass1.java b/day11/src/com/inmind/local_inner_class07/OuterClass1.java new file mode 100644 index 0000000..f5d1d61 --- /dev/null +++ b/day11/src/com/inmind/local_inner_class07/OuterClass1.java @@ -0,0 +1,23 @@ +package com.inmind.local_inner_class07; +/* +局部内部类访问外部局部变量的final问题 +局部内部类要访问一个外部的局部变量,必须使用final修饰 +为什么?? +因为普通的局部变量是随着方法的压栈而创建的,随方法的销毁而销毁,对于局部内部类而言,它定义的对象是保存在堆内存中的,对它使用的 +的变量有强引用,如果外部的变量随着方法直接销毁掉,会影响局部内部类对象的操作,所以编译器,将这个普通的局部变量,提升为final修饰 +,就不会受方法的出栈的影响,而存在的更久 + */ +public class OuterClass1 { + + public void method(){ + //final int i = 10;//局部变量 + int i = 10;//局部变量--如果内部类访问该变量,当前i默认添加了final + + class InnerClass {//局部内部类 + public void method(){ + System.out.println(i); + } + } + } + +} diff --git a/day11/src/com/inmind/member_inner_class06/Demo01.java b/day11/src/com/inmind/member_inner_class06/Demo01.java new file mode 100644 index 0000000..d63e134 --- /dev/null +++ b/day11/src/com/inmind/member_inner_class06/Demo01.java @@ -0,0 +1,19 @@ +package com.inmind.member_inner_class06; +/* +成员内部类的使用 +1.间接使用:在定义了内部类的外部类中定义相关方法,方法中创建出内部类的对象,在测试类中直接创建外部类对象,调用成员方法的形式,间接访问操作 +2.直接使用:直通通过创建内部类的对象,操作它的属性和行为 +外部类.内部类 对象名 = new 外部类().new 内部类(); + */ +public class Demo01 { + public static void main(String[] args) { + //创建出外部类的对象 + OuterClass outerClass = new OuterClass(); + outerClass.method(); + System.out.println("--------------------"); + OuterClass.InnerClass innerClass = new OuterClass().new InnerClass(); + innerClass.method(); + System.out.println(innerClass.num); + System.out.println(innerClass.num1); + } +} diff --git a/day11/src/com/inmind/member_inner_class06/OuterClass.java b/day11/src/com/inmind/member_inner_class06/OuterClass.java new file mode 100644 index 0000000..5849604 --- /dev/null +++ b/day11/src/com/inmind/member_inner_class06/OuterClass.java @@ -0,0 +1,44 @@ +package com.inmind.member_inner_class06; +/* +成员内部类:定义在类中方法外 +定义格式: +public class 外部类名{ + int i = 0;// + public class 内部类名{ + + } +} + +成员内部类中内容访问的注意事项: +1.内部类是可以直接使用外部类的成员变量 +2.外部类要使用内部类的内容,必须通过创建内部类的对象,来调用 +3.在内部类中,不能使用static修饰的,跟内部类的生命周期 +4.内部类的访问外部类同名的变量,必须通过外部类名.this.成员变量名 + + */ +public class OuterClass { + int num = 10;//成员属性 + static int j = 20;//外部类可以定义静态变量 + + public class InnerClass { + //static int k = 20; + //内部类的成员变量 + int num1 = 20; + int num = 30;//与外部类同名的变量 + //内部类的成员方法 + public void method(){ + System.out.println(num1);//内部类的属性 + System.out.println(num);//内部类的属性 + System.out.println(this.num); + System.out.println(this.num1); + System.out.println(OuterClass.this.num); + } + } + + public void method(){ + //外部类的方法中,访问内部类的属性,创建出内部类对象,才能访问 + InnerClass innerClass = new InnerClass(); + System.out.println(innerClass.num1); + innerClass.method(); + } +} diff --git a/day11/src/com/inmind/member_inner_class06/SameOuterClass.java b/day11/src/com/inmind/member_inner_class06/SameOuterClass.java new file mode 100644 index 0000000..c692e8f --- /dev/null +++ b/day11/src/com/inmind/member_inner_class06/SameOuterClass.java @@ -0,0 +1,29 @@ +package com.inmind.member_inner_class06; +/* +10.内部类的同名变量访问 + */ +public class SameOuterClass { + int i = 10; + int num = 10;//外部类成员变量 + + public class InnerClass { + int num = 20;///内部类成员变量 + + public void methodInner() { + int num = 30;//内部类的局部变量 + System.out.println(num);//30 + System.out.println(this.num);//20 + System.out.println(SameOuterClass.this.num);//10 + } + } + + public void method(){ + int num = 40;///外部类局部变量 + } + + public static void main(String[] args) { + SameOuterClass.InnerClass innerClass = new SameOuterClass().new InnerClass(); + innerClass.methodInner(); + } + +} diff --git a/day11/src/com/inmind/noname_inner_class08/AbstractFu.java b/day11/src/com/inmind/noname_inner_class08/AbstractFu.java new file mode 100644 index 0000000..4ee1cde --- /dev/null +++ b/day11/src/com/inmind/noname_inner_class08/AbstractFu.java @@ -0,0 +1,5 @@ +package com.inmind.noname_inner_class08; + +public abstract class AbstractFu { + public abstract void method(); +} diff --git a/day11/src/com/inmind/noname_inner_class08/Animal.java b/day11/src/com/inmind/noname_inner_class08/Animal.java new file mode 100644 index 0000000..754efd0 --- /dev/null +++ b/day11/src/com/inmind/noname_inner_class08/Animal.java @@ -0,0 +1,9 @@ +package com.inmind.noname_inner_class08; + +public class Animal { + String name; + + public void method(){ + + } +} diff --git a/day11/src/com/inmind/noname_inner_class08/Demo.java b/day11/src/com/inmind/noname_inner_class08/Demo.java new file mode 100644 index 0000000..86ba9d2 --- /dev/null +++ b/day11/src/com/inmind/noname_inner_class08/Demo.java @@ -0,0 +1,68 @@ +package com.inmind.noname_inner_class08; +/* +匿名内部类 :是内部类的简化写法。它的本质是一个带具体实现的 父类或者父接口的 匿名的 子类对象。 +匿名内部类的定义: +{ + String name; + @Override + public void method() { + System.out.println("匿名内部类的method方法执行了"); + } +}; + +总结: + 必须跟new 接口名(){匿名内部类的定义}; + new 抽象类(){匿名内部类的定义}; + new 非final修饰的类(){匿名内部类的定义} + + + */ +public class Demo { + public static void main(String[] args) { + //普通接口的使用(直接创建实现类对象,调用方法) + MyInterfaceImpl myInterface = new MyInterfaceImpl(); + myInterface.method(); + //多态:父类引用指向子类对象 + MyInterface myInterface1 = new MyInterfaceImpl(); + + myInterface1.method(); + /* + 当我们只需要定义出一个接口或者父类的子类,并且该子类只需要使用一次时, + 能不能省略掉MyInterfaceImpl实现类的定义,直接使用接口或父类的匿名内部类 + 当前就是匿名内部类的定义和对象的创建过程 + */ + MyInterface myInterface2 = new MyInterface() { + String name; + @Override + public void method() { + System.out.println("匿名内部类的method方法执行了"); + } + }; + myInterface2.method(); + + System.out.println("--------------抽象父类的匿名内部类的书写---------------------"); + //抽象类的多态 + AbstractFu fu = new Zi(); + fu.method(); + + AbstractFu fu1 = new AbstractFu() { + @Override + public void method() { + System.out.println("匿名内部类的method方法执行,它是AbstractFu的子类"); + } + } ; + fu1.method(); + System.out.println("--------------普通父类的匿名内部类的书写---------------------"); + //普通类的多态 + Animal animal = new Dog(); + animal.method(); + Animal animal1 = new Animal() { + @Override + public void method() { + super.method(); + System.out.println("普通的子类的匿名内部类的method方法"); + } + }; + animal1.method(); + } +} diff --git a/day11/src/com/inmind/noname_inner_class08/Dog.java b/day11/src/com/inmind/noname_inner_class08/Dog.java new file mode 100644 index 0000000..780bf71 --- /dev/null +++ b/day11/src/com/inmind/noname_inner_class08/Dog.java @@ -0,0 +1,9 @@ +package com.inmind.noname_inner_class08; + +public class Dog extends Animal{ + @Override + public void method() { + super.method(); + System.out.println("dog的method方法"); + } +} diff --git a/day11/src/com/inmind/noname_inner_class08/MyInterface.java b/day11/src/com/inmind/noname_inner_class08/MyInterface.java new file mode 100644 index 0000000..49bfe44 --- /dev/null +++ b/day11/src/com/inmind/noname_inner_class08/MyInterface.java @@ -0,0 +1,5 @@ +package com.inmind.noname_inner_class08; + +public interface MyInterface { + void method(); +} diff --git a/day11/src/com/inmind/noname_inner_class08/MyInterfaceImpl.java b/day11/src/com/inmind/noname_inner_class08/MyInterfaceImpl.java new file mode 100644 index 0000000..040e2df --- /dev/null +++ b/day11/src/com/inmind/noname_inner_class08/MyInterfaceImpl.java @@ -0,0 +1,9 @@ +package com.inmind.noname_inner_class08; + +public class MyInterfaceImpl implements MyInterface{ + String name; + @Override + public void method() { + System.out.println("实现类的method方法"); + } +} diff --git a/day11/src/com/inmind/noname_inner_class08/Zi.java b/day11/src/com/inmind/noname_inner_class08/Zi.java new file mode 100644 index 0000000..f1c2be0 --- /dev/null +++ b/day11/src/com/inmind/noname_inner_class08/Zi.java @@ -0,0 +1,8 @@ +package com.inmind.noname_inner_class08; + +public class Zi extends AbstractFu{ + @Override + public void method() { + System.out.println("普通子类的method方法"); + } +} diff --git a/day11/src/com/inmind/test_11/Player.java b/day11/src/com/inmind/test_11/Player.java new file mode 100644 index 0000000..90c790d --- /dev/null +++ b/day11/src/com/inmind/test_11/Player.java @@ -0,0 +1,124 @@ +package com.inmind.test_11; + +import java.util.ArrayList; + +/* +3. 玩家操作功能 +拾取武器:玩家可获取武器并加入自身武器库,若未装备武器则自动装备。 +切换武器:玩家可在已拾取的武器中切换当前使用的武器。 +攻击目标:使用当前装备的武器对敌方玩家发起攻击,输出攻击过程及伤害结果。 +收到伤害,计算血量 + */ +//玩家类 +public class Player { + //玩家姓名 + private String name; + //血量 + private int hp; + //武器包 + private ArrayList weapons; + //当前装备的武器 + private Weapon currentWeapon; + + public Player(String name) { + this.name = name; + this.hp = 100; + this.weapons = new ArrayList<>(); + } + + //拾取武器:玩家可获取武器并加入自身武器库,若未装备武器则自动装备。 + public void pickWeapon(Weapon weapon){ + this.weapons.add(weapon); + //如果当前手上没有装备,立刻武装 + if (this.currentWeapon == null) { + this.currentWeapon = weapon; + } + System.out.println(this.name+"拾取了"+weapon.getName()); + } + + + + //切换武器:玩家可在已拾取的武器中切换当前使用的武器。 + public void switchWeapon(String weaponName){ + //判断武器包中有没有这个武器,有就切换,否则就提示 + boolean flag = false; + for (int i = 0; i < weapons.size(); i++) { + Weapon w = weapons.get(i); + if (w.getName().equals(weaponName)) { + flag = true; + this.currentWeapon = w;//切换武器 + } + } + if (!flag) { + System.out.println(this.name +"没有该武器,切换失败"); + } + + } + + + //攻击目标:使用当前装备的武器对敌方玩家发起攻击,输出攻击过程及伤害结果。 + public void attack(Player target){ + //你是否有武器 + if (this.currentWeapon == null) { + System.out.println(this.name+"没有装备武器"); + return; + } + + //攻击输出信息 + System.out.println(this.name+"使用了"+this.currentWeapon.getName()+"武器,攻击了"+target.getName()); + //使用当前的武器向目标开火 + this.currentWeapon.fire(target); + //如果弹药耗尽,自动换弹 + if (this.currentWeapon.getAmmoCount() == 0) { + this.currentWeapon.reload();//换弹匣 + } + + } + + //收到伤害,计算血量 + public void takeDamage(int damage){ + this.hp -= damage; + if (this.hp <= 0) {//血量的判断 + this.hp = 0; + } + System.out.println(this.name+"收到"+damage+"点伤害,剩余Hp:"+this.hp); + //如果hp已经是0了,淘汰 + if (this.hp == 0) { + System.out.println(this.name+"被淘汰了"); + } + + } + + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public int getHp() { + return hp; + } + + public void setHp(int hp) { + this.hp = hp; + } + + public ArrayList getWeapons() { + return weapons; + } + + public void setWeapons(ArrayList weapons) { + this.weapons = weapons; + } + + public Weapon getCurrentWeapon() { + return currentWeapon; + } + + public void setCurrentWeapon(Weapon currentWeapon) { + this.currentWeapon = currentWeapon; + } +} diff --git a/day11/src/com/inmind/test_11/Test.java b/day11/src/com/inmind/test_11/Test.java new file mode 100644 index 0000000..b56aff1 --- /dev/null +++ b/day11/src/com/inmind/test_11/Test.java @@ -0,0 +1,74 @@ +package com.inmind.test_11; +/* +构建一个模拟 CF 游戏基础对战的系统,具体功能需求如下: +1. 核心角色与阵营 +支持创建至少两名玩家角色,区分 "潜伏者" 和 "保卫者" 阵营(通过名称标识)。 +每个玩家初始生命值固定为 100 点,生命值归 0 时判定为 "被淘汰"。 +2. 武器系统 +支持多种经典武器,包括: +AK47 步枪(伤害 42 点,弹夹容量 30 发) +AWM 狙击枪(伤害 100 点,弹夹容量 10 发) +沙漠之鹰手枪(伤害 25 点,弹夹容量 12 发) +可扩展自定义武器(如 M4A1,伤害 30 点,弹夹容量 30 发)。 +武器需具备基础行为: +开火(消耗 1 发弹药,对目标造成对应伤害); +换弹(当弹药耗尽时自动触发,将弹夹装满); +显示当前剩余弹药数。 +3. 玩家操作功能 +拾取武器:玩家可获取武器并加入自身武器库,若未装备武器则自动装备。 +切换武器:玩家可在已拾取的武器中切换当前使用的武器。 +攻击目标:使用当前装备的武器对敌方玩家发起攻击,输出攻击过程及伤害结果。 +4. 对战流程 +初始化两名玩家并分配初始武器(如潜伏者持 AK47,保卫者持 AWM)。 +模拟多轮对战:玩家交替攻击,展示武器开火、弹药消耗、伤害计算等过程。 +当玩家生命值归 0 时,输出 "被淘汰" 提示,结束该玩家的对战能力。 +5. 交互反馈 +所有操作需输出清晰的文字提示,包括: +玩家拾取 / 切换武器的信息; +攻击过程(如 "潜伏者 - 小明使用 AK47 攻击保卫者 - 小红"); +武器开火效果(如 "🔫 AK47 开火!剩余弹药:29"); +伤害结果(如 "保卫者 - 小红受到 42 点伤害,剩余 HP:58")。 + */ +public class Test { + + /* + 4. 对战流程 + 初始化两名玩家并分配初始武器(如潜伏者持 AK47,保卫者持 AWM)。 + 模拟多轮对战:玩家交替攻击,展示武器开火、弹药消耗、伤害计算等过程。 + 当玩家生命值归 0 时,输出 "被淘汰" 提示,结束该玩家的对战能力。 + */ + public static void main(String[] args) { + Player player1 = new Player("潜伏者-小明"); + Player player2 = new Player("保卫者-小红"); + + //使用武器工厂类,获取武器 + Weapon ak47 = WeaponFactory.createWeapon("AK47"); + player1.pickWeapon(ak47); + + //玩家2获取了2把武器 + player2.pickWeapon(WeaponFactory.createWeapon("AWM")); + + player2.pickWeapon(WeaponFactory.createWeapon("手枪")); + + + //模拟对战 + while (true) { + player1.attack(player2); + System.out.println(); + if (player2.getHp() <= 0) { + System.out.println("游戏结束"); + break; + } + + player2.attack(player1); + player2.switchWeapon("沙漠之鹰"); + System.out.println(); + if (player1.getHp() <= 0) { + System.out.println("游戏结束"); + break; + } + } + + + } +} diff --git a/day11/src/com/inmind/test_11/Weapon.java b/day11/src/com/inmind/test_11/Weapon.java new file mode 100644 index 0000000..4156c14 --- /dev/null +++ b/day11/src/com/inmind/test_11/Weapon.java @@ -0,0 +1,29 @@ +package com.inmind.test_11; +/* +2. 武器系统 +支持多种经典武器,包括: +AK47 步枪(伤害 42 点,弹夹容量 30 发) +AWM 狙击枪(伤害 100 点,弹夹容量 10 发) +沙漠之鹰手枪(伤害 25 点,弹夹容量 12 发) +可扩展自定义武器(如 M4A1,伤害 30 点,弹夹容量 30 发)。 + +武器需具备基础行为: +开火(消耗 1 发弹药,对目标造成对应伤害); +换弹(当弹药耗尽时自动触发,将弹夹装满); +显示当前剩余弹药数。 + */ +public interface Weapon { + //开火的行为,参数为玩家 + void fire(Player player); + //换弹 + void reload(); + + //获取武器的伤害值 + int getDamage(); + + //显示当前剩余弹药数 + int getAmmoCount(); + + //获取自己的名称 + String getName(); +} diff --git a/day11/src/com/inmind/test_11/WeaponFactory.java b/day11/src/com/inmind/test_11/WeaponFactory.java new file mode 100644 index 0000000..9945a5e --- /dev/null +++ b/day11/src/com/inmind/test_11/WeaponFactory.java @@ -0,0 +1,131 @@ +package com.inmind.test_11; +/* +武器工厂的作用 +支持多种经典武器,包括: +AK47 步枪(伤害 42 点,弹夹容量 30 发) +AWM 狙击枪(伤害 100 点,弹夹容量 10 发) +沙漠之鹰手枪(伤害 25 点,弹夹容量 12 发) +可扩展自定义武器(如 M4A1,伤害 30 点,弹夹容量 30 发)。 + + */ +public class WeaponFactory { + public static Weapon createWeapon(String type){ + switch (type){ + case "AK47"://创建AK47 + Weapon weapon = new Weapon() { + private int ammo = 30;//当前的弹药 + private final int maxAmmo = 30; + + @Override + public void fire(Player target) { + if (ammo <= 0) { + System.out.println("弹药耗尽,请换弹"); + return; + } + ammo--;//消耗1发子弹 + target.takeDamage(42);//对目标造成42伤害 + System.out.println("🔫 AK47 开火!剩余弹药:"+this.ammo); + } + + @Override + public void reload() { + System.out.println("🔫 AK47 换弹药中..."); + this.ammo = maxAmmo; + } + + @Override + public int getDamage() { + return 42; + } + + @Override + public int getAmmoCount() { + return this.ammo; + } + + @Override + public String getName() { + return "AK47"; + } + }; + return weapon; +// break; + case "AWM": + return new Weapon() { + private int ammo = 10;//当前的弹药 + private final int maxAmmo = 10; + + @Override + public void fire(Player target) { + if (ammo <= 0) { + System.out.println("弹药耗尽,请换弹"); + return; + } + ammo--;//消耗1发子弹 + target.takeDamage(80);//对目标造成42伤害 + System.out.println("🔫 AWM 开火!剩余弹药:"+this.ammo); + } + + @Override + public void reload() { + System.out.println("🔫 AWM 换弹药中..."); + this.ammo = maxAmmo; + } + + @Override + public int getDamage() { + return 80; + } + + @Override + public int getAmmoCount() { + return this.ammo; + } + + @Override + public String getName() { + return "AWM"; + } + }; +// break; + default: + return new Weapon() { + private int ammo = 12;//当前的弹药 + private final int maxAmmo = 12; + + @Override + public void fire(Player target) { + if (ammo <= 0) { + System.out.println("弹药耗尽,请换弹"); + return; + } + ammo--;//消耗1发子弹 + target.takeDamage(30);//对目标造成42伤害 + System.out.println("🔫 沙漠之鹰 开火!剩余弹药:"+this.ammo); + } + + @Override + public void reload() { + System.out.println("🔫 沙漠之鹰 换弹药中..."); + this.ammo = maxAmmo; + } + + @Override + public int getDamage() { + return 30; + } + + @Override + public int getAmmoCount() { + return this.ammo; + } + + @Override + public String getName() { + return "沙漠之鹰"; + } + }; +// break; + } + } +} diff --git a/dd.jpg b/dd.jpg new file mode 100644 index 0000000..21ade94 Binary files /dev/null and b/dd.jpg differ diff --git a/index.html b/index.html new file mode 100644 index 0000000..182571b --- /dev/null +++ b/index.html @@ -0,0 +1,9 @@ + + + + HelloJava + + +Hello, World! I Love Java! + + \ No newline at end of file diff --git a/list.txt b/list.txt new file mode 100644 index 0000000..d3254a0 Binary files /dev/null and b/list.txt differ diff --git a/s_day01/src/com/inmind/Calendar_04/Demo01.java b/s_day01/src/com/inmind/Calendar_04/Demo01.java new file mode 100644 index 0000000..d71d3cb --- /dev/null +++ b/s_day01/src/com/inmind/Calendar_04/Demo01.java @@ -0,0 +1,17 @@ +package com.inmind.Calendar_04; + +import java.util.Calendar; + +/* + Date类大部分的功能都过时了,那么JDK提供了一个更好用的类辅助Date,Calendar类 + Calendar类是一个抽象类,必须使用它的子类,它比较特殊,通过静态工具方法,返回一个日历对象 + +获取日历对象的方法: + static Calendar getInstance() 使用默认时区和区域设置获取日历。 + */ +public class Demo01 { + public static void main(String[] args) { + Calendar calendar = Calendar.getInstance();//多态 返回了一个GregorianCalendar 对象 + System.out.println(calendar); + } +} diff --git a/s_day01/src/com/inmind/Calendar_04/Demo02.java b/s_day01/src/com/inmind/Calendar_04/Demo02.java new file mode 100644 index 0000000..7c54b9d --- /dev/null +++ b/s_day01/src/com/inmind/Calendar_04/Demo02.java @@ -0,0 +1,18 @@ +package com.inmind.Calendar_04; + +import java.util.Calendar; + +/* +10.Calendar里面的get方法 +int get(int field) 返回给定日历字段的值。 + */ +public class Demo02 { + public static void main(String[] args) { + Calendar calendar = Calendar.getInstance(); + showCalender(calendar); + } + + private static void showCalender(Calendar calendar) { + System.out.println(calendar.get(Calendar.YEAR)+"-"+(calendar.get(Calendar.MONTH)+1)+"-"+calendar.get(Calendar.DAY_OF_MONTH)); + } +} diff --git a/s_day01/src/com/inmind/Calendar_04/Demo03.java b/s_day01/src/com/inmind/Calendar_04/Demo03.java new file mode 100644 index 0000000..5784fab --- /dev/null +++ b/s_day01/src/com/inmind/Calendar_04/Demo03.java @@ -0,0 +1,29 @@ +package com.inmind.Calendar_04; + +import java.util.Calendar; + +/* +Calendar里面的set方法 +void set(int field, int value) 将给定的日历字段设置为给定的值。 +参数一:日历类固定的值 +参数二:修改后的值 +Date类操作时间必须传入毫秒值,日历类提供了直接操作年月日,时分秒的api + */ +public class Demo03 { + public static void main(String[] args) { + Calendar cal = Calendar.getInstance(); + //想将2025-7-25改为2030-7-25 + cal.set(Calendar.YEAR,2030); + showCalender(cal); + //想将2030-7-25改为2030-9-25 + cal.set(Calendar.MONTH,8);//注意:Calendar.MONTH的值从0开始,展示时自动+1 + showCalender(cal); + cal.set(Calendar.DAY_OF_MONTH,33);//对于天数,按照当前月的天数计算,如果超出就月份+1,剩下的天数 + showCalender(cal); + } + + + private static void showCalender(Calendar calendar) { + System.out.println(calendar.get(Calendar.YEAR)+"-"+(calendar.get(Calendar.MONTH)+1)+"-"+calendar.get(Calendar.DAY_OF_MONTH)); + } +} diff --git a/s_day01/src/com/inmind/Calendar_04/Demo04.java b/s_day01/src/com/inmind/Calendar_04/Demo04.java new file mode 100644 index 0000000..59f73e1 --- /dev/null +++ b/s_day01/src/com/inmind/Calendar_04/Demo04.java @@ -0,0 +1,35 @@ +package com.inmind.Calendar_04; + +import java.util.Calendar; +import java.util.Date; + +/* +abstract void add(int field, int amount) 根据日历的规则,将指定的时间量添加或减去给定的日历字段。 +参数一:要修改的字段固定值 +参数二:要增加或减少的值 + +我们可以使用日历对象,操作计算得到想到的时间,又要获取对应的毫秒值时,可以将日历对象转为日期对象 +Date getTime() 返回表示 Calendar的时间值(与 Epoch的毫秒偏移量)的 Date对象。 + */ +public class Demo04 { + public static void main(String[] args) { + Calendar cal = Calendar.getInstance(); + showCalender(cal); + //在当前时间的基础上+2年 + cal.add(Calendar.YEAR,2); + showCalender(cal); + //在当前时间的基础上+10个月 + cal.add(Calendar.MONTH,10); + showCalender(cal); + //在当前时间的基础上-30天 + cal.add(Calendar.DAY_OF_MONTH,7); + showCalender(cal); + //26 27 28 29 30 31 1 + Date date = cal.getTime();//获取日期对象 + System.out.println(date.getTime());//获取日期的毫秒值 + } + + private static void showCalender(Calendar calendar) { + System.out.println(calendar.get(Calendar.YEAR)+"-"+(calendar.get(Calendar.MONTH)+1)+"-"+calendar.get(Calendar.DAY_OF_MONTH)); + } +} diff --git a/s_day01/src/com/inmind/Calendar_04/Demo05.java b/s_day01/src/com/inmind/Calendar_04/Demo05.java new file mode 100644 index 0000000..e6abd4f --- /dev/null +++ b/s_day01/src/com/inmind/Calendar_04/Demo05.java @@ -0,0 +1,40 @@ +package com.inmind.Calendar_04; + +import java.util.Date; + +/* +Date Calendar类是在jdk8之前的日期操作,是有一些弊端 + +JDK8之后的日期操作新类: +Calendar的替代: + LocalDate + LocalTime + LocatDateTime + ZoneId + ZoneDateTime +Date替代: + Instant + +DateFormat的替代: + DateTimeFormatter + + + + */ +public class Demo05 { + public static void main(String[] args) { + //1.设计不合理,很多功能已经废弃 + Date date = new Date(); + + //2.Date,Calendar的值可以被修改掉,会丢失原本的数据 + + //3.线程不安全 + + //4.Date只能精确到毫秒,新的api能够精确到纳秒 + /* + 1秒 = 1000毫秒 + 1毫秒 = 1000微秒 + 1微秒 = 1000纳秒 + */ + } +} diff --git a/s_day01/src/com/inmind/DateFormat_03/Demo01.java b/s_day01/src/com/inmind/DateFormat_03/Demo01.java new file mode 100644 index 0000000..44fdeb2 --- /dev/null +++ b/s_day01/src/com/inmind/DateFormat_03/Demo01.java @@ -0,0 +1,34 @@ +package com.inmind.DateFormat_03; + +import java.text.SimpleDateFormat; +import java.util.Date; +import java.util.SimpleTimeZone; + +/* + Date展示的时间,使用歪果仁喜欢的时间,中国人不喜欢,能不能变成熟悉的年月日时分秒?? + 可以,使用java中DateFormat类,但是它是抽象类,我们必须使用它的子类SimpleDateFormat + + 构造方法: + SimpleDateFormat(String pattern) 使用给定模式构建一个 SimpleDateFormat ,默认日期格式符号为默认的 FORMAT区域设置。 + + 字母模式: y 表示年 M表示月 d表示日 H表示时 m表示分 s表示秒 S表示毫秒 + + 希望展示的时间:2025年07月25日 11时11分11秒 + 对应的模式:yyyy年MM月dd日 HH时mm分ss秒 + + 常用方法: + String format(Date date) 将日期对象格式化成日期/时间字符串。 + + */ +public class Demo01 { + public static void main(String[] args) { + //创建出一个日期格式化对象 + SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); + //String format(Date date) 将日期对象格式化成日期/时间字符串 + Date date = new Date(); + System.out.println(date); + //将date转为日期字符串展示 + String formatDateStr = sdf.format(date); + System.out.println(formatDateStr); + } +} diff --git a/s_day01/src/com/inmind/DateFormat_03/Demo02.java b/s_day01/src/com/inmind/DateFormat_03/Demo02.java new file mode 100644 index 0000000..14ec889 --- /dev/null +++ b/s_day01/src/com/inmind/DateFormat_03/Demo02.java @@ -0,0 +1,23 @@ +package com.inmind.DateFormat_03; + +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.util.Date; + +/* + 网页上用户直接输入一个时间,但是对于我们后台服务而言,字符串只能展示,程序想要的是一个时间点对象,从而操作时间. + 需要将字符串重新转为Date对象 + Date parse(String source) 从给定字符串的开始解析文本以生成日期。 + 执行步骤: + 1.创建对象 + 2.调用解析方法 + */ +public class Demo02 { + public static void main(String[] args) throws ParseException { + SimpleDateFormat sdf = new SimpleDateFormat("yyyy年MM月dd日 HH:mm:ss"); + String time = "2025年07月25日 11:17:32"; + //获取time代表的时间的毫秒值 + Date date = sdf.parse(time); + System.out.println(date.getTime()); + } +} diff --git a/s_day01/src/com/inmind/DateFormat_03/Test03.java b/s_day01/src/com/inmind/DateFormat_03/Test03.java new file mode 100644 index 0000000..539399c --- /dev/null +++ b/s_day01/src/com/inmind/DateFormat_03/Test03.java @@ -0,0 +1,36 @@ +package com.inmind.DateFormat_03; + +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.util.Date; +import java.util.Scanner; + +/* +练习:根据生日求出已经活了多少天 +实现分析: + 1.scanner输入生日 + 2.使用格式化类,将生日转为日期对象 + 3.获取出生时的毫秒值 + 4.获取当前的毫秒值 + 5.计算活了多少毫秒值 + 6.将毫秒值转为天数 + */ +public class Test03 { + public static void main(String[] args) throws ParseException { + //1.scanner输入生日 + Scanner scanner = new Scanner(System.in); + System.out.println("请输入您的生日(例如:2000-01-01)"); + String birthdayStr = scanner.nextLine(); + //2.使用格式化类,将生日转为日期对象 + SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd"); + Date birthdayDate = sdf.parse(birthdayStr); + //3.获取出生时的毫秒值 + long birTime = birthdayDate.getTime(); + //4.获取当前的毫秒值 + long currentTime = new Date().getTime(); + //5.计算活了多少毫秒值 + long liveTime = currentTime - birTime; + //6.将毫秒值转为天数 + System.out.println("您活了"+(liveTime/(24*60*60*1000))+"天"); + } +} diff --git a/s_day01/src/com/inmind/date_02/Demo01.java b/s_day01/src/com/inmind/date_02/Demo01.java new file mode 100644 index 0000000..196c634 --- /dev/null +++ b/s_day01/src/com/inmind/date_02/Demo01.java @@ -0,0 +1,43 @@ +package com.inmind.date_02; + +import java.util.Date; + +/* + 在java中有一个类Date,表示日期时间的瞬间,精确到毫秒值 + + date类的构造方法: + Date() :无参构造方法,以当前的系统时间来创建出date对象 + Date(long date) 有参构造方法,根据传入的指定的毫秒值来创建出date对象 + 指定的毫秒值:从1970年1月1日(计算机的基准时间)起,经过的毫秒值 + + 中国处于:东八区 + + Date类的常用方法: + long getTime() 返回自1970年1月1日以来,date对象所经过的毫秒值。 + void setTime(long time) 将此 Date对象设置为1970年1月1日00:00:00起经过的毫秒值 + + + */ +public class Demo01 { + public static void main(String[] args) { + //Date():无参构造方法,以当前的系统时间来创建出date对象 + Date date = new Date(); + System.out.println(date);//重写toString + + //我想要一个1970年1月1日的date对象 + Date date1 = new Date(0); + System.out.println(date1); + + //想要一个1970年1月2日的date对象 + Date date2 = new Date(24 * 60 * 60 * 1000); + System.out.println(date2); + + System.out.println("------------------常用方法------------------"); + //long getTime() 返回自1970年1月1日以来,date对象所经过的毫秒值。 + long time = date.getTime();//1970~现在经过的毫秒值 + System.out.println(time); + //void setTime(long time) 将此 Date对象设置为1970年1月1日00:00:00起经过的毫秒值 + date.setTime(0);//修改了当前的date对象的时间,为1970年1月1日00:00:00开始,经过0毫秒之后的值 + System.out.println(date); + } +} diff --git a/s_day01/src/com/inmind/jdk8_time_06/Dem06.java b/s_day01/src/com/inmind/jdk8_time_06/Dem06.java new file mode 100644 index 0000000..9a54824 --- /dev/null +++ b/s_day01/src/com/inmind/jdk8_time_06/Dem06.java @@ -0,0 +1,39 @@ +package com.inmind.jdk8_time_06; + +import java.time.LocalDateTime; +import java.time.format.DateTimeFormatter; + +/* + 使用新的类DateTimeFormatter 对JDK8的日期操作进行格式化 + 创建出格式化对象方法 + static DateTimeFormatter ofPattern(String pattern) 使用指定的模式创建格式化程序。 + 字母模式: y 表示年 M表示月 d表示日 H表示时 m表示分 s表示秒 S表示毫秒 + + 格式化时间方法: + String format(TemporalAccessor temporal) 使用此格式化程序格式化日期时间对象。(正向格式化) + ------------------------------------------------------------------------------------ + LocalDateTime提供了格式化,解析时间的方法 + String format(DateTimeFormatter formatter) 使用指定的格式化程序格式化此日期时间。 (反向格式化) + + static LocalDateTime parse(CharSequence text) 从 2007-12-03T10:15:30等文本字符串获取 LocalDateTime的实例。 (解析) + + */ +public class Dem06 { + public static void main(String[] args) { + //解析格式对象 + DateTimeFormatter dtf = DateTimeFormatter.ofPattern("yyyy年MM月dd日 HH:mm:ss"); + //获取一个日期对象 + LocalDateTime now = LocalDateTime.now(); + System.out.println(now); + System.out.println("DateTimeFormatter的format方法"+dtf.format(now));//正向格式化 + System.out.println("--------------------------------------------"); + //LocalDateTime提供了一个反向格式化的api,format + String formatStr = now.format(dtf);//反向格式化 + System.out.println("LocalDateTime的format方法:"+formatStr); + + String dateString = "2025年07月25日 15:49:32"; + //将字符串解析为LocalDateTime对象 + LocalDateTime parsedDateTime = LocalDateTime.parse(dateString, dtf); + System.out.println(parsedDateTime); + } +} diff --git a/s_day01/src/com/inmind/jdk8_time_06/Demo01.java b/s_day01/src/com/inmind/jdk8_time_06/Demo01.java new file mode 100644 index 0000000..d0ab5a6 --- /dev/null +++ b/s_day01/src/com/inmind/jdk8_time_06/Demo01.java @@ -0,0 +1,67 @@ +package com.inmind.jdk8_time_06; + +import java.time.LocalDate; + +/* +LocalDate:不可改变的,表示年月日的类 +static LocalDate now() 从默认时区的系统时钟获取当前日期。 + */ +public class Demo01 { + public static void main(String[] args) { + LocalDate localDate = LocalDate.now(); + System.out.println(localDate);//toString方法被重写过了 + //1.获取该日期对象的属性 + int year = localDate.getYear(); + int month = localDate.getMonthValue(); + int day = localDate.getDayOfMonth(); + System.out.println(year); + System.out.println(month); + System.out.println(day); + System.out.println("-----------------------------"); + //2.直接修改某个数据 + //LocalDate withYear(int year) 返回该 LocalDate的副本。 + LocalDate localDate1 = localDate.withYear(2099); + LocalDate localDate2 = localDate.withMonth(12); + LocalDate localDate3 = localDate.withDayOfMonth(10); + System.out.println(localDate); + System.out.println(localDate1); + System.out.println(localDate2); + System.out.println(localDate3); + + System.out.println("-----------------------------"); + //3.把某个字段值加上固定的值plus + //LocalDate plusYears(long yearsToAdd) 以指定的年数返回此 LocalDate的副本。 + LocalDate localDate4 = localDate.plusYears(5); + LocalDate localDate5 = localDate.plusMonths(5); + LocalDate localDate6 = localDate.plusDays(20); + System.out.println(localDate); + System.out.println(localDate4); + System.out.println(localDate5); + System.out.println(localDate6); + + System.out.println("-----------------------------"); + //4.把某个字段值减去固定的值minus + //LocalDate minusYears(long yearsToSubtract) 返回此 LocalDate的副本,并减去指定的年数。 + LocalDate localDate7 = localDate.minusYears(5); + LocalDate localDate8 = localDate.minusMonths(5); + LocalDate localDate9 = localDate.minusDays(20); + System.out.println(localDate); + System.out.println(localDate7); + System.out.println(localDate8); + System.out.println(localDate9); + + System.out.println("-----------------------------"); + //5.直接获取指定的日期对象: + //static LocalDate of(int year, int month, int dayOfMonth) 从一年,一个月和一天获得一个 LocalDate的实例。 + LocalDate localDate10 = LocalDate.of(2099, 9, 9); + System.out.println(localDate10); + + //6、判断时间在前,在后,时间相同的呢???equals isBefore isAfter + //boolean isAfter(ChronoLocalDate other) 检查此日期是否在指定日期之后。 + //boolean isBefore(ChronoLocalDate other) 检查此日期是否在指定日期之前。 + System.out.println(localDate10.isAfter(localDate9));//true + System.out.println(localDate10.isBefore(localDate9));//false + System.out.println(localDate10.equals(localDate9));//false + + } +} diff --git a/s_day01/src/com/inmind/jdk8_time_06/Demo02.java b/s_day01/src/com/inmind/jdk8_time_06/Demo02.java new file mode 100644 index 0000000..8afb171 --- /dev/null +++ b/s_day01/src/com/inmind/jdk8_time_06/Demo02.java @@ -0,0 +1,50 @@ +package com.inmind.jdk8_time_06; + +import java.time.LocalTime; + +/* +LocalTime:表示的是一个时分秒纳秒日期对象 +API与LocalDate类似 + */ +public class Demo02 { + public static void main(String[] args) { + // 0、获取本地时间对象 + LocalTime lt = LocalTime.now(); // 时 分 秒 纳秒 不可变的 + System.out.println(lt); + + // 1、获取时间中的信息 + int hour = lt.getHour(); //时 + int minute = lt.getMinute(); //分 + int second = lt.getSecond(); //秒 + int nano = lt.getNano(); //纳秒 + + // 2、修改时间:withHour、withMinute、withSecond、withNano + LocalTime lt3 = lt.withHour(10); + LocalTime lt4 = lt.withMinute(10); + LocalTime lt5 = lt.withSecond(10); + LocalTime lt6 = lt.withNano(10); + + // 3、加多少:plusHours、plusMinutes、plusSeconds、plusNanos + LocalTime lt7 = lt.plusHours(10); + LocalTime lt8 = lt.plusMinutes(10); + LocalTime lt9 = lt.plusSeconds(10); + LocalTime lt10 = lt.plusNanos(10); + + // 4、减多少:minusHours、minusMinutes、minusSeconds、minusNanos + LocalTime lt11 = lt.minusHours(10); + LocalTime lt12 = lt.minusMinutes(10); + LocalTime lt13 = lt.minusSeconds(10); + LocalTime lt14 = lt.minusNanos(10); + + // 5、获取指定时间的LocalTime对象: + // public static LocalTime of(int hour, int minute, int second) + LocalTime lt15 = LocalTime.of(12, 12, 12); + LocalTime lt16 = LocalTime.of(12, 12, 12); + + // 6、判断2个时间对象,是否相等,在前还是在后: equals isBefore isAfter + System.out.println(lt15.equals(lt16)); // true + System.out.println(lt15.isAfter(lt)); // false + System.out.println(lt15.isBefore(lt)); // true + + } +} diff --git a/s_day01/src/com/inmind/jdk8_time_06/Demo03.java b/s_day01/src/com/inmind/jdk8_time_06/Demo03.java new file mode 100644 index 0000000..11414c1 --- /dev/null +++ b/s_day01/src/com/inmind/jdk8_time_06/Demo03.java @@ -0,0 +1,64 @@ +package com.inmind.jdk8_time_06; + +import java.time.LocalDate; +import java.time.LocalDateTime; +import java.time.LocalTime; + +/* +LocalDateTime类的基本使用 代表的是年月日时分秒纳秒 + */ +public class Demo03 { + public static void main(String[] args) { + // 0、获取本地日期和时间对象。 + LocalDateTime ldt = LocalDateTime.now(); // 年 月 日 时 分 秒 纳秒 + System.out.println(ldt); + + // 1、可以获取日期和时间的全部信息 + int year = ldt.getYear(); // 年 + int month = ldt.getMonthValue(); // 月 + int day = ldt.getDayOfMonth(); // 日 + int dayOfYear = ldt.getDayOfYear(); // 一年中的第几天 + int dayOfWeek = ldt.getDayOfWeek().getValue(); // 获取是周几 + int hour = ldt.getHour(); //时 + int minute = ldt.getMinute(); //分 + int second = ldt.getSecond(); //秒 + int nano = ldt.getNano(); //纳秒 + + // 2、修改时间信息: + // withYear withMonth withDayOfMonth withDayOfYear withHour + // withMinute withSecond withNano + LocalDateTime ldt2 = ldt.withYear(2029); + LocalDateTime ldt3 = ldt.withMinute(59); + + // 3、加多少: + // plusYears plusMonths plusDays plusWeeks plusHours plusMinutes plusSeconds plusNanos + LocalDateTime ldt4 = ldt.plusYears(2); + LocalDateTime ldt5 = ldt.plusMinutes(3); + + // 4、减多少: + // minusDays minusYears minusMonths minusWeeks minusHours minusMinutes minusSeconds minusNanos + LocalDateTime ldt6 = ldt.minusYears(2); + LocalDateTime ldt7 = ldt.minusMinutes(3); + + + // 5、获取指定日期和时间的LocalDateTime对象: + // public static LocalDateTime of(int year, Month month, int dayOfMonth, int hour, + // int minute, int second, int nanoOfSecond) + LocalDateTime ldt8 = LocalDateTime.of(2029, 12, 12, 12, 12, 12, 1222); + LocalDateTime ldt9 = LocalDateTime.of(2029, 12, 12, 12, 12, 12, 1222); + + // 6、 判断2个日期、时间对象,是否相等,在前还是在后: equals、isBefore、isAfter + System.out.println(ldt9.equals(ldt8)); + System.out.println(ldt9.isAfter(ldt)); + System.out.println(ldt9.isBefore(ldt)); + + // 7、可以把LocalDateTime与LocalDate和LocalTime 相互转换 + // public LocalDate toLocalDate() + // public LocalTime toLocalTime() + // public static LocalDateTime of(LocalDate date, LocalTime time) + LocalDate ld = ldt.toLocalDate(); + LocalTime lt = ldt.toLocalTime(); + LocalDateTime ldt10 = LocalDateTime.of(ld, lt); + + } +} \ No newline at end of file diff --git a/s_day01/src/com/inmind/jdk8_time_06/Demo04.java b/s_day01/src/com/inmind/jdk8_time_06/Demo04.java new file mode 100644 index 0000000..21cb68a --- /dev/null +++ b/s_day01/src/com/inmind/jdk8_time_06/Demo04.java @@ -0,0 +1,35 @@ +package com.inmind.jdk8_time_06; + +import java.time.Clock; +import java.time.ZoneId; +import java.time.ZonedDateTime; + +/* +ZoneId 时区对象,每个国家的时间不同,有可能直接获取指定时区的日期对象 + */ +public class Demo04 { + public static void main(String[] args) { + //获取一个系统默认的时区对象 + ZoneId zoneId = ZoneId.systemDefault(); + System.out.println(zoneId.getId()); + System.out.println(zoneId); + + //获取java支持的全部时区的id + //static Set getAvailableZoneIds() 获取一组可用的区域ID。 + //America/New_York + System.out.println(ZoneId.getAvailableZoneIds()); + + //带时区的时间 ZonedDateTie + //根据时区ID字符串获取时区对象 + //static ZoneId of(String zoneId) 从ID获取一个 ZoneId的实例,确保该ID是有效的并且可供使用。 + ZoneId zoneIdNewYork = ZoneId.of("America/New_York"); + //static ZonedDateTime now(ZoneId zone) 从指定时区的系统时钟获取当前的日期时间。 + ZonedDateTime newYorkDateTime = ZonedDateTime.now(zoneIdNewYork); + System.out.println(newYorkDateTime); + + //世界标准时间 + ZonedDateTime now = ZonedDateTime.now(Clock.systemUTC()); + System.out.println(now); + + } +} diff --git a/s_day01/src/com/inmind/jdk8_time_06/Demo05.java b/s_day01/src/com/inmind/jdk8_time_06/Demo05.java new file mode 100644 index 0000000..ebab5a6 --- /dev/null +++ b/s_day01/src/com/inmind/jdk8_time_06/Demo05.java @@ -0,0 +1,27 @@ +package com.inmind.jdk8_time_06; + +import java.time.Instant; + +/* +Instant:时间点,精确到纳秒级,它分为2个部分:年月日时分秒 和 纳秒(2025-07-25T07:23:00.668753300Z) + */ +public class Demo05 { + public static void main(String[] args) { + //static Instant now() 从系统时钟获取当前瞬间。 + Instant instant = Instant.now(); + System.out.println(instant); + + //获取总秒数 + //long getEpochSecond() 从1970-01-01T00:00:00Z的Java时代获取秒数。 + long epochSecond = instant.getEpochSecond(); + System.out.println(epochSecond); + + //获取纳秒数 + int nano = instant.getNano(); + System.out.println(nano); + + //plus 加秒毫秒纳秒 minus减秒毫秒纳秒 + //作用:可以对某段功能,进行纳秒级别的检测,代码执行效率 + + } +} diff --git a/s_day01/src/com/inmind/jdk8_time_06/Demo07.java b/s_day01/src/com/inmind/jdk8_time_06/Demo07.java new file mode 100644 index 0000000..424c6bd --- /dev/null +++ b/s_day01/src/com/inmind/jdk8_time_06/Demo07.java @@ -0,0 +1,28 @@ +package com.inmind.jdk8_time_06; + +import java.time.LocalDate; +import java.time.Period; + +/* +jdk8提供了2个对时间日期计算的便捷的类,计算2个时间点的间隔 +Period:计算日期间隔(年月日) + +Duration:计算时间间隔(时分秒纳秒) + +Period 日期间隔对象的获取 +static Period between(LocalDate a, LocalDate b) 获得一个 Period包括两个日期之间的年数,月份和日期。 + + + */ +public class Demo07 { + public static void main(String[] args) { + LocalDate start = LocalDate.of(2025, 7, 25); + LocalDate end = LocalDate.of(2025, 8, 25); + //获取日期间隔对象 + Period period = Period.between(start, end); + //获取年 月 日的间隔数据 + System.out.println(period.getYears()); + System.out.println(period.getMonths()); + System.out.println(period.getDays()); + } +} diff --git a/s_day01/src/com/inmind/jdk8_time_06/Demo08.java b/s_day01/src/com/inmind/jdk8_time_06/Demo08.java new file mode 100644 index 0000000..d6b3e15 --- /dev/null +++ b/s_day01/src/com/inmind/jdk8_time_06/Demo08.java @@ -0,0 +1,28 @@ +package com.inmind.jdk8_time_06; + +import java.time.Duration; +import java.time.LocalDateTime; + +/* +Duration:计算时间间隔(时分秒纳秒) +static Duration between(Temporal start, Temporal end) 获取表示两个时间对象之间的持续时间的 Duration 。 +注意:Duration支持LocalTime LocalDateTime Instant + + */ +public class Demo08 { + public static void main(String[] args) { + LocalDateTime start = LocalDateTime.of(2025, 10, 10, 10, 10, 10); + LocalDateTime end = LocalDateTime.of(2025, 10, 10, 10, 11, 11); + //获取时间间隔对象 + Duration duration = Duration.between(start, end); + + //获取时间间隔的数据 + System.out.println(duration.toDays()); + System.out.println(duration.toHours()); + System.out.println(duration.toMinutes()); + System.out.println(duration.toSeconds()); + System.out.println(duration.toMillis()); + System.out.println(duration.toNanos()); + + } +} diff --git a/s_day01/src/com/inmind/object_01/Demo01.java b/s_day01/src/com/inmind/object_01/Demo01.java new file mode 100644 index 0000000..207dcc1 --- /dev/null +++ b/s_day01/src/com/inmind/object_01/Demo01.java @@ -0,0 +1,29 @@ +package com.inmind.object_01; +/* +Object类:所有类的父类,java中所有的类直接或者间接继承自Object + +String toString() 返回对象的字符串表示形式。 + +Object类的源码: + public String toString() { + return getClass().getName() + "@" + Integer.toHexString(hashCode()); + } + +注意:在实际开发中,一个对象的地址值对于我们而言,没有太大的帮助,我们程序员希望直接看到对象的内容(属性),那怎么办?? +现在父类object的toString方法,不符合我们需求,我们就在自己类中重写toString方法, + +总结:今后打印对象,如果发现打印是输出了地址,但是我们想看内容,那就应该在对应的类中重写toString,不用手动写,alt+insert自动生成即可 + + */ +public class Demo01 { + public static void main(String[] args) { + Student student = new Student(); + student.setAge(18); + student.setName("张三"); + + System.out.println(student); + //为何学生类的toString重写了,打印对象也变了??因为println(object),底层本身就是调用该对象的toString方法 + String str = student.toString(); + System.out.println(str); + } +} diff --git a/s_day01/src/com/inmind/object_01/Demo02.java b/s_day01/src/com/inmind/object_01/Demo02.java new file mode 100644 index 0000000..dccef8c --- /dev/null +++ b/s_day01/src/com/inmind/object_01/Demo02.java @@ -0,0 +1,34 @@ +package com.inmind.object_01; +/* +boolean equals(Object obj) 指示一些其他对象是否等于本对象。 + +== : + 基本数据类型:比较2个数据是否相同 + 引用数据类型:比较的是地址是否相同 + + +在实际开发中,地址值对我们没有太大的作用,比较关心数据内容,经常将内容相同的2个对象,看作是同一个,要使用Object的equals方法 +Object父类的源码: +public boolean equals(Object obj) { + return (this == obj); + } + +如果父类的内容比较功能,不符合子类的需求,那就重写equals方法 + +总结:每个对象的equals方法继承自Object类,默认使用==比较2个对象是否相同,==比较的是地址,这个 +不符合程序员业务的需求,我们都会在每个自定义类中重写equals,不用手写,直接alt+insert自动生成 + + */ +public class Demo02 { + public static void main(String[] args) { + String str1 = "123"; + String str2 = "123"; + System.out.println(str1 == str2);//true + + Student s1 = new Student("李四", 20); + Student s2 = new Student("李四", 20); + System.out.println(s1 == s2);//比较地址,不符合需求,false + System.out.println(s1.equals(s2));//比较的是内容,true + + } +} diff --git a/s_day01/src/com/inmind/object_01/ObjectsDemo03.java b/s_day01/src/com/inmind/object_01/ObjectsDemo03.java new file mode 100644 index 0000000..a2845dc --- /dev/null +++ b/s_day01/src/com/inmind/object_01/ObjectsDemo03.java @@ -0,0 +1,22 @@ +package com.inmind.object_01; + +import java.util.Objects; + +/* +static boolean equals(Object a, Object b) 返回 true如果参数相等,彼此 false否则。 +Objects类的equals方法的作用:实现2个对象是否相同的判断,底层还是使用参数1的equals(重写),有效地避免空指针异常 + */ +public class ObjectsDemo03 { + public static void main(String[] args) { + Student s1 = new Student("李四", 20); + Student s2 = new Student("李四", 20); + +// s1 = null; + + /*if (s1 != null) { + System.out.println(s1.equals(s2)); + }*/ + boolean equals = Objects.equals(s1, s2); + System.out.println(equals); + } +} diff --git a/s_day01/src/com/inmind/object_01/Student.java b/s_day01/src/com/inmind/object_01/Student.java new file mode 100644 index 0000000..149e0f5 --- /dev/null +++ b/s_day01/src/com/inmind/object_01/Student.java @@ -0,0 +1,76 @@ +package com.inmind.object_01; + +import java.util.Objects; + +public class Student extends Object{ + private String name; + private int age; + + public Student() { + } + + public Student(String name, int age) { + this.name = name; + this.age = age; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public int getAge() { + return age; + } + + public void setAge(int age) { + this.age = age; + } + + /*@Override + public String toString() { + //查看自己的属性 + String str = this.name + "--" + this.age; + return str; + }*/ + + @Override + public String toString() { + return "Student{" + + "name='" + name + '\'' + + ", age=" + age + + '}'; + } + + /*@Override + public boolean equals(Object obj) { + //先判断调用者对象和传入者对象地址是否相同 + if (this == obj) { + return true; + } + //先判断传入对象的类型是不是学生类型 + if(obj instanceof Student) { + //如果是就判断属性内容 + Student other = (Student) obj; + //判断2个学生的内容是否相同 + if (this.name.equals(other.getName()) && this.age == other.getAge()) { + return true; + } else { + return false; + } + }else{ + return false; + } + }*/ + + @Override + public boolean equals(Object o) { + if (o == null || getClass() != o.getClass()) return false; + Student student = (Student) o; + return age == student.age && Objects.equals(name, student.name); + } + +} diff --git a/s_day01/src/com/inmind/stringbuilder_08/Demo01.java b/s_day01/src/com/inmind/stringbuilder_08/Demo01.java new file mode 100644 index 0000000..1fd9c02 --- /dev/null +++ b/s_day01/src/com/inmind/stringbuilder_08/Demo01.java @@ -0,0 +1,61 @@ +package com.inmind.stringbuilder_08; +/* +StringBuilder构造方法: +StringBuilder() 构造一个没有字符的字符串构建器,初始容量为16个字符。 +StringBuilder(String str) 构造一个初始化为指定字符串内容的字符串构建器。 + +常用Api +StringBuilder append(Object b) 将 boolean参数的字符串表示附加到序列中。 +String toString() 返回表示此顺序中的数据的字符串 +StringBuilder reverse() 导致该字符序列被序列的相反代替。 + +StringBuffer跟StringBuilder对应,api一模一样 +StringBuilder线程不安全,效率高 ,StringBuffer线程安全 + */ +public class Demo01 { + public static void main(String[] args) { + String str1 = "Hello"; + String str2 = "world"; + String str3 = "java"; +// String str = ""; + StringBuilder sb = new StringBuilder(); + for (int i = 0; i < 1000000; i++) { + sb.append(str1).append(str2).append(str3); + } + + System.out.println(sb.toString()); + } + + + private static void stringBuilderMethod() { + StringBuilder sb = new StringBuilder("StringBuilder"); + Student student = new Student(); + student.name = "张三"; + student.age = 20; + sb.append(10); + sb.append('a'); + //如果拼接对象,直接拼接该对象的字符串表现形式,也就是toString的返回值 + StringBuilder sb1 = sb.append(1.0F).append(2.0).append(true).append("hello").append(student); + System.out.println(sb); + System.out.println(sb == sb1);//true + + sb.reverse(); + //注意此时sb对象还是一个可变序列,能不能确定下来??变成字符串对象 + String result = sb.toString(); + System.out.println(result); + } + + //错误的字符串拼接 + private static void errorString() { + String str1 = "Hello"; + String str2 = "world"; + String str3 = "java"; + String str = ""; + for (int i = 0; i < 1000000; i++) { + str += str1+str2+str3; + } + + System.out.println(str1+str2+str3); + System.out.println(str); + } +} diff --git a/s_day01/src/com/inmind/stringbuilder_08/Student.java b/s_day01/src/com/inmind/stringbuilder_08/Student.java new file mode 100644 index 0000000..cad4c2c --- /dev/null +++ b/s_day01/src/com/inmind/stringbuilder_08/Student.java @@ -0,0 +1,14 @@ +package com.inmind.stringbuilder_08; + +public class Student { + String name; + int age; + + @Override + public String toString() { + return "Student{" + + "name='" + name + '\'' + + ", age=" + age + + '}'; + } +} diff --git a/s_day01/src/com/inmind/stringjoiner_09/Demo01.java b/s_day01/src/com/inmind/stringjoiner_09/Demo01.java new file mode 100644 index 0000000..374abf9 --- /dev/null +++ b/s_day01/src/com/inmind/stringjoiner_09/Demo01.java @@ -0,0 +1,48 @@ +package com.inmind.stringjoiner_09; + +import java.util.StringJoiner; + +/* +将String[]的内容,按[v1,v2,v3] + +StringJoiner +构造方法 +StringJoiner(CharSequence delimiter) 构造一个 StringJoiner与其中不带字符,没有 prefix或 suffix ,和所提供的副本 delimiter 。 +StringJoiner(CharSequence delimiter, CharSequence prefix, CharSequence suffix) 构造一个 StringJoiner使用的供给拷贝在不带字符 prefix , delimiter和 suffix 。 +常用方法: +StringJoiner add(CharSequence newElement) 将给定的副本 CharSequence值作为下一个元素 StringJoiner值。 +int length() 返回此 StringJoiner的 String表示的 StringJoiner 。 +String toString() 返回当前值,由 prefix ,由 delimiter分隔的值以及 suffix ,除非没有添加任何元素,否则返回 prefix + suffix或 emptyValue字符。 + */ +public class Demo01 { + public static void main(String[] args) { + //创建StringJoiner +// StringJoiner sj = new StringJoiner(","); + StringJoiner sj = new StringJoiner(",","{","}"); + sj.add("a"); + sj.add("b"); + sj.add("c"); + System.out.println(sj); + System.out.println("--------------------------------"); + StringJoiner sj2 = new StringJoiner(",","[","]"); + String[] strArr = {"a","b","c","d","e","f"}; + for (int i = 0; i < strArr.length; i++) { + sj2.add(strArr[i]); + } + System.out.println(sj2); + } + + private static void demo() { + String[] strArr = {"a","b","c","d","e","f"}; + StringBuilder sb = new StringBuilder(); + sb.append("["); + for (int i = 0; i < strArr.length; i++) { + if (i == strArr.length - 1) { + sb.append(strArr[i]).append("]"); + } else { + sb.append(strArr[i]).append(","); + } + } + System.out.println(sb); + } +} diff --git a/s_day01/src/com/inmind/system_07/Demo01.java b/s_day01/src/com/inmind/system_07/Demo01.java new file mode 100644 index 0000000..02d221f --- /dev/null +++ b/s_day01/src/com/inmind/system_07/Demo01.java @@ -0,0 +1,29 @@ +package com.inmind.system_07; + +import java.util.Date; + +/* +System类获取当前系统时刻 +static long currentTimeMillis() 返回当前时间(以毫秒为单位)。 + +作用:以毫秒级别测试一段代码的执行效率,Instant以纳秒级别测试代码的执行效率 + */ +public class Demo01 { + public static void main(String[] args) { + long currentTimeMillis = System.currentTimeMillis(); + System.out.println(currentTimeMillis); + + Date date = new Date();//获取当前系统时间的日期对象 + System.out.println(date.getTime()); + + //记录循环之前的毫秒值 + long start = System.currentTimeMillis(); + for (int i = 0; i < 1000; i++) { + System.out.println(i); + } + //记录循环之后的毫秒值进行计算 + long end = System.currentTimeMillis(); + System.out.println("执行了1000次,消耗了多少毫秒:"+(end-start)); + + } +} diff --git a/s_day01/src/com/inmind/system_07/Demo02.java b/s_day01/src/com/inmind/system_07/Demo02.java new file mode 100644 index 0000000..c9e4de0 --- /dev/null +++ b/s_day01/src/com/inmind/system_07/Demo02.java @@ -0,0 +1,43 @@ +package com.inmind.system_07; + +import java.util.Arrays; + +/* +System中的arrayCopy方法 + +static void arraycopy(Object src, int srcPos, Object dest, int destPos, int length) +将指定源数组中的数组从指定位置复制到目标数组的指定位置。 +参数一src :表示源数组 +参数二srcPos:表示源数组的索引位置 +参数三dest:表示目标数组 +参数四destPos:表示目标数组的索引位置 +参数五length:长度 + +将src数组中前3个元素,复制到dest数组的前3个位置上 +复制元素前: + src数组元素[1,2,3,4,5], + dest数组元素[6,7,8,9,10] +复制元素后: + src数组元素[1,2,3,4,5], + dest数组元素[6,7,4,5,10] + */ +public class Demo02 { + public static void main(String[] args) { + int[] src = {1,2,3,4,5}; + int[] dest = {6,7,8,9,10}; + System.out.println(Arrays.toString(src)); + System.out.println(Arrays.toString(dest)); + //使用arraycopy方法 + /* + 底层源码: + public static native void arraycopy(Object src, int srcPos, + Object dest, int destPos, + int length); + java中JNI:通过java代码调用底层C,C++代码从而操作硬件 + */ + System.arraycopy(src,3,dest,2,2); + System.out.println("----------------转换之后---------------------"); + System.out.println(Arrays.toString(src)); + System.out.println(Arrays.toString(dest)); + } +} diff --git a/s_day01/src/com/inmind/system_07/Demo03.java b/s_day01/src/com/inmind/system_07/Demo03.java new file mode 100644 index 0000000..017a4c2 --- /dev/null +++ b/s_day01/src/com/inmind/system_07/Demo03.java @@ -0,0 +1,35 @@ +package com.inmind.system_07; + +import java.util.ArrayList; +import java.util.Collection; + +/* + System中读取属性和环境变量的方法 + + + */ +public class Demo03 { + public static void main(String[] args) { + Collection dd = new ArrayList<>(); + dd.add(""); + dd.contains(""); + dd.toArray(); + dd.iterator(); + + + //获取java版本 + String version = System.getProperty("java.version"); + System.out.println(version); + //获取操作系统的版本 + String osName = System.getProperty("os.name"); + System.out.println(osName); + + //获取环境变量 path javaHome OSS秘钥ID + String javaHome = System.getenv("JAVA_HOME"); + String path = System.getenv("Path"); + String ossId = System.getenv("OSS_ACCESS_KEY_ID"); + System.out.println(javaHome); + System.out.println(path); + System.out.println(ossId); + } +} diff --git a/s_day01/src/com/inmind/wrap_10/Demo01.java b/s_day01/src/com/inmind/wrap_10/Demo01.java new file mode 100644 index 0000000..06dcfbe --- /dev/null +++ b/s_day01/src/com/inmind/wrap_10/Demo01.java @@ -0,0 +1,33 @@ +package com.inmind.wrap_10; +/* + java中 4类8种基本数据类型,有对应引用数据类型(包装类对应) + byte Byte + short Short + int Integer + long Long + float Float + double Double + char Character + boolean Boolean + + jdk1.5自动拆装箱子 + 拆箱: + 包装类------基本类型 + 装箱 + 基本类型------包装类 + */ +public class Demo01 { + public static void main(String[] args) { + Integer i = 10; + Integer j = 20; + Integer sum = i+j; + System.out.println(sum); + + /* + Integer i = Integer.valueOf(10); + Integer j = Integer.valueOf(20); + Integer sum = Integer.valueOf(i.intValue() + j.intValue()); + System.out.println(sum); + */ + } +} diff --git a/s_day01/src/com/inmind/wrap_10/Demo02.java b/s_day01/src/com/inmind/wrap_10/Demo02.java new file mode 100644 index 0000000..2bf6a5d --- /dev/null +++ b/s_day01/src/com/inmind/wrap_10/Demo02.java @@ -0,0 +1,37 @@ +package com.inmind.wrap_10; +/* +字符串与基本类型的转换 +在实际开发中,我们接收用户输入的字符串,大部分是String,但是我们java进行数据的操作也就是基本类型。 + +需求场景: +基本类型-----String ++ “” +String -----基本类型 +包装类名.parseXXX(字符串) + + */ +public class Demo02 { + public static void main(String[] args) { + //基本类型转字符串 + int i = 10; + String iStr = Integer.toString(i); + String iStr1 = i+""; + //字符串转基本类型 + String str2 = "2.0"; + double d = Double.parseDouble(str2); + System.out.println(d); + + String str3 = "2.0f"; + float f = Float.parseFloat(str3); + System.out.println(f); + + String str4 = "true"; + boolean b = Boolean.parseBoolean(str4); + System.out.println(b); + + //char (特殊的API,字符串转字符) + String str5 = "abc"; + char c = str5.charAt(0); + System.out.println(c); + } +} diff --git a/s_day02/src/com/inmind/collection_01/Demo01.java b/s_day02/src/com/inmind/collection_01/Demo01.java new file mode 100644 index 0000000..20ff848 --- /dev/null +++ b/s_day02/src/com/inmind/collection_01/Demo01.java @@ -0,0 +1,17 @@ +package com.inmind.collection_01; + +import java.util.ArrayList; + +/* +1.ArrayList集合概述以及集合和数组的区别 +数组长度固定,保存引用数据类型的容器 +ArrayList是个长度可变的容器,底层就是一个Object[] + + */ +public class Demo01 { + public static void main(String[] args) { + ArrayList list = new ArrayList(); + list.add("A"); + list.remove(""); + } +} diff --git a/s_day02/src/com/inmind/collection_01/Demo02.java b/s_day02/src/com/inmind/collection_01/Demo02.java new file mode 100644 index 0000000..1c48ae8 --- /dev/null +++ b/s_day02/src/com/inmind/collection_01/Demo02.java @@ -0,0 +1,58 @@ +package com.inmind.collection_01; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; + +/* +Collection接口常用方法 + public boolean add(E e) : 把给定的对象添加到当前集合中 。 + public void clear() :清空集合中所有的元素。 + public boolean remove(E e) : 把给定的对象在当前集合中删除。 + public boolean contains(E e) : 判断当前集合中是否包含给定的对象。 + public boolean isEmpty() : 判断当前集合是否为空。 + public int size() : 返回集合中元素的个数。 + public Object[] toArray() : 把集合中的元素,存储到数组中。 + + */ +public class Demo02 { + public static void main(String[] args) { + + //Collection的多态的写法 + Collection collection = new ArrayList(); + //添加元素 + //public boolean add(E e) : 把给定的对象添加到当前集合中,返回是否添加成功 + boolean addResult = collection.add("张三"); + collection.add("李四"); + collection.add("王五"); + System.out.println(addResult); + System.out.println(collection); + + //public void clear() :清空集合中所有的元素。 + /*collection.clear(); + System.out.println(collection);*/ + + //public boolean remove(E e) : 把给定的对象在当前集合中删除。 + boolean removed = collection.remove("张三"); + System.out.println(removed); + System.out.println(collection); + + //public boolean contains(E e) : 判断当前集合中是否包含给定的对象。 + //如果要对自定义对象Student,使用contains的功能,必须在Student中重写equals,否则它使用的是== + boolean contains = collection.contains("张三"); + boolean contains1 = collection.contains("李四"); + System.out.println(contains);//false + System.out.println(contains1);//true + + //public boolean isEmpty() : 判断当前集合是否为空 + System.out.println(collection.isEmpty()); + + //public int size() : 返回集合中元素的个数。 + System.out.println(collection.size());//2 + + // public Object[] toArray() : 把集合中的元素,存储到数组中(集合转数组类型) + Object[] array = collection.toArray(); + System.out.println(Arrays.toString(array)); + + } +} diff --git a/s_day02/src/com/inmind/foreach_03/Demo01.java b/s_day02/src/com/inmind/foreach_03/Demo01.java new file mode 100644 index 0000000..74cc135 --- /dev/null +++ b/s_day02/src/com/inmind/foreach_03/Demo01.java @@ -0,0 +1,40 @@ +package com.inmind.foreach_03; +/* + 增强for循环遍历数组 + 由于部分集合没有索引,在jdk1.5 出现了一个遍历容器的增强for循环的格式,作用简化迭代器代码 + foreach循环的格式: + for(数据类型 变量名 : 容器名){ + 循环体; + } + 格式中: + 数据类型:容器中存放的数据类型 + 变量名:就是标识符,表示容器中每个元素 + 容器:就是数组或集合 + 循环体:java语句 + + 注意:foreach循环其实是一个语法糖,本质不变,代码简化了,这让程序员像吃了糖一样 + 数组的foreach循环本质是普通for循环 + + + 使用场景: + 1.如果要使用索引,那就使用普通for循环 + 2.如果不要使用索引,那就使用增强for循环 + + 数组名.for自动生成 + */ +public class Demo01 { + public static void main(String[] args) { + int[] arr = {1,2,3,4,5}; + //普通for循环 + for (int i = 0; i < arr.length; i++) { + System.out.println(arr[i]); + } + System.out.println("--------------------------"); + //增强for循环 + for (int element : arr) { + System.out.println(element);//element = arr[i] + } + + + } +} diff --git a/s_day02/src/com/inmind/foreach_03/Demo02.java b/s_day02/src/com/inmind/foreach_03/Demo02.java new file mode 100644 index 0000000..3b77d7b --- /dev/null +++ b/s_day02/src/com/inmind/foreach_03/Demo02.java @@ -0,0 +1,26 @@ +package com.inmind.foreach_03; + +import java.util.ArrayList; + +/* +.增强for循环遍历集合 +注意:集合的foreach循环本质是迭代器,那么所有的单列集合都可以用foreach遍历 + */ +public class Demo02 { + public static void main(String[] args) { + ArrayList list = new ArrayList(); + list.add("A"); + list.add("B"); + list.add("C"); + //普通for循环遍历 + for (int i = 0; i < list.size(); i++) { + System.out.println(list.get(i)); + } + System.out.println("----------------------------"); + //增强for循环 + for (String s : list) { + System.out.println(s); + } + + } +} diff --git a/s_day02/src/com/inmind/generic_04/Demo01.java b/s_day02/src/com/inmind/generic_04/Demo01.java new file mode 100644 index 0000000..0410bc1 --- /dev/null +++ b/s_day02/src/com/inmind/generic_04/Demo01.java @@ -0,0 +1,44 @@ +package com.inmind.generic_04; + +import java.util.ArrayList; + +/* +使用泛型(generic)的概念和好处 +泛型:就是定义了一个未知的类型,当我们使用它时,才确定该类型,直接使用大写的字母来表示即可 +格式为:<大写字母> +比如: Collection 此处E就是一个泛型 + +那么泛型何时确定类型的??? +当我们使用,比如对象创建时确定,如果不使用泛型,默认是Object + +泛型的好处: + 1.使用泛型,可以省略强转的操作 + 2.将运行时期的异常提前到了编译时期,确保了数据的安全性 + + */ +public class Demo01 { + public static void main(String[] args) { + //不使用泛型 + ArrayList list1 = new ArrayList(); + list1.add("张三"); + list1.add("李四"); + list1.add("王五"); + list1.add(100); + System.out.println(list1); + for (Object o : list1) { + String s = (String) o; + System.out.println(s.length()); + } + + System.out.println("----------------------------"); + //使用泛型 + ArrayList list2 = new ArrayList(); + list2.add("张三"); + list2.add("李四"); + list2.add("王五"); + System.out.println(list2); + for (String s : list2) { + System.out.println(s.length()); + } + } +} diff --git a/s_day02/src/com/inmind/generic_04/Demo02.java b/s_day02/src/com/inmind/generic_04/Demo02.java new file mode 100644 index 0000000..76c0ddb --- /dev/null +++ b/s_day02/src/com/inmind/generic_04/Demo02.java @@ -0,0 +1,36 @@ +package com.inmind.generic_04; + +public class Demo02 { + public static void main(String[] args) { + //买一个手机和平板 + Phone phone = new Phone(); + Pad pad = new Pad(); + phone.call(); + pad.play(); + System.out.println("------------------------"); + //找厂家修理手机和平板 + /*Factory factory = new Factory(); + *//*phone = factory.fixPhone(phone); + pad = factory.fixPad(pad);*//* + phone = (Phone) factory.fix(phone); + pad = (Pad) factory.fix(pad); + phone.call(); + pad.play();*/ + + Factory phoneFactory = new Factory<>(); + Phone fixedPhone = phoneFactory.fix(phone); + fixedPhone.call(); + + Factory padFactory = new Factory<>(); + Pad fixPad = padFactory.fix(pad); + fixPad.play(); + + System.out.println("-------------------------"); + //手机厂家的维修工,什么都能修,它想自己搞点外快 + Pad pad1 = phoneFactory.fixAll(pad); + pad1.play(); + + Dog dog = phoneFactory.fixAll(new Dog()); + + } +} diff --git a/s_day02/src/com/inmind/generic_04/Dog.java b/s_day02/src/com/inmind/generic_04/Dog.java new file mode 100644 index 0000000..2831e4a --- /dev/null +++ b/s_day02/src/com/inmind/generic_04/Dog.java @@ -0,0 +1,4 @@ +package com.inmind.generic_04; + +public class Dog { +} diff --git a/s_day02/src/com/inmind/generic_04/Factory.java b/s_day02/src/com/inmind/generic_04/Factory.java new file mode 100644 index 0000000..b937c95 --- /dev/null +++ b/s_day02/src/com/inmind/generic_04/Factory.java @@ -0,0 +1,54 @@ +package com.inmind.generic_04; +/* + 能不能在一个类中定义一个未知的类型,接收的具体是什么类型,就返回该类型,这个数据类型要动态,并省略掉强转操作,避免了 + 类型转换异常??? + 可以,使用泛型类,在类名后加上<大写字母> + + 泛型类的格式: + public class 类名<大写字母> + + 泛型类的A类型,何时确定的呢??? + 创建对象时确定该类型 + --------------------------------------------------------------- + 需求:我们希望在一个工厂类中接私活,定义出一个功能,接收任意类型的数据,动态返回该类型的数据,可以实现吗?? + 可以,只能通过泛型方法 + + 泛型方法格式:表示在一个方法中定义了一个未知的类型 + 方法修饰符 <大写字母> 返回值类型 方法名(参数列表){ + 方法体 + } + 泛型方法的B类型何时确定呢?? + 方法调用时才确定 + + 注意: + 1.泛型在类中和方法中可以定义多个 + 2.泛型类和泛型方法是可以分开定义 + */ +public class Factory { + + + //使用了泛型类中A类型的普通成员方法 + public A fix(A obj){ + System.out.println("修理了设备"); + return obj; + } + + public B fixAll(B a) { + return a; + } + + /*public Object fix(Object obj){ + System.out.println("修理了设备"); + return obj; + }*/ + + /*public Phone fixPhone(Phone phone) { + System.out.println("修理了手机"); + return phone; + } + + public Pad fixPad(Pad pad) { + System.out.println("修理了平板"); + return pad; + }*/ +} diff --git a/s_day02/src/com/inmind/generic_04/Pad.java b/s_day02/src/com/inmind/generic_04/Pad.java new file mode 100644 index 0000000..1e2f2be --- /dev/null +++ b/s_day02/src/com/inmind/generic_04/Pad.java @@ -0,0 +1,8 @@ +package com.inmind.generic_04; + +public class Pad { + public void play(){ + System.out.println("玩平板游戏"); + } + +} diff --git a/s_day02/src/com/inmind/generic_04/Phone.java b/s_day02/src/com/inmind/generic_04/Phone.java new file mode 100644 index 0000000..d096048 --- /dev/null +++ b/s_day02/src/com/inmind/generic_04/Phone.java @@ -0,0 +1,7 @@ +package com.inmind.generic_04; + +public class Phone { + public void call() { + System.out.println("手机打电话"); + } +} diff --git a/s_day02/src/com/inmind/generic_interface_05/Demo01.java b/s_day02/src/com/inmind/generic_interface_05/Demo01.java new file mode 100644 index 0000000..f3a8308 --- /dev/null +++ b/s_day02/src/com/inmind/generic_interface_05/Demo01.java @@ -0,0 +1,17 @@ +package com.inmind.generic_interface_05; +/* +泛型接口的使用 + */ +public class Demo01 { + public static void main(String[] args) { + //情况1,在定义实现类时,明确T为String + MyInterfaceImpl1 myInterfaceImpl1 = new MyInterfaceImpl1(); + myInterfaceImpl1.method1(); + //情况2,在创建时才确定类型 + MyInterfaceImpl2 myInterfaceImpl2 =new MyInterfaceImpl2<>(); + myInterfaceImpl2.method(""); + + MyInterfaceImpl2 myInterfaceImpl3 =new MyInterfaceImpl2<>(); + myInterfaceImpl3.method1(); + } +} diff --git a/s_day02/src/com/inmind/generic_interface_05/MyInterface.java b/s_day02/src/com/inmind/generic_interface_05/MyInterface.java new file mode 100644 index 0000000..92b413e --- /dev/null +++ b/s_day02/src/com/inmind/generic_interface_05/MyInterface.java @@ -0,0 +1,19 @@ +package com.inmind.generic_interface_05; +/* + 泛型接口:在接口中定义一个未知类型 + 泛型接口的格式: + public interface 接口名<大写字母>{ + } + + 泛型接口的泛型类型何时确定??? + 1.在定义实现子类中直接确定泛型的类型 + 2.在实现子类中不确定类型,在创建实现类对象时才确定类型 + */ +public interface MyInterface { + //泛型作为返回值 + T method1(); + //泛型作为参数 + void method(T t); + //泛型作为参数也作为返回值 + T method2(T t); +} diff --git a/s_day02/src/com/inmind/generic_interface_05/MyInterfaceImpl1.java b/s_day02/src/com/inmind/generic_interface_05/MyInterfaceImpl1.java new file mode 100644 index 0000000..352b33a --- /dev/null +++ b/s_day02/src/com/inmind/generic_interface_05/MyInterfaceImpl1.java @@ -0,0 +1,18 @@ +package com.inmind.generic_interface_05; + +public class MyInterfaceImpl1 implements MyInterface{ + @Override + public String method1() { + return ""; + } + + @Override + public void method(String s) { + + } + + @Override + public String method2(String s) { + return ""; + } +} diff --git a/s_day02/src/com/inmind/generic_interface_05/MyInterfaceImpl2.java b/s_day02/src/com/inmind/generic_interface_05/MyInterfaceImpl2.java new file mode 100644 index 0000000..39948d2 --- /dev/null +++ b/s_day02/src/com/inmind/generic_interface_05/MyInterfaceImpl2.java @@ -0,0 +1,18 @@ +package com.inmind.generic_interface_05; + +public class MyInterfaceImpl2 implements MyInterface{ + @Override + public T method1() { + return null; + } + + @Override + public void method(T t) { + + } + + @Override + public T method2(T t) { + return null; + } +} diff --git a/s_day02/src/com/inmind/generic_limit_06/Demo01.java b/s_day02/src/com/inmind/generic_limit_06/Demo01.java new file mode 100644 index 0000000..365bfbd --- /dev/null +++ b/s_day02/src/com/inmind/generic_limit_06/Demo01.java @@ -0,0 +1,61 @@ +package com.inmind.generic_limit_06; + +import java.util.ArrayList; + +/* +13.泛型通配符的使用(了解) ? +当我们要接受一个数据类型,它的泛型不一致,要使用泛型通配符,匹配? + +格式: + :泛型的类型只能是B类型或者B类型的子类;上限 + : 泛型的类型只能是B类型或者B类型的父类;下限 + */ +public class Demo01 { + public static void main(String[] args) { + Persion p1 = new Persion("张三", 18); + Persion p2 = new Persion("张三1", 19); + Persion p3 = new Persion("张三2", 20); + ArrayList persions = new ArrayList<>(); + persions.add(p1); + persions.add(p2); + persions.add(p3); +// foreachPersons(persions); + foreach(persions); + + Student s1 = new Student("张三", 18); + Student s2 = new Student("张三1", 19); + Student s3 = new Student("张三2", 20); + ArrayList students = new ArrayList<>(); + students.add(s1); + students.add(s2); + students.add(s3); +// foreachStudents(students); + foreach(students); + } + + //在是不支持多态 + private static void foreach(ArrayList objects) { + for (Object o : objects) { + System.out.println("hello"); + System.out.println("java"); + System.out.println(o); + } + } + + + /*private static void foreachStudents(ArrayList students) { + for (Student student : students) { + System.out.println("hello"); + System.out.println("java"); + System.out.println(student); + } + }*/ + + /*private static void foreachPersons(ArrayList persions) { + for (Persion persion : persions) { + System.out.println("hello"); + System.out.println("java"); + System.out.println(persion); + } + }*/ +} diff --git a/s_day02/src/com/inmind/generic_limit_06/Persion.java b/s_day02/src/com/inmind/generic_limit_06/Persion.java new file mode 100644 index 0000000..8a05189 --- /dev/null +++ b/s_day02/src/com/inmind/generic_limit_06/Persion.java @@ -0,0 +1,11 @@ +package com.inmind.generic_limit_06; + +public class Persion { + String name; + int age; + + public Persion(String name, int age) { + this.name = name; + this.age = age; + } +} diff --git a/s_day02/src/com/inmind/generic_limit_06/Student.java b/s_day02/src/com/inmind/generic_limit_06/Student.java new file mode 100644 index 0000000..fe96fdd --- /dev/null +++ b/s_day02/src/com/inmind/generic_limit_06/Student.java @@ -0,0 +1,8 @@ +package com.inmind.generic_limit_06; + +public class Student extends Persion{ + + public Student(String name, int age) { + super(name, age); + } +} diff --git a/s_day02/src/com/inmind/iterator_02/Demo01.java b/s_day02/src/com/inmind/iterator_02/Demo01.java new file mode 100644 index 0000000..5d48bf1 --- /dev/null +++ b/s_day02/src/com/inmind/iterator_02/Demo01.java @@ -0,0 +1,57 @@ +package com.inmind.iterator_02; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.Iterator; + +/* +1.为什么要学习迭代器?? +因为单列集合有一部分是没有索引,之前的普通for循环是通过索引获取每个元素,不满足所有单列集合的遍历操作,所以我们要学习一个更通用的遍历方式,迭代器 + +2.如何获取迭代器 +Iterator iterator() 返回此集合中元素的迭代器。 + +3.如何使用迭代器 +boolean hasNext() 如果迭代具有更多元素,则返回 true 。 +E next() 返回迭代中的下一个元素。 +default void remove() 从底层集合中删除此迭代器返回的最后一个元素(可选操作)。 + + */ +public class Demo01 { + public static void main(String[] args) { + //单列集合多态 + Collection collection = new ArrayList(); + collection.add("A"); + collection.add("B"); + collection.add("C"); + System.out.println(collection); + //获取迭代器 + Iterator iterator = collection.iterator(); + + //使用迭代器获取数据 + while (iterator.hasNext()) { + String element = iterator.next(); + if (element.equals("A")) { + iterator.remove();//直接将容器中对应的数据删除 + } + System.out.println(element); + } + System.out.println("程序结束"); + System.out.println(collection); + + /*if (iterator.hasNext()) { + System.out.println(iterator.next()); + } + + if (iterator.hasNext()) { + System.out.println(iterator.next()); + }*/ + + /*String nextElement = iterator.next(); + System.out.println(nextElement);*/ + + //如果超出边界获取数据:java.util.NoSuchElementException + //System.out.println(iterator.next()); + + } +} diff --git a/s_day02/src/com/inmind/test_07/Book.java b/s_day02/src/com/inmind/test_07/Book.java new file mode 100644 index 0000000..86c2363 --- /dev/null +++ b/s_day02/src/com/inmind/test_07/Book.java @@ -0,0 +1,59 @@ +package com.inmind.test_07; + +import java.util.Objects; + +public class Book implements Product{ + private String id;//书id + private String name;//书的名称 + private Double price;//书的价格 + private String author;//作者 + + public Book(String id, String name, Double price, String author) { + this.id = id; + this.name = name; + this.price = price; + this.author = author; + } + + @Override + public String getId() { + return this.id; + } + + @Override + public String getName() { + return this.name; + } + + @Override + public Double getPrice() { + return this.price; + } + + public String getAuthor() { + return author; + } + + public void setAuthor(String author) { + this.author = author; + } + + @Override + public String toString() { + return "Book{" + + "id='" + id + '\'' + + ", name='" + name + '\'' + + ", price=" + price + + ", author='" + author + '\'' + + '}'; + } + + @Override + public boolean equals(Object o) { + if (o == null || getClass() != o.getClass()) return false; + Book book = (Book) o; + return Objects.equals(id, book.id) && Objects.equals(name, book.name) && Objects.equals(price, book.price) && Objects.equals(author, book.author); + } + + +} diff --git a/s_day02/src/com/inmind/test_07/ElectricDevice.java b/s_day02/src/com/inmind/test_07/ElectricDevice.java new file mode 100644 index 0000000..12eb504 --- /dev/null +++ b/s_day02/src/com/inmind/test_07/ElectricDevice.java @@ -0,0 +1,58 @@ +package com.inmind.test_07; + +import java.util.Objects; + +public class ElectricDevice implements Product{ + private String id;//商品id + private String name;//商品的名称 + private Double price;//商品的价格 + private String brand;//品牌 + + public ElectricDevice(String id, String name, Double price, String brand) { + this.id = id; + this.name = name; + this.price = price; + this.brand = brand; + } + + @Override + public String getId() { + return this.id; + } + + @Override + public String getName() { + return this.name; + } + + @Override + public Double getPrice() { + return this.price; + } + + public String getBrand() { + return brand; + } + + public void setBrand(String brand) { + this.brand = brand; + } + + @Override + public String toString() { + return "ElectricDevice{" + + "id='" + id + '\'' + + ", name='" + name + '\'' + + ", price=" + price + + ", brand='" + brand + '\'' + + '}'; + } + + @Override + public boolean equals(Object o) { + if (o == null || getClass() != o.getClass()) return false; + ElectricDevice that = (ElectricDevice) o; + return Objects.equals(id, that.id) && Objects.equals(name, that.name) && Objects.equals(price, that.price) && Objects.equals(brand, that.brand); + } + +} diff --git a/s_day02/src/com/inmind/test_07/Product.java b/s_day02/src/com/inmind/test_07/Product.java new file mode 100644 index 0000000..87aca04 --- /dev/null +++ b/s_day02/src/com/inmind/test_07/Product.java @@ -0,0 +1,9 @@ +package com.inmind.test_07; +/* +商品接口 + */ +public interface Product { + String getId();//商品的ID + String getName();//商品的名称 + Double getPrice();//商品的价格 +} diff --git a/s_day02/src/com/inmind/test_07/ProductManager.java b/s_day02/src/com/inmind/test_07/ProductManager.java new file mode 100644 index 0000000..89ee9c4 --- /dev/null +++ b/s_day02/src/com/inmind/test_07/ProductManager.java @@ -0,0 +1,70 @@ +package com.inmind.test_07; + +import java.util.ArrayList; + +/* +ProductManager只管理商品 + */ +public class ProductManager { + //泛型集合:保存商品记录的容器 + private ArrayList> productRecords = new ArrayList<>(); + + //根据商品的ID,查询库存记录 + public ProductRecord findRecordById(String productId) { + for (ProductRecord record : this.productRecords) { + if (record.getProduct().getId().equals(productId)) { + return record; + } + } + return null; + } + + //添加商品 + public void addProduct(T product,int quantity,String address) { + //查询是否已经存在品尚的库存记录,如果不存在则创建新的 + ProductRecord record = findRecordById(product.getId()); + if (record != null) { + //已存在商品,数量相加即可 + record.setQuantity(record.getQuantity()+quantity); + }else{ + //如果不存在,保存新的商品记录 + ProductRecord newRecord = new ProductRecord<>(product,quantity,address); + this.productRecords.add(newRecord); + } + } + + + //从库存中出库商品,删除减少 + public boolean removeProduct(String productId,int removeQquantity) { + //判断是否有商品 + ProductRecord record = findRecordById(productId); + if(record != null) { + if(record.getQuantity()>=removeQquantity){//判断数量够不够 + record.setQuantity(record.getQuantity()-removeQquantity); + //判断如果商品的数量为0了,也就表示仓库中没有该商品,对应的记录单也就没了 + if (record.getQuantity()<=0){ + this.productRecords.remove(record); + } + return true; + } + } + return false;//出库失败,商品不存在,数量不足 + } + + //展示库存总信息 + public int getTotalQuantity() { + int total = 0; + for (ProductRecord productRecord : this.productRecords) { + total += productRecord.getQuantity(); + } + + return total; + } + + //显示所有记录的信息(每个不同的商品的记录) + public void showAllRecords() { + for (ProductRecord productRecord : this.productRecords) { + System.out.println(productRecord); + } + } +} diff --git a/s_day02/src/com/inmind/test_07/ProductRecord.java b/s_day02/src/com/inmind/test_07/ProductRecord.java new file mode 100644 index 0000000..0a6b064 --- /dev/null +++ b/s_day02/src/com/inmind/test_07/ProductRecord.java @@ -0,0 +1,48 @@ +package com.inmind.test_07; +/* +库存记录类:关联商品和库存信息,使用泛型限制存储的只能是商品 + */ +public class ProductRecord { + private T product;//商品对象 + private int quantity;//商品数量 + private String address;//库存位置 + + public ProductRecord(T product, int quantity, String address) { + this.product = product; + this.quantity = quantity; + this.address = address; + } + + public T getProduct() { + return product; + } + + public void setProduct(T product) { + this.product = product; + } + + public int getQuantity() { + return quantity; + } + + public void setQuantity(int quantity) { + this.quantity = quantity; + } + + public String getAddress() { + return address; + } + + public void setAddress(String address) { + this.address = address; + } + + @Override + public String toString() { + return "ProductRecord{" + + "product=" + product + + ", quantity=" + quantity + + ", address='" + address + '\'' + + '}'; + } +} diff --git a/s_day02/src/com/inmind/test_07/Test.java b/s_day02/src/com/inmind/test_07/Test.java new file mode 100644 index 0000000..d87c2d2 --- /dev/null +++ b/s_day02/src/com/inmind/test_07/Test.java @@ -0,0 +1,40 @@ +package com.inmind.test_07; + +import java.util.HashSet; +import java.util.LinkedList; + +/* + 业务需求:系统需要管理多种商品(电子设备、图书等),每种商品有共性(ID、名称、价格)也有特性(品牌、作者),但库存管理逻辑(添加、删除、查询)完全相同。 + +类型安全保障:如果不使用泛型,要么需要为每种商品编写一套库存管理类(代码冗余),要么使用 Object 类型导致类型转换错误风险(如将图书误加入电子设备库存)。 + +代码复用:泛型让InventoryManager类可以被不同商品类型复用,同时保持类型检查。 + +业务扩展性:当新增商品类型(如服装)时,只需实现Product接口,无需修改库存管理逻辑。 + */ +public class Test { + public static void main(String[] args) { + HashSet set = new HashSet(); + set.add(1); + + //1.创建电子设备库存管理器 + ProductManager electricManager = new ProductManager<>(); + //2.向电子设备管理器中添加商品(入库) + ElectricDevice device1 = new ElectricDevice("E001", "智能手机", 5999.9, "华为"); + electricManager.addProduct(device1,500,"A区-1"); + ElectricDevice device2 = new ElectricDevice("E002", "笔记本", 7999.9, "华硕"); + electricManager.addProduct(device2,200,"A区-2"); + //显示库存总数和详细记录 + System.out.println("当前仓库有:"+electricManager.getTotalQuantity()); + electricManager.showAllRecords(); + + //创建图书管理器 + ProductManager bookManager = new ProductManager<>(); + Book book1 = new Book("B003", "java从入门到入土", 99.9, "詹姆斯_搞死你"); + Book book2 = new Book("B005", "mysql删库到跑步", 199.9, "XXX"); + bookManager.addProduct(book1,1000,"B区-13"); + bookManager.addProduct(book2,1200,"B区-15"); + System.out.println("当前仓库有:"+bookManager.getTotalQuantity()); + bookManager.showAllRecords(); + } +} diff --git a/s_day03/src/com/inmind/collections_04/Demo01.java b/s_day03/src/com/inmind/collections_04/Demo01.java new file mode 100644 index 0000000..695b95f --- /dev/null +++ b/s_day03/src/com/inmind/collections_04/Demo01.java @@ -0,0 +1,24 @@ +package com.inmind.collections_04; + +import java.util.ArrayList; +import java.util.Collections; + +/* +Collections的常用方法 +static boolean addAll(Collection c, T... elements) 将所有指定的元素添加到指定的集合。 + +static void shuffle(List list) 使用默认的随机源随机排列指定的列表。 + */ +public class Demo01 { + public static void main(String[] args) { + ArrayList list = new ArrayList(); + /*list.add("A"); + list.add("B"); + list.add("C");*/ + Collections.addAll(list, "刘备", "关羽", "张飞", "吕布", "曹操"); + System.out.println(list); + + Collections.shuffle(list); + System.out.println(list); + } +} diff --git a/s_day03/src/com/inmind/collections_04/Demo02.java b/s_day03/src/com/inmind/collections_04/Demo02.java new file mode 100644 index 0000000..ce5649c --- /dev/null +++ b/s_day03/src/com/inmind/collections_04/Demo02.java @@ -0,0 +1,37 @@ +package com.inmind.collections_04; + + +import java.util.ArrayList; +import java.util.Collections; + +/* +static > void sort(List list) 根据其元素的自然排序,按照升序排列指定的列表。 + */ +public class Demo02 { + public static void main(String[] args) { + //整数的自然排序:默认升序 + ArrayList lists = new ArrayList<>(); + Collections.addAll(lists, 100, 29, 13, 44, 35, 56); + System.out.println(lists); + Collections.sort(lists); + System.out.println(lists); + System.out.println("--------------------------------------"); + //字符串的自然排序:默认升序,按照每个字符的ASCII码表的十进制的值来排序 + ArrayList lists1 = new ArrayList<>(); + Collections.addAll(lists1, "ba", "aa", "ab", "ca"); + System.out.println(lists1); + Collections.sort(lists1); + System.out.println(lists1); + System.out.println("-------------------自定义对象排序-------------------"); + ArrayList students = new ArrayList<>(); + Student s1 = new Student("张三", 18); + Student s2 = new Student("李四", 19); + Student s3 = new Student("王五", 20); + Collections.addAll(students, s1, s2, s3); + System.out.println(students); + //注意:Collections.sort排序时,传入的集合的内容,必须拥有自然排序功能(实现Comparable) + Collections.sort(students); + System.out.println(students); + + } +} diff --git a/s_day03/src/com/inmind/collections_04/Demo03.java b/s_day03/src/com/inmind/collections_04/Demo03.java new file mode 100644 index 0000000..6d5a868 --- /dev/null +++ b/s_day03/src/com/inmind/collections_04/Demo03.java @@ -0,0 +1,63 @@ +package com.inmind.collections_04; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.Comparator; + +/* +18.比较器Comparetor的使用 +static void sort(List list, Comparator c) 根据指定的比较器引起的顺序对指定的列表进行排序。 + +当集合中保存的数据不具有自然排序功能或者它原本的自然排序功能不满足我们的需求,就可以使用比较器来添加或者覆盖排序效果 + + */ +public class Demo03 { + public static void main(String[] args) { + ArrayList list = new ArrayList<>(); + Person s1 = new Person("张三", 18,80); + Person s2 = new Person("李四", 19,80); + Person s3 = new Person("王五", 20,99); + Collections.addAll(list, s1, s3, s2); + System.out.println(list); + Collections.sort(list, new Comparator() { + @Override + public int compare(Person o1, Person o2) { + /* //按年龄排序升序:我(o1)-它(o2) +// return o1.age - o2.age; + ////按年龄排序降序:它(o2)-我(o1) + return o2.age - o1.age;*/ + + //先按成绩降序排,如果成绩相同,才按年龄升序排 +// int compare = Integer.compare(o2.score, o1.score); + int compare = o1.score - o2.score; + if (compare != 0) { + return compare; + }else{ + //成绩相同,按年龄升序排 +// return Integer.compare(o1.age, o2.age); + return o2.age- o1.age; + } + + } + }); + + System.out.println(list); + System.out.println("-----------------------------------------"); + ArrayList students = new ArrayList<>(); + Student ss1 = new Student("张三", 18); + Student ss2 = new Student("李四", 19); + Student ss3 = new Student("王五", 20); + Collections.addAll(students, ss1, ss2, ss3); + System.out.println(students); + //注意:Collections.sort排序时,传入的集合的内容,必须拥有自然排序功能(实现Comparable) + //默认按照按年龄排降序排序,但是我不好默认的降序,我使用新的比较器降原本的自然排序功能覆盖要改为升序(框架思想:接口回调) + Collections.sort(students, new Comparator() { + @Override + public int compare(Student o1, Student o2) { + return o1.age - o2.age; + } + }); + System.out.println(students); + + } +} diff --git a/s_day03/src/com/inmind/collections_04/Demo04.java b/s_day03/src/com/inmind/collections_04/Demo04.java new file mode 100644 index 0000000..88d6281 --- /dev/null +++ b/s_day03/src/com/inmind/collections_04/Demo04.java @@ -0,0 +1,22 @@ +package com.inmind.collections_04; + +import java.util.ArrayList; +import java.util.Collections; + +/* +static int binarySearch(List list, T key, Comparator c) 使用二叉搜索算法搜索指定对象的指定列表。 +static int binarySearch(List list, T key) 使用二叉搜索算法搜索指定对象的指定列表。 +注意:由于采用二分法快速查找,所以它是基于排序之后的查询,必须先升序排序 + */ +public class Demo04 { + public static void main(String[] args) { + ArrayList list = new ArrayList<>(); + Collections.addAll(list, 1, 2, 4, 10, 5, 6, 9, 8, 3); + System.out.println(list); + Collections.sort(list); + int index = Collections.binarySearch(list, 5); + System.out.println(list); + System.out.println(index); + } + +} diff --git a/s_day03/src/com/inmind/collections_04/Person.java b/s_day03/src/com/inmind/collections_04/Person.java new file mode 100644 index 0000000..399df59 --- /dev/null +++ b/s_day03/src/com/inmind/collections_04/Person.java @@ -0,0 +1,38 @@ +package com.inmind.collections_04; + +import java.util.Objects; + +public class Person { + String name; + int age; + int score; + + public Person(String name, int age, int score) { + this.name = name; + this.age = age; + this.score = score; + } + + + + @Override + public boolean equals(Object o) { + if (!(o instanceof Person)) return false; + Person student = (Person) o; + return age == student.age && Objects.equals(name, student.name); + } + + @Override + public int hashCode() { + return Objects.hash(name, age); + } + + @Override + public String toString() { + return "Person{" + + "name='" + name + '\'' + + ", age=" + age + + ", score=" + score + + '}'; + } +} diff --git a/s_day03/src/com/inmind/collections_04/Student.java b/s_day03/src/com/inmind/collections_04/Student.java new file mode 100644 index 0000000..29ec7cd --- /dev/null +++ b/s_day03/src/com/inmind/collections_04/Student.java @@ -0,0 +1,49 @@ +package com.inmind.collections_04; + +import java.util.Objects; + +public class Student implements Comparable{ + String name; + int age; + + public Student(String name, int age) { + this.name = name; + this.age = age; + } + + + @Override + public boolean equals(Object o) { + if (!(o instanceof Student)) return false; + Student student = (Student) o; + return age == student.age && Objects.equals(name, student.name); + } + + @Override + public int hashCode() { + return Objects.hash(name, age); + } + + @Override + public String toString() { + return "Student{" + + "name='" + name + '\'' + + ", age=" + age + + '}'; + } + + //学生类的自然排序功能 + /* + 负整数,零或正整数,因为该对象(this)小于,等于或大于指定对象(参数o)。 + 口诀: + 我-它:升序 + 它-我:降序 + */ + @Override + public int compareTo(Student o) { + //按年龄排序,升序 +// return this.age - o.age; + //按年龄排序,降序 + return o.age - this.age; + } +} diff --git a/s_day03/src/com/inmind/list_01/Demo01.java b/s_day03/src/com/inmind/list_01/Demo01.java new file mode 100644 index 0000000..38b2d4f --- /dev/null +++ b/s_day03/src/com/inmind/list_01/Demo01.java @@ -0,0 +1,32 @@ +package com.inmind.list_01; + +import java.util.ArrayList; +import java.util.List; + +/* + List接口的特点: + 1.存取有序 + 2.有索引 + 3.可以重复 + List接口的常用实现类 + ArrayList LinkedList + + List接口是Collection的子接口,前天学习的单列集合API是都能使用 + + */ +public class Demo01 { + public static void main(String[] args) { + //List接口的多态 + List lists = new ArrayList(); + lists.add("刘备"); + lists.add("关羽"); + lists.add("张飞"); + lists.add("关羽"); + + String s = lists.get(2); + System.out.println(s); + + System.out.println(lists); + + } +} diff --git a/s_day03/src/com/inmind/list_01/Demo02.java b/s_day03/src/com/inmind/list_01/Demo02.java new file mode 100644 index 0000000..bc5a2a6 --- /dev/null +++ b/s_day03/src/com/inmind/list_01/Demo02.java @@ -0,0 +1,44 @@ +package com.inmind.list_01; + +import java.util.ArrayList; +import java.util.List; + +/* +2.List接口的常用方法 +List既拥有Collection的共有方法,也有它自己独有的功能,有序集合,有索引相关的增删改查操作 +索引相关的增删改查API + public void add(int index, E element) : 将指定的元素,添加到该集合中的指定位置上。 + public E get(int index) :返回集合中指定位置的元素。 + public E remove(int index) : 移除列表中指定位置的元素, 返回的是被移除的元素。 + public E set(int index, E element) :用指定元素替换集合中指定位置的元素,返回值的更新前的元素。 + + */ +public class Demo02 { + public static void main(String[] args) { + //list接口的多态 + List lists = new ArrayList(); + lists.add("刘备"); + lists.add("关羽"); + lists.add("张飞"); + System.out.println(lists); + + //public void add(int index, E element) : 将指定的元素,添加到该集合中的指定位置上 (插队) + //吕布插入到张飞之前 + lists.add(2, "吕布"); + System.out.println(lists); + + //public E get(int index) :返回集合中指定位置的元素。 + System.out.println(lists.get(3)); + + //public E remove(int index) : 移除列表中指定位置的元素, 返回的是被移除的元素。 + String removedStr = lists.remove(2); + System.out.println(removedStr); + System.out.println(lists); + + //public E set(int index, E element) :用指定元素替换集合中指定位置的元素,返回值的更新前的旧元素。 + //把关羽修改为关二哥 + String updatedStr = lists.set(1, "关二哥"); + System.out.println(updatedStr); + System.out.println(lists); + } +} diff --git a/s_day03/src/com/inmind/list_01/Demo03.java b/s_day03/src/com/inmind/list_01/Demo03.java new file mode 100644 index 0000000..55f0f29 --- /dev/null +++ b/s_day03/src/com/inmind/list_01/Demo03.java @@ -0,0 +1,25 @@ +package com.inmind.list_01; + +import java.util.ArrayList; +import java.util.List; + +/* + List接口的实现类----ArrayList类的特点 + 它的底层是Object[] + 它的特点: + + 1.查询快 (连续空间) + 2.增删慢 (固定长度) + 3.存取有序 + 4.有索引 + 5.数据可以重复 + */ +public class Demo03 { + public static void main(String[] args) { + ArrayList lists = new ArrayList(); + lists.add("刘备"); + lists.add("关羽"); + lists.add("张飞"); + System.out.println(lists); + } +} diff --git a/s_day03/src/com/inmind/list_01/Demo04.java b/s_day03/src/com/inmind/list_01/Demo04.java new file mode 100644 index 0000000..03978cf --- /dev/null +++ b/s_day03/src/com/inmind/list_01/Demo04.java @@ -0,0 +1,63 @@ +package com.inmind.list_01; + +import java.util.ArrayList; +import java.util.LinkedList; + +/* +LinkedList的特点和基本使用 +LinkedList是List接口的实现类,它的集合特点: 存取有序,有索引数据,可以重复 + +LinkedList底层数据结构是双向链表,它的数据结构的特点:1.查询慢 2.增删快 + +注意:当对很多数据要进行增删操作时,而不是就用来查询,那就使用LinkedList,反之ArrayList +------------------------------------------------- +LinkedList底层采用双向链表,它对于头尾操作的效率较高,所以该类提供了高效头尾操作的api + + 8.LinkedList独有的方法 + public void addFirst(E e) :将指定元素插入此列表的开头。 + public void addLast(E e) :将指定元素添加到此列表的结尾。 + + public E getFirst() :返回此列表的第一个元素。 + public E getLast() :返回此列表的最后一个元素。 + + public E removeFirst() :移除并返回此列表的第一个元素。 + public E removeLast() :移除并返回此列表的最后一个元素。 + + //模仿栈结构的api(操作双向链表的第一个数据) + public E pop() :从此列表所表示的堆栈处弹出一个元素。 + public void push(E e) :将元素推入此列表所表示的堆栈。 + + */ +public class Demo04 { + public static void main(String[] args) { + LinkedList lists = new LinkedList(); + lists.add("刘备"); + lists.add("关羽"); + lists.add("张飞"); + System.out.println(lists); + System.out.println("-------------------独有方法------------------------"); + //public void addFirst(E e) :将指定元素插入此列表的开头。 + //public void addLast(E e) :将指定元素添加到此列表的结尾。 + lists.addFirst("孙权"); + lists.addLast("周瑜"); + System.out.println(lists); + + //public E getFirst() :返回此列表的第一个元素。 + //public E getLast() :返回此列表的最后一个元素。 + System.out.println(lists.getFirst()); + System.out.println(lists.getLast()); + + //public E removeFirst() :移除并返回此列表的第一个元素。 + //public E removeLast() :移除并返回此列表的最后一个元素。 + System.out.println(lists.removeFirst()); + System.out.println(lists.removeLast()); + System.out.println(lists); + + //public E pop() :从此列表所表示的堆栈处弹出一个元素。(removeFirst()) + //public void push(E e) :将元素推入此列表所表示的堆栈。(addFirst()) + System.out.println(lists.pop()); + System.out.println(lists); + lists.push("刘备"); + System.out.println(lists); + } +} diff --git a/s_day03/src/com/inmind/set_02/Demo01.java b/s_day03/src/com/inmind/set_02/Demo01.java new file mode 100644 index 0000000..31e6f2c --- /dev/null +++ b/s_day03/src/com/inmind/set_02/Demo01.java @@ -0,0 +1,29 @@ +package com.inmind.set_02; + +import java.util.HashSet; +import java.util.Set; + +/* + Set接口是Collection接口的子接口,它拥有Collection的所有功能 + Set接口的特点: + 1.存取无序(怎么存不一定怎么取) + 2.没有索引 + 3.不能重复 + + Set接口的常用实现类: + HashSet LinkedHashSet + */ +public class Demo01 { + public static void main(String[] args) { + //set多态 + Set sets = new HashSet<>(); + sets.add("张飞"); + sets.add("刘备"); + sets.add("关羽"); + sets.add("关羽"); + sets.add("关羽"); + sets.add("关羽"); + + System.out.println(sets); + } +} diff --git a/s_day03/src/com/inmind/set_02/Demo02.java b/s_day03/src/com/inmind/set_02/Demo02.java new file mode 100644 index 0000000..2859f55 --- /dev/null +++ b/s_day03/src/com/inmind/set_02/Demo02.java @@ -0,0 +1,39 @@ +package com.inmind.set_02; + +import java.util.*; + +/* +10.HashSet特点以及遍历 +HashSet接口的特点: + 1.存取无序(怎么存不一定怎么取) + 2.没有索引 + 3.不能重复 + +HashSet底层数据结构是哈希表,就是一个HashMap + */ +public class Demo02 { + public static void main(String[] args) { + HashSet sets = new HashSet<>(); + sets.add("张飞"); + sets.add("刘备"); + sets.add("关羽"); + + System.out.println(sets); + //Set集合没有get方法,数据如何获取???只能通过迭代器数据,或者转为数组,之后的stream流操作 + //迭代器遍历:获取迭代器,如果有,就拿数据 + Iterator iterator = sets.iterator(); + while (iterator.hasNext()) { + String element = iterator.next(); + System.out.println(element); + } + System.out.println("---------------------"); + //foreach遍历,底层就是迭代器 + for (String element : sets) { + System.out.println(element); + } + System.out.println("-----------转数组------------"); + Object[] array = sets.toArray(); + System.out.println(Arrays.toString(array)); + + } +} diff --git a/s_day03/src/com/inmind/set_02/Demo03.java b/s_day03/src/com/inmind/set_02/Demo03.java new file mode 100644 index 0000000..65ecb17 --- /dev/null +++ b/s_day03/src/com/inmind/set_02/Demo03.java @@ -0,0 +1,34 @@ +package com.inmind.set_02; +/* + 1.什么是哈希值??? + 哈希值就是对象的特征码,使用十进制int来表示的,int是取值范围的,有限的,对象是无限。(不同的对象的哈希值可能相同的) + + 2.如何获取一个对象的哈希值??? + int hashCode() 返回对象的哈希码值。 + Object的hashCode源码: + public native int hashCode();//通过真正的地址值,使用哈希算法,返回的一个int值 + + 3.我们发现每个对象的哈希值都是默认通过地址来获取,对于程序员来说没有意义,我们在实际开发中 + 希望拥有相同的内容的对象是同一个对象(哈希值要一样),所以我们子类重写hashCode方法,在判断 + 时使用到的哈希值要保持一致。 + + 如何重写??学习一个最终类 String,得出String的哈希值跟它的内容有关,那么自定义的类重写 + hashCode方法,那么也跟自己的属性有关,alt+insert + + + */ +public class Demo03 { + public static void main(String[] args) { + Student s1 = new Student("刘备", 10); + Student s2 = new Student("刘备", 10); + String s; + + int i = s1.hashCode(); + System.out.println(i); + System.out.println(s1); + int i2 = s2.hashCode(); + System.out.println(i2); + System.out.println(s2); + + } +} diff --git a/s_day03/src/com/inmind/set_02/Demo04.java b/s_day03/src/com/inmind/set_02/Demo04.java new file mode 100644 index 0000000..c1f5c6b --- /dev/null +++ b/s_day03/src/com/inmind/set_02/Demo04.java @@ -0,0 +1,32 @@ +package com.inmind.set_02; + +import java.util.HashSet; + +/* + Set集合底层的数据结构是哈希表 + jdk8之前,数组+链表组成哈希表 + jdk8之后,数组+链表+红黑树组成哈希表 + + + */ +public class Demo04 { + public static void main(String[] args) { + String str1 = "abc"; + String str2 = new String("abc"); + String str3 = "通话"; + String str4 = "重地"; + + System.out.println(str1.hashCode()); + System.out.println(str2.hashCode()); + System.out.println(str3.hashCode()); + System.out.println(str4.hashCode()); + + HashSet hashSet = new HashSet<>(); + hashSet.add(str1); + hashSet.add(str2); + hashSet.add(str4); + hashSet.add(str3); + System.out.println(hashSet); + + } +} diff --git a/s_day03/src/com/inmind/set_02/Demo05.java b/s_day03/src/com/inmind/set_02/Demo05.java new file mode 100644 index 0000000..887ba67 --- /dev/null +++ b/s_day03/src/com/inmind/set_02/Demo05.java @@ -0,0 +1,23 @@ +package com.inmind.set_02; + +import java.util.HashSet; + +/* +13.HashSet存储自定义对象 +注意:我们保存数据时,先判断哈希值,如果不一样直接存,如果哈希值相同,还要使用equals方法判断内容 +是否相同,如果相同,就不存,不同则保存,所以必须重写hashCode和equals + */ +public class Demo05 { + public static void main(String[] args) { + Persion p1 = new Persion("刘备", 20); + Persion p4 = new Persion("刘备", 20); + Persion p3 = new Persion("张飞", 20); + Persion p2 = new Persion("关羽", 20); + HashSet sets = new HashSet<>(); + sets.add(p1); + sets.add(p2); + sets.add(p3); + sets.add(p4); + System.out.println(sets); + } +} diff --git a/s_day03/src/com/inmind/set_02/Demo06.java b/s_day03/src/com/inmind/set_02/Demo06.java new file mode 100644 index 0000000..56de712 --- /dev/null +++ b/s_day03/src/com/inmind/set_02/Demo06.java @@ -0,0 +1,36 @@ +package com.inmind.set_02; + +import java.util.HashSet; +import java.util.LinkedHashSet; + +/* +LinkedHashSet的特点 +1.存取有序 +2.没有索引 +3.不能重复 + +LinkedHashSet的底层数据结构:在哈希表的基础上,添加了链表 +哈希表:去重,高效查询 +链接:保证数据的顺序 + +注意:当我们定义的集合既要去重,也要保证顺序,采用LinkedHashSet + */ +public class Demo06 { + public static void main(String[] args) { + HashSet sets = new HashSet<>(); + sets.add("刘备"); + sets.add("关羽"); + sets.add("张飞"); + System.out.println(sets); + System.out.println("------------------------------------"); + LinkedHashSet linkedSets = new LinkedHashSet<>(); + linkedSets.add("张飞"); + linkedSets.add("关羽"); + linkedSets.add("关羽"); + linkedSets.add("关羽"); + linkedSets.add("刘备"); + linkedSets.add("刘备"); + linkedSets.add("刘备"); + System.out.println(linkedSets); + } +} diff --git a/s_day03/src/com/inmind/set_02/Persion.java b/s_day03/src/com/inmind/set_02/Persion.java new file mode 100644 index 0000000..7f72555 --- /dev/null +++ b/s_day03/src/com/inmind/set_02/Persion.java @@ -0,0 +1,33 @@ +package com.inmind.set_02; + +import java.util.Objects; + +public class Persion { + String name; + int age; + + public Persion(String name, int age) { + this.name = name; + this.age = age; + } + + @Override + public boolean equals(Object o) { + if (o == null || getClass() != o.getClass()) return false; + Persion persion = (Persion) o; + return age == persion.age && Objects.equals(name, persion.name); + } + + @Override + public int hashCode() { + return Objects.hash(name, age); + } + + @Override + public String toString() { + return "Persion{" + + "name='" + name + '\'' + + ", age=" + age + + '}'; + } +} diff --git a/s_day03/src/com/inmind/set_02/Student.java b/s_day03/src/com/inmind/set_02/Student.java new file mode 100644 index 0000000..b030268 --- /dev/null +++ b/s_day03/src/com/inmind/set_02/Student.java @@ -0,0 +1,26 @@ +package com.inmind.set_02; + +import java.util.Objects; + +public class Student { + String name; + int age; + + public Student(String name, int age) { + this.name = name; + this.age = age; + } + + + @Override + public boolean equals(Object o) { + if (!(o instanceof Student)) return false; + Student student = (Student) o; + return age == student.age && Objects.equals(name, student.name); + } + + @Override + public int hashCode() { + return Objects.hash(name, age); + } +} diff --git a/s_day03/src/com/inmind/test05/Poker.java b/s_day03/src/com/inmind/test05/Poker.java new file mode 100644 index 0000000..d3d5335 --- /dev/null +++ b/s_day03/src/com/inmind/test05/Poker.java @@ -0,0 +1,17 @@ +package com.inmind.test05; +//自定义的方式,实现牌的排序 +public class Poker implements Comparable { + String content; + int sort; + + public Poker(String content, int sort) { + this.content = content; + this.sort = sort; + } + + + @Override + public int compareTo(Poker o) { + return this.sort - o.sort; + } +} diff --git a/s_day03/src/com/inmind/test05/Test.java b/s_day03/src/com/inmind/test05/Test.java new file mode 100644 index 0000000..b942d4b --- /dev/null +++ b/s_day03/src/com/inmind/test05/Test.java @@ -0,0 +1,79 @@ +package com.inmind.test05; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.HashMap; + +/* +按照斗地主的规则,完成洗牌发牌的动作。 +具体规则: + +使用54张牌打乱顺序,三个玩家参与游戏,三人交替摸牌,每人17张牌,最后三张留作底牌。 +步骤分析: + 1.准备54张牌(花色+数字) + 2.洗牌(打乱牌的顺序) + 3.创建3个集合轮流摸牌,创建1个集合保存底牌 + 4.打印集合的内容 + + */ +public class Test { + public static void main(String[] args) { + //1.准备54张牌(花色+数字) + String [] colors = {"♠", "♥", "♣", "♦"}; + String[] nums = {"3", "4", "5", "6", "7", "8", "9", "10", "J", "Q", "K", "A", "2"}; + ArrayList pokers = new ArrayList<>(); + for (String color : colors) { + for (String num : nums) { + String poker = color+num; + pokers.add(poker); + } + } + + pokers.add("大王"); + pokers.add("小王"); + System.out.println(pokers.size()); + System.out.println(pokers); + + + //2.洗牌(打乱牌的顺序) + System.out.println("洗牌之后:"); + Collections.shuffle(pokers); + System.out.println(pokers); + //3.创建3个集合轮流摸牌,创建1个集合保存底牌 + ArrayList player1 = new ArrayList<>(); + ArrayList player2 = new ArrayList<>(); + ArrayList player3 = new ArrayList<>(); + ArrayList dipai = new ArrayList<>(); + /* + 玩家1 0 3 6 %3 = 0 + 玩家2 1 4 7 %3 = 1 + 玩家3 2 5 8 %3 = 2 + */ + for (int i = 0; i < pokers.size(); i++) { + if (i >= pokers.size() - 3) { + dipai.add(pokers.get(i)); + }else{ + switch (i%3) { + case 0: + player1.add(pokers.get(i)); + break; + case 1: + player2.add(pokers.get(i)); + break; + case 2: + player3.add(pokers.get(i)); + break; + } + } + } + //4.打印集合的内容(预留:如何实现抓完牌之后的排序功能升序,降序) + System.out.println("抓牌之后:"); + System.out.println(player1); + System.out.println(player2); + System.out.println(player3); + System.out.println(dipai); + + HashMap map = new HashMap<>(); + } +} diff --git a/s_day03/src/com/inmind/test06/CartSytem.java b/s_day03/src/com/inmind/test06/CartSytem.java new file mode 100644 index 0000000..095cd99 --- /dev/null +++ b/s_day03/src/com/inmind/test06/CartSytem.java @@ -0,0 +1,183 @@ +package com.inmind.test06; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Map; +import java.util.Scanner; + +public class CartSytem { + //保存所有的商品list + private static ArrayList products = new ArrayList<>(); + //保存购物车map + private static HashMap carts = new HashMap<>(); + private static Scanner sc = new Scanner(System.in); + + public static void main(String[] args) { + //初始化商品 + initData(); + + //提示 + System.out.println("===== 简易购物系统 ====="); + + showMainMenu(); + } + + private static void showMainMenu() { + while (true) { + boolean flag = false; + System.out.println(); + System.out.println(); + System.out.println("===== 主菜单 ====="); + System.out.println("1. 浏览所有商品"); + System.out.println("2. 搜索商品"); + System.out.println("3. 查看购物车"); + System.out.println("4. 添加商品到购物车"); + System.out.println("5. 修改购物车商品数量"); + System.out.println("6. 清空购物车"); + System.out.println("7. 退出"); + System.out.println("8. 按分类去查看商品???"); + System.out.println("请选择:"); + int choice = sc.nextInt(); + if (choice<1||choice>7) { + System.out.println("无效的选项"); + continue; + } + + switch (choice) { + case 1: browsProducts(); break; + case 2: searchProduct(); break; + case 3: showCarts(); break; + case 4: addCart(); break; + case 5: putCart(); break; + case 6: clearCart(); break; + case 7: + System.out.println("谢谢使用!!再见"); + flag = true; + break; + } + + if (flag) { + break;//结束外面的死循环 + } + } + } + + private static void clearCart() { + carts.clear(); + System.out.println("购物车已清空"); + } + + private static void putCart() { + System.out.println("请输入要修改的商品ID:"); + sc.nextLine(); + String pId = sc.nextLine(); + //先判断下是否有该商品 + Product product = null; + for (Product p : carts.keySet()) { + if (p.getId().equals(pId)) { + product = p; + } + } + //如果有则保存数量,如没有则return + if (product == null) { + System.out.println("购物车中未找到该商品"); + return; + } + + System.out.println("请输入新的数量:"); + int quantity = sc.nextInt(); + + carts.put(product,quantity); + System.out.println("数量已更新"); + } + + private static void addCart() { + System.out.println("请输入商品ID: "); + sc.nextLine(); + String pId = sc.nextLine(); + //先判断下是否有该商品 + Product product = null; + for (Product p : products) { + if (p.getId().equals(pId)) { + product = p; + } + } + //如果有则保存数量,如没有则return + if (product == null) { + System.out.println("未找到该商品"); + return; + } + + System.out.println("请输入购买数量:"); + int quantity = sc.nextInt(); + + //添加到购物车,product:数量 + if (carts.containsKey(product)) { + carts.put(product, carts.get(product) + quantity); + } else { + carts.put(product, quantity); + } + System.out.println("已加入购物车"); + + } + + private static void showCarts() { + System.out.println("===== 购物车 ====="); + if (carts.isEmpty()) { + System.out.println("购物车是空的!!"); + return; + } + + int total = 0;//总价 + for (Map.Entry entry : carts.entrySet()) { + Product product = entry.getKey(); + Integer count = entry.getValue(); + int sum = product.getPrice()*count; + System.out.println(product.getName()+", 数量: "+count+", 小计: ¥"+sum); + total += sum; + } + + System.out.println("购物车总计: ¥"+total); + } + + private static void searchProduct() { + System.out.println("请输入商品名称关键字:"); + sc.nextLine(); + String search = sc.nextLine(); + ArrayList searchLists = new ArrayList<>(); + for (Product product : products) { + if (product.getName().contains(search)) { + searchLists.add(product); + } + } + + System.out.println("===== 搜索结果 ====="); + if (searchLists.size() == 0) { + System.out.println("没有找到匹配的商品"); + } else { + for (Product product : searchLists) { + System.out.println(product); + } + } + } + + private static void browsProducts() { + System.out.println("===== 所有商品 ====="); + for (Product product : products) { + System.out.println(product); + } + System.out.println(); + } + + private static void method() { + + } + + private static void initData() { + products.add(new Product("P01", "笔记本电脑", 5999, "电子产品", 10)); + products.add(new Product("P02", "机械键盘", 299, "电脑配件", 20)); + products.add(new Product("P03", "无线鼠标", 129, "电脑配件", 30)); + products.add(new Product("P04", "蓝牙耳机", 799, "音频设备", 15)); + products.add(new Product("P05", "智能手机", 3999, "电子产品", 25)); + } +} diff --git a/s_day03/src/com/inmind/test06/Product.java b/s_day03/src/com/inmind/test06/Product.java new file mode 100644 index 0000000..2cd699b --- /dev/null +++ b/s_day03/src/com/inmind/test06/Product.java @@ -0,0 +1,83 @@ +package com.inmind.test06; + +import java.util.Objects; + +public class Product { + //商品编号 + private String id; + //名称 + private String name; + //价格 + private Integer price; + //分类 + private String category; + //数量 + private Integer quantity; + + + public Product(String id, String name, Integer price, String category, Integer quantity) { + this.id = id; + this.name = name; + this.price = price; + this.category = category; + this.quantity = quantity; + } + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public Integer getPrice() { + return price; + } + + public void setPrice(Integer price) { + this.price = price; + } + + public String getCategory() { + return category; + } + + public void setCategory(String category) { + this.category = category; + } + + public Integer getQuantity() { + return quantity; + } + + public void setQuantity(Integer quantity) { + this.quantity = quantity; + } + + + @Override + public String toString() { + return "ID: "+this.id+", 名称: "+this.name+", 价格: ¥"+this.price+", 分类: "+this.category+", 库存: "+this.quantity; + } + + @Override + public boolean equals(Object o) { + if (!(o instanceof Product)) return false; + Product product = (Product) o; + return Objects.equals(id, product.id); + } + + @Override + public int hashCode() { + return Objects.hashCode(id); + } +} diff --git a/s_day03/src/com/inmind/var_params_03/Demo01.java b/s_day03/src/com/inmind/var_params_03/Demo01.java new file mode 100644 index 0000000..d165719 --- /dev/null +++ b/s_day03/src/com/inmind/var_params_03/Demo01.java @@ -0,0 +1,45 @@ +package com.inmind.var_params_03; +/* + 在jdk5中,提供可变参数,当我们要定义多个同一种类型的参数,并且,个数还不确定时,此时可以用可变参数来替代 + + 可变参数的语法: + (数据类型... 参数名) + + 可变参数也是一个语法糖,本质不变,就是数组 + + 注意事项: + 1.可变参数在一个参数列表中只能出现一次 + 2.如果有多个参数,可变参数必须在最后一个 + */ +public class Demo01 { + public static void main(String[] args) { + //计算2个整数 + System.out.println(getSum("1",1, 2)); + //计算5个整数 + System.out.println(getSum("1",1, 2,3,4,5)); + //计算7个整数 + System.out.println(getSum("1",1, 2,3,4,5,6,7)); + + } + public static int getSum(String str3,int...arr){ + int sum = 0; + for (int i : arr) { + sum += i; + } + return sum; + } + + /*//定义2个整数相加之和的方法 + public int getSum(int a, int b) { + return a + b; + } + //定义3个整数相加之和的方法 + public int getSum(int a, int b, int c) { + return a + b + c; + } + //定义4个整数相加之和的方法 + public int getSum(int a, int b, int c, int d) { + return a + b + c + d; + }*/ + +} diff --git a/s_day04/src/com/inmind/map_01/Demo01.java b/s_day04/src/com/inmind/map_01/Demo01.java new file mode 100644 index 0000000..0ed8210 --- /dev/null +++ b/s_day04/src/com/inmind/map_01/Demo01.java @@ -0,0 +1,63 @@ +package com.inmind.map_01; + +import java.util.HashMap; +import java.util.Map; + +/* + Interface Map + 参数类型 + K - 键的类型 + V - 值的类型 +常用实现类: +HashMap LinkedHashMap TreeMap + +常用的数据操作方法: +- public V put(K key, V value): 把指定的键与指定的值添加到Map集合中。 +- public V remove(Object key): 把指定的键 所对应的键值对元素 在Map集合中删除,返回被删除元素的值。 +- public V get(Object key) 根据指定的键,在Map集合中获取对应的值。 +- public boolean containKey(Object key):判断该集合中是否有此键。 + + +- public Set keySet(): 获取Map集合中所有的键,存储到Set集合中。 +- public Set> entrySet(): 获取到Map集合中所有的键值对对象的集合(Set集合)。 + + */ +public class Demo01 { + public static void main(String[] args) { + //Map的多态 + //请创建出一个key为整数,value为字符串的双列集合 + Map maps = new HashMap<>(); + + //- public V put(K key, V value): 把指定的键与指定的值添加到Map集合中。 + maps.put(1, "刘备"); + maps.put(2, "吕布"); + maps.put(3, "张飞"); + String str = maps.put(4, "关羽");//如果保存新的键值,返回的是null,表示新增 + System.out.println(str); + String str1 = maps.put(2, "貂蝉");//如果保存已有的键值,返回的是被替换的旧数据,表示修改 + System.out.println(str1); + System.out.println(maps); + + //- public V remove(Object key): 把指定的键 所对应的键值对元素 在Map集合中删除,返回被删除元素的值。 + //删除貂蝉 + String removeStr = maps.remove(2); + System.out.println(removeStr);//貂蝉------返回被删除的键值对的值 + System.out.println(maps); + + //- public V get(Object key) 根据指定的键,在Map集合中获取对应的值。 + String result = maps.get(4); + System.out.println(result);//关羽 + String result1 = maps.get(100); + System.out.println(result1);//null 如果获取不存在的key,返回null,表示没有,而不是报错 + + //- public boolean containKey(Object key):判断该集合中是否有此键。 + System.out.println(maps.containsKey(1));//true + System.out.println(maps.containsKey(100));//false + + //boolean containsValue(Object value) 如果此映射将一个或多个键映射到指定的值,则返回 true 。 + System.out.println(maps.containsValue("貂蝉"));//false + System.out.println(maps.containsValue("刘备"));//true + System.out.println(maps); + + } +} diff --git a/s_day04/src/com/inmind/map_01/Demo02.java b/s_day04/src/com/inmind/map_01/Demo02.java new file mode 100644 index 0000000..9b70874 --- /dev/null +++ b/s_day04/src/com/inmind/map_01/Demo02.java @@ -0,0 +1,36 @@ +package com.inmind.map_01; + +import java.util.HashMap; +import java.util.Iterator; +import java.util.Map; +import java.util.Set; + +/* +3.Map集合的第一种遍历方式(键找值) +Map也是没有索引,也没有迭代器功能,所以不能通过普通for循环,也不能通过迭代器和foreach遍历,只能间接遍历 + +- public Set keySet(): 获取Map集合中所有的键,存储到Set集合中。 + */ +public class Demo02 { + public static void main(String[] args) { + //创建一个键和值都是String的双列集合 + Map map = new HashMap(); + map.put("刘备", "孙尚香"); + map.put("吕布", "貂蝉"); + map.put("张飞", "夏侯驰"); + Set keys = map.keySet(); + System.out.println(keys); + //迭代器遍历 + Iterator iterator = keys.iterator(); + while (iterator.hasNext()) { + String key = iterator.next(); + String value = map.get(key); + System.out.println(key + ":" + value); + } + System.out.println("-------------------"); + //foreach遍历 + for (String key : keys) { + System.out.println(key + ":" + map.get(key)); + } + } +} diff --git a/s_day04/src/com/inmind/map_01/Demo03.java b/s_day04/src/com/inmind/map_01/Demo03.java new file mode 100644 index 0000000..3ccb295 --- /dev/null +++ b/s_day04/src/com/inmind/map_01/Demo03.java @@ -0,0 +1,37 @@ +package com.inmind.map_01; + +import java.util.HashMap; +import java.util.Iterator; +import java.util.Map; +import java.util.Map.Entry; +import java.util.Set; + +/* +4.Map集合的第二种遍历方式(键值对遍历) +- public Set> entrySet(): 获取到Map集合中所有的键值对对象的集合(Set集合)。 + */ +public class Demo03 { + public static void main(String[] args) { + //创建一个键和值都是String的双列集合 + Map map = new HashMap(); + map.put("刘备", "孙尚香"); + map.put("吕布", "貂蝉"); + map.put("张飞", "夏侯驰"); + System.out.println(map); + //调用entrySet方法,返回保存键值对对象的Set集合 + Set> entries = map.entrySet(); + //迭代器遍历 + Iterator> iterator = entries.iterator(); + while(iterator.hasNext()) { + Map.Entry entry = iterator.next(); + System.out.println(entry.getKey()+":"+entry.getValue()); + } + System.out.println("-----------------------"); + //foreach遍历 + for (Entry entry : entries) { + System.out.println(entry.getKey()+":"+entry.getValue()); + entry.setValue("张三"); + } + System.out.println(map); + } +} diff --git a/s_day04/src/com/inmind/map_01/Demo04.java b/s_day04/src/com/inmind/map_01/Demo04.java new file mode 100644 index 0000000..64aa286 --- /dev/null +++ b/s_day04/src/com/inmind/map_01/Demo04.java @@ -0,0 +1,34 @@ +package com.inmind.map_01; + +import java.util.HashMap; +import java.util.HashSet; +import java.util.Map; + +/* +5.Map集合存储自定义对象 +需求:每位学生(姓名,年龄)都有自己的家庭住址,我要把学生对象和居住城市存储到Map集合中,学生作为键key,居住城市作为值 +注意:学生姓名和年龄如果相同看作同一个学生 + +哈希:通过hashCode,equals实现去重 + +总结: +1.hashMap存储自定义对象作为key时,要实现去重,必须在自定义类中重写hashCode,equals方法 +2.HashMap:底层数据结构就是哈希表,它跟对象哈希值有关 +3.HashSet 底层就是HashMap,HashMap,将set中的值作为map中的key,而map中值没有任何作用,就保存相同的数据 + */ +public class Demo04 { + public static void main(String[] args) { + Map maps = new HashMap<>(); + //保存学生 + Student s1 = new Student("刘备", 18); + Student s2 = new Student("关羽", 19); + Student s3 = new Student("张飞", 20); + Student s4 = new Student("张飞", 20); + maps.put(s1, "苏州"); + maps.put(s2, "无锡"); + maps.put(s3, "常州"); + maps.put(s4, "常州"); + System.out.println(maps); + new HashSet().add("abc"); + } +} diff --git a/s_day04/src/com/inmind/map_01/Demo05.java b/s_day04/src/com/inmind/map_01/Demo05.java new file mode 100644 index 0000000..28db38b --- /dev/null +++ b/s_day04/src/com/inmind/map_01/Demo05.java @@ -0,0 +1,29 @@ +package com.inmind.map_01; + +import java.util.HashMap; +import java.util.LinkedHashMap; +import java.util.Map; + +/* +6.LinkedHashMap的特点 +hash:哈希表,它的作用去重,通过hashCode和equals +link:链表,保证有序 + +LinkedHashMap:存取有序,没有索引,不能重复的,一个双列集合 + */ +public class Demo05 { + public static void main(String[] args) { + //创建一个键和值都是String的双列集合 + HashMap map = new HashMap(); + map.put("刘备", "孙尚香"); + map.put("张飞", "夏侯驰"); + map.put("吕布", "貂蝉"); + System.out.println(map); + System.out.println("--------------------------------"); + LinkedHashMap linkedmap = new LinkedHashMap(); + linkedmap.put("刘备", "孙尚香"); + linkedmap.put("张飞", "夏侯驰"); + linkedmap.put("吕布", "貂蝉"); + System.out.println(linkedmap); + } +} diff --git a/s_day04/src/com/inmind/map_01/Demo07.java b/s_day04/src/com/inmind/map_01/Demo07.java new file mode 100644 index 0000000..f538e02 --- /dev/null +++ b/s_day04/src/com/inmind/map_01/Demo07.java @@ -0,0 +1,27 @@ +package com.inmind.map_01; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; + +/* + 8.集合的嵌套 + 使用集合的嵌套,显示哪个省份有哪些城市 + 省份作为Key String + 城市作为值(有很多数据,容器集合) + */ +public class Demo07 { + public static void main(String[] args) { + ArrayList> lists = new ArrayList<>(); + + //江苏省,浙江省 + HashMap> map = new HashMap<>(); + ArrayList list = new ArrayList<>(); + Collections.addAll(list, "常州", "南京", "苏州", "南通"); + ArrayList list1 = new ArrayList<>(); + Collections.addAll(list1, "杭州", "宁波", "温州", "绍兴"); + map.put("江苏省", list); + map.put("浙江省", list1); + System.out.println(map); + } +} diff --git a/s_day04/src/com/inmind/map_01/Demo08.java b/s_day04/src/com/inmind/map_01/Demo08.java new file mode 100644 index 0000000..56a76da --- /dev/null +++ b/s_day04/src/com/inmind/map_01/Demo08.java @@ -0,0 +1,79 @@ +package com.inmind.map_01; + +import java.util.Iterator; +import java.util.SortedSet; +import java.util.TreeSet; + +/* +TreeSet和TreeMap对比学习 + +TreeSet是Set接口的一个实现类,有序的集合。 +它的特点: + 1.元素有序(默认自然排序,也可以通过构造方法传入新的排序) + 2.不能重复 + 3.底层是红黑树 + */ +public class Demo08 { + public static void main(String[] args) { + //创建自然排序的treeSet + TreeSet treeSet = new TreeSet<>(); + + treeSet.add(1); + treeSet.add(5); + treeSet.add(4); + treeSet.add(2); + treeSet.add(2); + treeSet.add(2); + treeSet.add(9); + System.out.println(treeSet); + + //之前已学过的Set接口的add,remove,contains + treeSet.remove(9); + System.out.println(treeSet); + System.out.println(treeSet.contains(5)); + + //由于TreeSet拥有排序的效果,所以它能直接获取头尾数据 + + //获取第一个元素first() + System.out.println(treeSet.first()); + //获取最后一个元素last() + System.out.println(treeSet.last()); + + //获取小于指定元素的最大元素(lower()) + System.out.println(treeSet.lower(5)); + + //获取小于等于指定元素的最大元素(floor()) + System.out.println(treeSet.floor(3)); + + //获取大于指定元素的最小元素(higher()) + System.out.println(treeSet.higher(2)); + + //获取大于等于指定元素的最小元素(ceiling()) + System.out.println(treeSet.ceiling(3)); + + //截取子集:截取子集合(headSet():小于指定元素) + SortedSet set = treeSet.headSet(5); + System.out.println(set); + + //截取子集合(tailSet():大于等于指定元素) + SortedSet set1 = treeSet.tailSet(2); + System.out.println(set1); + //截取子集合(subSet():大于等于fromElement,小于toElement) + System.out.println(treeSet.subSet(2, 6)); + + //升序迭代 + for (Integer i : treeSet) { + System.out.print(i+" "); + } + System.out.println(); + System.out.println("-----------------"); + + //降序迭代 + Iterator integerIterator = treeSet.descendingIterator(); + while (integerIterator.hasNext()) { + System.out.print( + integerIterator.next()+" " + ); + } + } +} diff --git a/s_day04/src/com/inmind/map_01/Demo09.java b/s_day04/src/com/inmind/map_01/Demo09.java new file mode 100644 index 0000000..cc9a91e --- /dev/null +++ b/s_day04/src/com/inmind/map_01/Demo09.java @@ -0,0 +1,33 @@ +package com.inmind.map_01; + +import java.util.Collections; +import java.util.Comparator; +import java.util.TreeSet; + +/* +9.1 TreeSet保存自定义对象 +注意:TreeSet会使用元素的自带的自然排序功能Comparable接口 +TreeSet的底层就是TreeMap + */ +public class Demo09 { + public static void main(String[] args) { + TreeSet treeSet = new TreeSet<>(); + treeSet.add(new Student("Jack", 21)); + treeSet.add(new Student("Mary", 25)); + treeSet.add(new Student("Tom", 23)); + + System.out.println(treeSet); + System.out.println("---------------------------------"); + TreeSet treeSet2 = new TreeSet<>(new Comparator() { + @Override + public int compare(Student o1, Student o2) { + return o1.age - o2.age; + } + }); + treeSet2.add(new Student("Jack", 21)); + treeSet2.add(new Student("Mary", 25)); + treeSet2.add(new Student("Tom", 23)); + + System.out.println(treeSet2); + } +} diff --git a/s_day04/src/com/inmind/map_01/Demo10.java b/s_day04/src/com/inmind/map_01/Demo10.java new file mode 100644 index 0000000..a072c98 --- /dev/null +++ b/s_day04/src/com/inmind/map_01/Demo10.java @@ -0,0 +1,91 @@ +package com.inmind.map_01; + +import java.util.TreeMap; + +/* +TreeMap的基本使用 +带有自然排序功能的双列集合(以Key值的自然排序功能进行排序) + +TreeMap 常用 API 总结 +基本操作: +put(K key, V value): 添加键值对,键重复时覆盖值 +get(Object key): 获取指定键对应的值 +remove(Object key): 删除指定键的键值对 +containsKey(Object key): 判断是否包含指定键 +containsValue(Object value): 判断是否包含指定值 +size(): 返回键值对数量 +clear(): 清空所有键值对 + +视图获取 +keySet(): 返回所有键的 Set 集合 +values(): 返回所有值的 Collection 集合 +entrySet(): 返回所有键值对的 Set 集合 +导航方法(有序特性相关) +firstEntry()/firstKey(): 获取第一个键值对 / 键 +lastEntry()/lastKey(): 获取最后一个键值对 / 键 +lowerKey(K key): 获取小于指定键的最大键 +higherKey(K key): 获取大于指定键的最小键 +floorEntry(K key): 获取小于等于指定键的最大键值对 +ceilingEntry(K key): 获取大于等于指定键的最小键值对 +子映射操作 +headMap(K toKey): 返回键小于 toKey 的子映射 +tailMap(K fromKey): 返回键大于等于 fromKey 的子映射 +subMap(K fromKey, K toKey): 返回键在 [fromKey, toKey) 范围内的子映射 + */ +public class Demo10 { + public static void main(String[] args) { + /* + 基本操作: + put(K key, V value): 添加键值对,键重复时覆盖值 + get(Object key): 获取指定键对应的值 + remove(Object key): 删除指定键的键值对 + containsKey(Object key): 判断是否包含指定键 + containsValue(Object value): 判断是否包含指定值 + size(): 返回键值对数量 + clear(): 清空所有键值对 + */ + TreeMap treeMap = new TreeMap<>(); + treeMap.put(1, "刘备"); + treeMap.put(3, "张飞"); + treeMap.put(2, "关羽"); + treeMap.put(3, "张飞"); + treeMap.put(4, "吕布"); + System.out.println(treeMap); + System.out.println(treeMap.get(4)); + String remove = treeMap.remove(4); + System.out.println(remove); + System.out.println(treeMap.containsKey(1)); + System.out.println(treeMap.containsKey(4)); + + //导航方法(有序特性相关) + //firstEntry()/firstKey(): 获取第一个键值对 / 键 + System.out.println(treeMap.firstEntry()); + System.out.println(treeMap.firstKey()); + + //lastEntry()/lastKey(): 获取最后一个键值对 / 键 + System.out.println(treeMap.lastEntry()); + System.out.println(treeMap.lastKey()); + + //lowerKey(K key): 获取小于指定键的最大键 + System.out.println(treeMap.lowerKey(5)); + + //higherKey(K key): 获取大于指定键的最小键 + System.out.println(treeMap.higherKey(2)); + + //floorEntry(K key): 获取小于等于指定键的最大键值对 + System.out.println(treeMap.floorEntry(4)); + //ceilingEntry(K key): 获取大于等于指定键的最小键值对 + System.out.println(treeMap.ceilingEntry(1)); + + + //子映射操作 + //headMap(K toKey): 返回键小于 toKey 的子Map + System.out.println(treeMap.headMap(3)); + + //tailMap(K fromKey): 返回键大于等于 fromKey 的子映射 + System.out.println(treeMap.tailMap(2)); + + //subMap(K fromKey, K toKey): 返回键在 [fromKey, toKey) 范围内的子映射 + System.out.println(treeMap.subMap(1, 3));//java:包头不包尾 + } +} diff --git a/s_day04/src/com/inmind/map_01/Demo11.java b/s_day04/src/com/inmind/map_01/Demo11.java new file mode 100644 index 0000000..ef45cf4 --- /dev/null +++ b/s_day04/src/com/inmind/map_01/Demo11.java @@ -0,0 +1,29 @@ +package com.inmind.map_01; + +import java.util.Comparator; +import java.util.TreeMap; +import java.util.TreeSet; + +/* +9.3 TreeMap保存自定义对象 +注意:TreeMap会使用Key键值类型的自带的自然排序功能Comparable接口,如果没有也可以手动传入比较器 +TreeSet其实就是TreeMap + */ +public class Demo11 { + public static void main(String[] args) { + TreeMap treeMap = new TreeMap<>(new Comparator() { + @Override + public int compare(Student o1, Student o2) { + return o1.age-o2.age; + } + }); + treeMap.put(new Student("Jack", 21),"常州"); + treeMap.put(new Student("Mary", 25),"苏州"); + treeMap.put(new Student("Tom", 23),"无锡"); + + System.out.println(treeMap); + + System.out.println("---------------------------------"); + + } +} diff --git a/s_day04/src/com/inmind/map_01/Demo12.java b/s_day04/src/com/inmind/map_01/Demo12.java new file mode 100644 index 0000000..de155b5 --- /dev/null +++ b/s_day04/src/com/inmind/map_01/Demo12.java @@ -0,0 +1,26 @@ +package com.inmind.map_01; + +import java.util.*; + +/* + 在JDK9中对单列和双列集合,定义了一个静态方法of,它能快速创建出简单的集合,保证集合不变的 + + 使用场景: + 在业务编写时,可以设计为不能更改的固定值,营业中,打烊中,准备中 + */ +public class Demo12 { + public static void main(String[] args) { + //List的of方法 + List list = List.of(1, 2, 3, 4, 5); + System.out.println(list); + + //Set的of方法 + Set set = Set.of(1, 2, 3, 4, 5); + System.out.println(set); + + //Map的of方法 + Map map = Map.of(1, "刘备",2,"关羽"); + System.out.println(map); + + } +} diff --git a/s_day04/src/com/inmind/map_01/Student.java b/s_day04/src/com/inmind/map_01/Student.java new file mode 100644 index 0000000..fa50ad8 --- /dev/null +++ b/s_day04/src/com/inmind/map_01/Student.java @@ -0,0 +1,42 @@ +package com.inmind.map_01; + +import java.util.Objects; + +public class Student implements Comparable{ +//public class Student { + String name; + int age; + + public Student(String name, int age) { + this.name = name; + this.age = age; + } + + @Override + public String toString() { + return "Student{" + + "name='" + name + '\'' + + ", age=" + age + + '}'; + } + + @Override + public boolean equals(Object o) { + if (o == null || getClass() != o.getClass()) return false; + Student student = (Student) o; + return age == student.age && Objects.equals(name, student.name); + } + + @Override + public int hashCode() { + return Objects.hash(name, age); + } + + @Override + public int compareTo(Student o) { + //我-它:升序 +// return this.age - o.age; + //它-我:降序 + return o.age - this.age; + } +} diff --git a/s_day04/src/com/inmind/map_01/Test06.java b/s_day04/src/com/inmind/map_01/Test06.java new file mode 100644 index 0000000..4dcad09 --- /dev/null +++ b/s_day04/src/com/inmind/map_01/Test06.java @@ -0,0 +1,62 @@ +package com.inmind.map_01; + +import java.util.HashMap; +import java.util.Map; +import java.util.Scanner; +import java.util.Set; + +/* +7.Map练习统计字符出现的次数 +实现分析: + 1.使用scanner接收输入字符串 + 2.字符串转字符数组 + 3.创建一个键为字符,值为整数的双列集合 + 4.遍历字符数组 + 判断双列集合中是否拥有某个字符为key,如果没有,直接添加,次数设置为1 + 判断双列集合中是否拥有某个字符为key,如果有,直接修改,次数设置为当前次数+1 + 5.遍历双列集合 + + */ +public class Test06 { + public static void main(String[] args) { + //1.使用scanner接收输入字符串 + Scanner sc = new Scanner(System.in); + System.out.println("请输入一个字符串:"); + String str = sc.nextLine(); + //2.字符串转字符数组 + char[] charArray = str.toCharArray(); + //3.创建一个键为字符,值为整数的双列集合 + HashMap map = new HashMap<>(); + //4.遍历字符数组 + printArr(charArray, map); + //5.遍历双列集合 + System.out.println(map); + + //遍历方式一:键找值 + Set keys = map.keySet(); + for (Character key : keys) { + Integer value = map.get(key); + System.out.println(key+":"+value); + } + System.out.println("-------------------------------"); + //遍历方式二:键值对遍历 + Set> entries = map.entrySet(); + for (Map.Entry entry : entries) { + System.out.println(entry.getKey()+":"+entry.getValue()); + } + } + + private static void printArr(char[] charArray, HashMap map) { + for (char c : charArray) { + if (!map.containsKey(c)) { + //判断双列集合中是否拥有某个字符为key,如果没有,直接添加,次数设置为1 + map.put(c, 1); + }else{ + //判断双列集合中是否拥有某个字符为key,如果有,直接修改,次数设置为当前次数+1 + /*Integer currentCount = map.get(c); + map.put(c, currentCount + 1);*/ + map.put(c, map.get(c)+1); + } + } + } +} diff --git a/s_day04/src/com/inmind/sort_02/Demo01.java b/s_day04/src/com/inmind/sort_02/Demo01.java new file mode 100644 index 0000000..8550741 --- /dev/null +++ b/s_day04/src/com/inmind/sort_02/Demo01.java @@ -0,0 +1,43 @@ +package com.inmind.sort_02; + +import java.util.Arrays; +import java.util.Collections; +import java.util.Comparator; + +/* +12.冒泡排序 + +13.接口回调案例:帮助大家理解,Comparator接口如何修改了源码中的排序效果 + */ +public class Demo01 { + public static void main(String[] args) { + int[] arr = {23,12,33,45,15}; + System.out.println(Arrays.toString(arr)); + sort(arr,new Comparator() { + @Override + public int compare(Integer o1, Integer o2) { +// return o1 - o2; + return o2 - o1; + } + }); + System.out.println(Arrays.toString(arr)); + } + + private static void sort(int[] arr, Comparator comparator) { + + //循环嵌套,来实现每轮相隔数据比较,如果左边大于右边则交换 + for (int i = 0; i < arr.length - 1; i++) {//外层循环(轮数) + for (int j = 0; j < arr.length - 1 - i; j++) { + if (comparator.compare(arr[j],arr[j+1]) > 0 ) {//左大右小就交换数据 + int temp = arr[j]; + arr[j] = arr[j + 1]; + arr[j + 1] = temp; + } + } + } +// if (arr[j] > arr[j + 1]) {//左大右小就交换数据 +// if (arr[j] > arr[j + 1]) {//左大右小就交换数据 +// if (arr[j] - arr[j + 1] > 0 ) {//左大右小就交换数据 +// if (arr[j+1] - arr[j] > 0 ) {//左大右小就交换数据 + } +} diff --git a/s_day04/src/com/inmind/sort_02/Demo02.java b/s_day04/src/com/inmind/sort_02/Demo02.java new file mode 100644 index 0000000..c356119 --- /dev/null +++ b/s_day04/src/com/inmind/sort_02/Demo02.java @@ -0,0 +1,32 @@ +package com.inmind.sort_02; + +import java.util.Arrays; +import java.util.Comparator; + +/* + Arrays + public static String toString(int[] a) :返回指定数组内容的字符串表示形式。 + public static void sort(int[] a) :对指定的 int 型数组按数字升序进行排序。 + static void sort(T[] a, Comparator c) 根据指定的比较器引发的顺序对指定的对象数组进行排序。 + */ +public class Demo02 { + public static void main(String[] args) { + String[] arr = {"aa","bb","ab","ba"}; + Integer[] arr2 = {1,2,33,24,52,16}; + System.out.println(Arrays.toString(arr)); + System.out.println(Arrays.toString(arr2)); + + Arrays.sort(arr); + Arrays.sort(arr2); + System.out.println(Arrays.toString(arr)); + System.out.println(Arrays.toString(arr2)); + + Arrays.sort(arr2,new Comparator() { + @Override + public int compare(Integer o1, Integer o2) { + return o2-o1; + } + }); + System.out.println(Arrays.toString(arr2)); + } +} diff --git a/s_day04/src/com/inmind/sort_02/Demo03.java b/s_day04/src/com/inmind/sort_02/Demo03.java new file mode 100644 index 0000000..1e86cea --- /dev/null +++ b/s_day04/src/com/inmind/sort_02/Demo03.java @@ -0,0 +1,59 @@ +package com.inmind.sort_02; +/* + + Student[] 排序 + */ + +import java.util.Arrays; +import java.util.Collections; +import java.util.Comparator; + +/* +12.冒泡排序 + +13.接口回调案例:帮助大家理解,Comparator接口如何修改了源码中的排序效果 + */ +public class Demo03 { + public static void main(String[] args) { + Student s1 = new Student(1, "张三", 20); + Student s2 = new Student(3, "李四", 18); + Student s3 = new Student(5, "张三", 20); + + Student[] stuArr= {s1,s2,s3}; + + System.out.println(Arrays.toString(stuArr)); + sort(stuArr,new Comparator() { + @Override + public int compare(Student o1, Student o2) { +// return o1 - o2; + //先按年龄降序排,如果相同则按学号升序排 + int result = o2.age - o1.age; + if (result == 0){ + return o1.id - o2.id; + }else { + return result; + } + } + }); + System.out.println(Arrays.toString(stuArr)); + } + + private static void sort(Student[] arr, Comparator comparator) { + + //循环嵌套,来实现每轮相隔数据比较,如果左边大于右边则交换 + for (int i = 0; i < arr.length - 1; i++) {//外层循环(轮数) + for (int j = 0; j < arr.length - 1 - i; j++) { + if (comparator.compare(arr[j],arr[j+1]) > 0 ) {//左大右小就交换数据 + Student temp = arr[j]; + arr[j] = arr[j + 1]; + arr[j + 1] = temp; + } + } + } +// if (arr[j] > arr[j + 1]) {//左大右小就交换数据 +// if (arr[j] > arr[j + 1]) {//左大右小就交换数据 +// if (arr[j] - arr[j + 1] > 0 ) {//左大右小就交换数据 +// if (arr[j+1] - arr[j] > 0 ) {//左大右小就交换数据 + } +} + diff --git a/s_day04/src/com/inmind/sort_02/Student.java b/s_day04/src/com/inmind/sort_02/Student.java new file mode 100644 index 0000000..2476853 --- /dev/null +++ b/s_day04/src/com/inmind/sort_02/Student.java @@ -0,0 +1,45 @@ +package com.inmind.sort_02; + +import java.util.Objects; + +public class Student implements Comparable{ + int id; +//public class Student { + String name; + int age; + + public Student(int id, String name, int age) { + this.id = id; + this.name = name; + this.age = age; + } + + @Override + public String toString() { + return "Student{" + + "id=" + id + + ", name='" + name + '\'' + + ", age=" + age + + '}'; + } + + @Override + public boolean equals(Object o) { + if (o == null || getClass() != o.getClass()) return false; + Student student = (Student) o; + return age == student.age && Objects.equals(name, student.name); + } + + @Override + public int hashCode() { + return Objects.hash(name, age); + } + + @Override + public int compareTo(Student o) { + //我-它:升序 +// return this.age - o.age; + //它-我:降序 + return o.age - this.age; + } +} diff --git a/s_day04/src/com/inmind/test_03/CartSytem.java b/s_day04/src/com/inmind/test_03/CartSytem.java new file mode 100644 index 0000000..063d676 --- /dev/null +++ b/s_day04/src/com/inmind/test_03/CartSytem.java @@ -0,0 +1,184 @@ +package com.inmind.test_03; + + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Map; +import java.util.Scanner; + +public class CartSytem { + //保存所有的商品list + private static ArrayList products = new ArrayList<>(); + //保存购物车map + private static HashMap carts = new HashMap<>(); + private static Scanner sc = new Scanner(System.in); + + public static void main(String[] args) { + //初始化商品 + initData(); + + //提示 + System.out.println("===== 简易购物系统 ====="); + + showMainMenu(); + } + + private static void showMainMenu() { + while (true) { + boolean flag = false; + System.out.println(); + System.out.println(); + System.out.println("===== 主菜单 ====="); + System.out.println("1. 浏览所有商品"); + System.out.println("2. 搜索商品"); + System.out.println("3. 查看购物车"); + System.out.println("4. 添加商品到购物车"); + System.out.println("5. 修改购物车商品数量"); + System.out.println("6. 清空购物车"); + System.out.println("7. 退出"); + System.out.println("8. 按分类去查看商品???"); + System.out.println("请选择:"); + int choice = sc.nextInt(); + if (choice<1||choice>7) { + System.out.println("无效的选项"); + continue; + } + + switch (choice) { + case 1: browsProducts(); break; + case 2: searchProduct(); break; + case 3: showCarts(); break; + case 4: addCart(); break; + case 5: putCart(); break; + case 6: clearCart(); break; + case 7: + System.out.println("谢谢使用!!再见"); + flag = true; + break; + } + + if (flag) { + break;//结束外面的死循环 + } + } + } + + private static void clearCart() { + carts.clear(); + System.out.println("购物车已清空"); + } + + private static void putCart() { + System.out.println("请输入要修改的商品ID:"); + sc.nextLine(); + String pId = sc.nextLine(); + //先判断下是否有该商品 + Product product = null; + for (Product p : carts.keySet()) { + if (p.getId().equals(pId)) { + product = p; + } + } + //如果有则保存数量,如没有则return + if (product == null) { + System.out.println("购物车中未找到该商品"); + return; + } + + System.out.println("请输入新的数量:"); + int quantity = sc.nextInt(); + + carts.put(product,quantity); + System.out.println("数量已更新"); + } + + private static void addCart() { + System.out.println("请输入商品ID: "); + sc.nextLine(); + String pId = sc.nextLine(); + //先判断下是否有该商品 + Product product = null; + for (Product p : products) { + if (p.getId().equals(pId)) { + product = p; + } + } + //如果有则保存数量,如没有则return + if (product == null) { + System.out.println("未找到该商品"); + return; + } + + System.out.println("请输入购买数量:"); + int quantity = sc.nextInt(); + + //添加到购物车,product:数量 + if (carts.containsKey(product)) { + carts.put(product, carts.get(product) + quantity); + } else { + carts.put(product, quantity); + } + System.out.println("已加入购物车"); + + } + + private static void showCarts() { + System.out.println("===== 购物车 ====="); + if (carts.isEmpty()) { + System.out.println("购物车是空的!!"); + return; + } + + int total = 0;//总价 + for (Map.Entry entry : carts.entrySet()) { + Product product = entry.getKey(); + Integer count = entry.getValue(); + int sum = product.getPrice()*count; + System.out.println(product.getName()+", 数量: "+count+", 小计: ¥"+sum); + total += sum; + } + + System.out.println("购物车总计: ¥"+total); + } + + private static void searchProduct() { + System.out.println("请输入商品名称关键字:"); + sc.nextLine(); + String search = sc.nextLine(); + ArrayList searchLists = new ArrayList<>(); + for (Product product : products) { + if (product.getName().contains(search)) { + searchLists.add(product); + } + } + + System.out.println("===== 搜索结果 ====="); + if (searchLists.size() == 0) { + System.out.println("没有找到匹配的商品"); + } else { + for (Product product : searchLists) { + System.out.println(product); + } + } + } + + private static void browsProducts() { + System.out.println("===== 所有商品 ====="); + for (Product product : products) { + System.out.println(product); + } + System.out.println(); + } + + private static void method() { + + } + + private static void initData() { + products.add(new Product("P01", "笔记本电脑", 5999, "电子产品", 10)); + products.add(new Product("P02", "机械键盘", 299, "电脑配件", 20)); + products.add(new Product("P03", "无线鼠标", 129, "电脑配件", 30)); + products.add(new Product("P04", "蓝牙耳机", 799, "音频设备", 15)); + products.add(new Product("P05", "智能手机", 3999, "电子产品", 25)); + } +} diff --git a/s_day04/src/com/inmind/test_03/Product.java b/s_day04/src/com/inmind/test_03/Product.java new file mode 100644 index 0000000..e68baa0 --- /dev/null +++ b/s_day04/src/com/inmind/test_03/Product.java @@ -0,0 +1,83 @@ +package com.inmind.test_03; + +import java.util.Objects; + +public class Product { + //商品编号 + private String id; + //名称 + private String name; + //价格 + private Integer price; + //分类 + private String category; + //数量 + private Integer quantity; + + + public Product(String id, String name, Integer price, String category, Integer quantity) { + this.id = id; + this.name = name; + this.price = price; + this.category = category; + this.quantity = quantity; + } + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public Integer getPrice() { + return price; + } + + public void setPrice(Integer price) { + this.price = price; + } + + public String getCategory() { + return category; + } + + public void setCategory(String category) { + this.category = category; + } + + public Integer getQuantity() { + return quantity; + } + + public void setQuantity(Integer quantity) { + this.quantity = quantity; + } + + + @Override + public String toString() { + return "ID: "+this.id+", 名称: "+this.name+", 价格: ¥"+this.price+", 分类: "+this.category+", 库存: "+this.quantity; + } + + @Override + public boolean equals(Object o) { + if (!(o instanceof Product)) return false; + Product product = (Product) o; + return Objects.equals(id, product.id); + } + + @Override + public int hashCode() { + return Objects.hashCode(id); + } +} diff --git a/s_day04/src/com/inmind/test_03/Test01.java b/s_day04/src/com/inmind/test_03/Test01.java new file mode 100644 index 0000000..d41f4ed --- /dev/null +++ b/s_day04/src/com/inmind/test_03/Test01.java @@ -0,0 +1,97 @@ +package com.inmind.test_03; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.HashMap; + +/* +//1.使用Map优化昨天案例,展示方便 + +Map +♠3>♥3>♦3>♣3 + +1----梅花3 +2----方片3 +3----红桃3 +4----黑桃3 +1~54作为键值保存到ArrayList,洗牌 +创建4个集合摸牌 +将排的键值抓到集合中 +Collections.sort +打印输出集合内容即可 + */ +public class Test01 { + public static void main(String[] args) { + String[] nums = {"3", "4", "5", "6", "7", "8", "9", "10", "J", "Q", "K", "A", "2"}; + String[] colors = {"♠", "♥", "♣", "♦"}; + //1.准备54张牌和指定整数一一对应 + HashMap pokers = new HashMap<>(); + ArrayList keys = new ArrayList<>(); + int index = 1; + for (String num : nums) { + for (String color : colors) { + String poker = color+num; + keys.add(index); + pokers.put(index, poker); + index++; + } + } + //添加大小王 + pokers.put(53, "小王"); + pokers.put(54, "大王"); + keys.add(53); + keys.add(54); + + System.out.println(keys); + System.out.println(pokers); + //洗牌 + Collections.shuffle(keys); + + System.out.println(pokers); + //3.创建3个集合轮流摸牌,创建1个集合保存底牌 + ArrayList player1 = new ArrayList<>(); + ArrayList player2 = new ArrayList<>(); + ArrayList player3 = new ArrayList<>(); + ArrayList dipai = new ArrayList<>(); + /* + 玩家1 0 3 6 %3 = 0 + 玩家2 1 4 7 %3 = 1 + 玩家3 2 5 8 %3 = 2 + */ + for (int i = 0; i < keys.size(); i++) { + if (i >= pokers.size() - 3) { + dipai.add(keys.get(i)); + }else{ + switch (i%3) { + case 0: + player1.add(keys.get(i)); + break; + case 1: + player2.add(keys.get(i)); + break; + case 2: + player3.add(keys.get(i)); + break; + } + } + } + + showPokers("周润发",player1,pokers); + showPokers("周星驰",player2,pokers); + showPokers("周星星",player3,pokers); + showPokers("王宝强",dipai,pokers); + + } + + private static void showPokers(String name, ArrayList cards, HashMap pokers) { + Collections.sort(cards); + //键找值拿牌展示 + String content = ""; + for (Integer key : cards) { + String poker = pokers.get(key); + content += poker+" "; + } + System.out.println(name+":"+content); + } +} diff --git a/s_day05/src/com/inmind/catch_exceptions_03/Demo01.java b/s_day05/src/com/inmind/catch_exceptions_03/Demo01.java new file mode 100644 index 0000000..33adcd8 --- /dev/null +++ b/s_day05/src/com/inmind/catch_exceptions_03/Demo01.java @@ -0,0 +1,45 @@ +package com.inmind.catch_exceptions_03; +/* + 11.try..catch处理多个异常 + + 在实际开发中,一段业务代码,可能会出现多种不同的异常,所以我们要进行多异常处理 + + try...catch的语法: + try{ + 可能会出现异常的代码或者方法 + }catch(指定异常类名 变量名){ + 捕获异常后,异常处理代码 + }catch(指定异常类名 变量名){ + 捕获异常后,异常处理代码 + }catch(指定异常类名 变量名){ + 捕获异常后,异常处理代码 + }..... + + 注意:在实际开发中,具体的异常处理,都是要进行相关的业务操作,而不是固定操作 + */ +public class Demo01 { + public static void main(String[] args) { + try { + int i = 7; + if (i < 5) { + throw new NullPointerException(); + } + if (i > 10) { + throw new ArrayIndexOutOfBoundsException(); + } + + throw new Exception(); + + }catch (ArrayIndexOutOfBoundsException e) { + System.out.println("捕获了越界异常"); + }catch (NullPointerException e) { + System.out.println("捕获了空异常"); + }catch (Exception e) { + System.out.println("大范围异常放最后保底操作,之前的catch,如果都没有捕获到异常,那么我们就抓一个最大的异常来确保JVM不能得到异常"); + }finally { + System.out.println("finally"); + } + + System.out.println("程序结束"); + } +} diff --git a/s_day05/src/com/inmind/catch_exceptions_03/Demo02.java b/s_day05/src/com/inmind/catch_exceptions_03/Demo02.java new file mode 100644 index 0000000..d3d374d --- /dev/null +++ b/s_day05/src/com/inmind/catch_exceptions_03/Demo02.java @@ -0,0 +1,29 @@ +package com.inmind.catch_exceptions_03; +/* +12.try..catch..finally里面有return的注意事项(了解) + +注意:由于finally的特殊性性,导致如果在finally中书写return,还是会执行,并修改原本的返回值!!! + */ +public class Demo02 { + public static void main(String[] args) { + int result = getValue(); + System.out.println("main方法中:"+result);//20还是30呢?? + } + + private static int getValue() { + int resutlt = 10; + + try { + resutlt = 20; + return resutlt;//先执行return result;return会将对应的值20,记录为返回值 + }catch (Exception e) { + e.printStackTrace(); + } finally { + //try中return执行之后,finally也还是会执行的!!! + resutlt = 30; + System.out.println("finally中:"+resutlt); + return resutlt;//最后执行return result;将之前的返回结果,覆盖为最新的值 + } +// return resutlt; + } +} diff --git a/s_day05/src/com/inmind/catch_exceptions_03/Demo03.java b/s_day05/src/com/inmind/catch_exceptions_03/Demo03.java new file mode 100644 index 0000000..f22d9f1 --- /dev/null +++ b/s_day05/src/com/inmind/catch_exceptions_03/Demo03.java @@ -0,0 +1,35 @@ +package com.inmind.catch_exceptions_03; +/* +13.Throwable里面的三个方法 + String getMessage() 返回此可抛出的简短描述。 + String toString() 返回此throwable的详细消息字符串。 + void printStackTrace() 将此throwable的错误信息直接打印在控制台(我们主动打印错误信息) + */ +public class Demo03 { + public static void main(String[] args) { + try { + int[] arr = {1, 2, 3, 4, 5}; + //定义出一个根据索引获取指定的值的方法 + int result = getValue(arr,8); + } catch (Exception e) {// Exception e = new ArrayIndexOutOfBoundsException(msg) + String message = e.getMessage(); + System.out.println(message); + System.out.println(e.toString()); + + e.printStackTrace();//我们程序员自己主动将异常信息以日志的形式打印到控制台(日志打印JVM采用的是多线程导致) + } finally { + } + + System.out.println("程序结束"); + } + private static int getValue(int[] arr, int i) { + //此处索引i可能越界,我们能不能自己抛出异常呢? + if (i >= (arr.length - 1) || i < 0) { +// throw new ArrayIndexOutOfBoundsException(); + String msg = "数组的最大索引为"+(arr.length-1)+",当前索引为"+i+",索引不合法"; + throw new ArrayIndexOutOfBoundsException(msg); + } + int result = arr[i]; + return result; + } +} diff --git a/s_day05/src/com/inmind/custom_exception04/Demo01.java b/s_day05/src/com/inmind/custom_exception04/Demo01.java new file mode 100644 index 0000000..b2d80e6 --- /dev/null +++ b/s_day05/src/com/inmind/custom_exception04/Demo01.java @@ -0,0 +1,34 @@ +package com.inmind.custom_exception04; + +import java.util.Scanner; + +/* +要求:我们模拟注册操作,如果用户名已存在,则抛出异常并提示:亲,该用户名已经被注册。 +使用异常来实现,用户名已注册的信息提示业务逻辑 + */ +public class Demo01 { + static String[] usernames = {"zhangsan","lisi","wangwu"}; + + public static void main(String[] args) { + Scanner sc = new Scanner(System.in); + System.out.println("请输入您的用户名:"); + String username = sc.nextLine(); + try { + regist(username); + } catch (RegistException e) { + e.printStackTrace(); + System.out.println(e.getMessage()); + } + + System.out.println("程序结束"); + } + + private static void regist(String username) throws RegistException{ + //如果用户名相同就抛出异常 + for (String user : usernames) { + if (user.equals(username)) { + throw new RegistException("该用户已经注册了"); + } + } + } +} diff --git a/s_day05/src/com/inmind/custom_exception04/RegistException.java b/s_day05/src/com/inmind/custom_exception04/RegistException.java new file mode 100644 index 0000000..ad9caa2 --- /dev/null +++ b/s_day05/src/com/inmind/custom_exception04/RegistException.java @@ -0,0 +1,13 @@ +package com.inmind.custom_exception04; +/* +自定义注册失败异常 + 1.编译时异常:提醒代码有语法问题,带有检查型功能,extends Exception + 2.运行时异常:用来处理业务逻辑的,不带有检查型功能,extends RuntimeException + */ +public class RegistException extends RuntimeException{ + public RegistException() { + } + public RegistException(String message) { + super(message); + } +} diff --git a/s_day05/src/com/inmind/exception_01/Demo01.java b/s_day05/src/com/inmind/exception_01/Demo01.java new file mode 100644 index 0000000..be4b192 --- /dev/null +++ b/s_day05/src/com/inmind/exception_01/Demo01.java @@ -0,0 +1,22 @@ +package com.inmind.exception_01; +/* +异常:程序运行时,会产生的一些问题或者错误。 + +在java中有一个类专门来表示错误和异常,Throwable +Throwable类是Java语言中所有错误和异常的超类。 + Throwable分类: + 1.错误 Error,表示程序发生不可挽救的错误。 + 2.异常Exception,表示程序发生轻微问题,可以处理。 + + */ +public class Demo01 { + public static void main(String[] args) { + int[] arr = {1, 2, 3, 4, 5}; +// System.out.println(arr[8]); + + int[] arr1 = new int[10000*1000*100]; + int[] arr2 = new int[10000*1000*100]; + int[] arr3 = new int[10000*1000*100]; + System.out.println(arr1); + } +} diff --git a/s_day05/src/com/inmind/exception_01/Demo02.java b/s_day05/src/com/inmind/exception_01/Demo02.java new file mode 100644 index 0000000..0b195e6 --- /dev/null +++ b/s_day05/src/com/inmind/exception_01/Demo02.java @@ -0,0 +1,35 @@ +package com.inmind.exception_01; +/* + 3.异常产生的原因以及流程 + + throw关键字的作用 + 之前的代码中如果出现异常都是JVM创建并抛出的,那么我们能不能自己抛出异常呢??? + 可以,throw能够让java开发人员自己抛出一个异常。 + 语法:throw new 异常名(); + + 为何要自己抛出异常,而不使用JVM的异常操作呢???? + 1.自己抛出的异常,是根据具体的业务进行操作 + 2.JVM会直接终止程序。 + + */ +public class Demo02 { + public static void main(String[] args) { + int[] arr = {1, 2, 3, 4, 5}; + + //定义出一个根据索引获取指定的值的方法 + int result = getValue(arr,8); + + System.out.println("程序结束"); + } + + private static int getValue(int[] arr, int i) { + //此处索引i可能越界,我们能不能自己抛出异常呢? + if (i >= (arr.length - 1) || i < 0) { +// throw new ArrayIndexOutOfBoundsException(); + String msg = "数组的最大索引为"+(arr.length-1)+",当前索引为"+i+",索引不合法"; + throw new ArrayIndexOutOfBoundsException(msg); + } + int result = arr[i]; + return result; + } +} diff --git a/s_day05/src/com/inmind/exception_01/Demo03.java b/s_day05/src/com/inmind/exception_01/Demo03.java new file mode 100644 index 0000000..21651e6 --- /dev/null +++ b/s_day05/src/com/inmind/exception_01/Demo03.java @@ -0,0 +1,24 @@ +package com.inmind.exception_01; + +import java.util.Objects; + +/* +Objects里面的requireNonNull方法(了解) +JDK源码中,它也使用通过throw主动抛出一个异常,而不是让JVM抛出 + +总结,该API就是提醒大家,要自己抛出异常,那就用throw关键字 + */ +public class Demo03 { + public static void main(String[] args) { + //判断一个引用数据类型,是否是null,是则主动抛出一个空指针异常 + String str = null; + /*if (str == null) { +// throw new NullPointerException(); + throw new NullPointerException("str is null"); + }*/ + //如果为空则抛出空异常 + Objects.requireNonNull(str, "str is null"); + + System.out.println("程序结束"); + } +} diff --git a/s_day05/src/com/inmind/exception_01/Demo04.java b/s_day05/src/com/inmind/exception_01/Demo04.java new file mode 100644 index 0000000..4a07215 --- /dev/null +++ b/s_day05/src/com/inmind/exception_01/Demo04.java @@ -0,0 +1,34 @@ +package com.inmind.exception_01; +/* +6.throws关键字 +throws:声明一个异常,提醒方法的调用者,指定方法可能会抛出某些异常,但是也可能不抛异常 +throw:真的抛出一个真正的异常 + +throws关键字的语法格式: +方法修饰符 返回值类型 方法名(参数列表) throws 异常名1,异常名2.... { + 方法体 +} + +注意点: +1.方法中如果抛出一个编译时异常,一定要处理(try-catch)或throws声明出去 +2.如果调用了一个声明了编译时异常的方法,那么当前方法中也一定要处理try-catch)或throws声明出去 +3.如果一个方法中没有异常,我们也是可以声明异常的 + +总结:throws的作用什么?? + 提醒方法调用者,指定方法,可能出异常,当我们想将本方法中可能出现的异常交给别人去处理,那么就使用throws + */ +public class Demo04 { + public static void main(String[] args) throws Exception{ +// method1(); + method2(); + } + + private static void method2() throws Exception{ + //正常操作,没有任何异常 + } + + private static void method1() throws Exception {//该方法声明可能会出现Exception,自己不处理,由调用者处理 + //手动真的抛出一个编译时异常 + throw new Exception(); + } +} diff --git a/s_day05/src/com/inmind/exception_01/ExceptionDiffDemo07.java b/s_day05/src/com/inmind/exception_01/ExceptionDiffDemo07.java new file mode 100644 index 0000000..85d9d9a --- /dev/null +++ b/s_day05/src/com/inmind/exception_01/ExceptionDiffDemo07.java @@ -0,0 +1,44 @@ +package com.inmind.exception_01; + + +/* +9.运行时异常和编译时异常的区别 +运行时异常:属于非检查型异常,无需强制处理,可以通过优化代码逻辑,避免异常。 +编译时异常:属于检查型异常,在编写阶段,可能出现语法问题必须处理,需要程序员预见并处理可能的异常情况,可以通过try-catch或throws处理 + +总结:编写代码时,编译时异常必须处理,而运行时异常,可以选择性地处理 + +一个方法中的异常可以有2种处理方式: + 1.throws 声明出去 + 2.try-catch 自己处理 +在main方法顶层,真正能处理掉异常的只有try-catch + */ +public class ExceptionDiffDemo07 { + public static void main(String[] args) { + try { + method2(); + } catch (Exception e) { + System.out.println(e); + } finally { + + } + System.out.println("程序结束"); + } + + private static void method2() { + throw new RuntimeException(); + } + + // private static void method1() throws Exception{ + private static void method1() { + //alt+enter + try { + System.out.println("method1"); + System.out.println("method1"); + System.out.println("method1"); + throw new Exception();//检查型,编译异常 + } catch (Exception e) { + throw new RuntimeException(e); + } + } +} diff --git a/s_day05/src/com/inmind/exception_01/TryCatchDemo05.java b/s_day05/src/com/inmind/exception_01/TryCatchDemo05.java new file mode 100644 index 0000000..5385429 --- /dev/null +++ b/s_day05/src/com/inmind/exception_01/TryCatchDemo05.java @@ -0,0 +1,46 @@ +package com.inmind.exception_01; +/* +7.try...catch异常处理方式以及执行流程 +之前throws关键字只是将异常声明出去,交给调用者处理,没有真正地处理异常,那么如何真的解决异常呢??? + +try...catch的作用:真的处理掉异常,JVM不会再接收到异常,程序就会正常执行 +try...catch的语法: + try{ + 可能会出现异常的代码或者方法 + }catch(指定异常类名 变量名){ + 捕获异常后,异常处理代码 + } + + +try-catch的执行顺序: + 1.当try中的代码,如果没有发现异常,那么try中的代码正常执行,并且catch中的代码就不执行 + 2.当try中的代码,如果发现了异常,那么try中在产生异常之后的代码就不会执行,如果catch捕获到异常,那么catch后面的代码会执行,程序正常执行 + 3.当try中的代码,如果发现了异常,那么try中在产生异常之后的代码就不会执行,如果catch没有捕获到异常, + 那么catch后面的代码也不会执行,会将没有捕获到的异常交给JVM,JVM打印异常信息,程序异常终止 + */ +public class TryCatchDemo05 { + public static void main(String[] args) { + + try { + System.out.println("try中方法-----开始了【1】"); + int[] arr = {1, 2, 3, 4, 5}; + int result = getValue(arr,8); + System.out.println("try中方法-----结束了【2】"); + }catch(ArrayIndexOutOfBoundsException e){ + System.out.println("捕获了异常------【3】"); + System.out.println("处理了数组索引越界异常"); + } + + System.out.println("程序结束-------【4】"); + } + + private static int getValue(int[] arr, int i) { + if (i >= (arr.length - 1) || i < 0) { + String msg = "数组的最大索引为"+(arr.length-1)+",当前索引为"+i+",索引不合法"; +// throw new ArrayIndexOutOfBoundsException(msg); + throw new NullPointerException(msg); + } + int result = arr[i]; + return result; + } +} diff --git a/s_day05/src/com/inmind/exception_01/TryCatchFinallyDemo06.java b/s_day05/src/com/inmind/exception_01/TryCatchFinallyDemo06.java new file mode 100644 index 0000000..969761e --- /dev/null +++ b/s_day05/src/com/inmind/exception_01/TryCatchFinallyDemo06.java @@ -0,0 +1,51 @@ +package com.inmind.exception_01; +/* +8.try..catch...finally的格式以及执行流程 + +try...catch....finally的作用:保证一段代码不管是否出现异常,不管该异常是否被处理,此段代码一定执行(IO的资源释放,数据库连接资源释放) +try...catch....finally的语法: + try{ + 可能会出现异常的代码或者方法 + }catch(指定异常类名 变量名){ + 捕获异常后,异常处理代码 + }finally{ + 一定要执行的代码 + } + + +try-catch....finally的执行顺序: + 1.当try中的代码,如果没有发现异常,那么try中的代码正常执行,并且catch中的代码就不执行, + 遇到finally中的代码正常执行 + 2.当try中的代码,如果发现了异常,那么try中在产生异常之后的代码就不会执行,如果catch捕获到异常,那么catch后面的代码会执行, + 遇到finally中的代码正常执行,程序正常执行 + 3.当try中的代码,如果发现了异常,那么try中在产生异常之后的代码就不会执行,如果catch没有捕获到异常, + 那么catch后面的代码也不会执行, + 遇到finally中的代码正常执行,执行完Finally之后,会将没有捕获到的异常交给JVM,JVM打印异常信息,程序异常终止 + */ +public class TryCatchFinallyDemo06 { + public static void main(String[] args) { + + try { + System.out.println("try中方法-----开始了【1】"); + int[] arr = {1, 2, 3, 4, 5}; + int result = getValue(arr,8); + System.out.println("try中方法-----结束了【2】"); + }catch(ArrayIndexOutOfBoundsException e){ + System.out.println("捕获了异常------【3】"); + System.out.println("处理了数组索引越界异常"); + }finally { + System.out.println("finally中的代码执行了------【4】"); + } + + System.out.println("程序结束-------【5】"); + } + private static int getValue(int[] arr, int i) { + if (i >= (arr.length - 1) || i < 0) { + String msg = "数组的最大索引为"+(arr.length-1)+",当前索引为"+i+",索引不合法"; +// throw new ArrayIndexOutOfBoundsException(msg); + throw new NullPointerException(msg); + } + int result = arr[i]; + return result; + } +} diff --git a/s_day05/src/com/inmind/extends_exception_02/Demo01.java b/s_day05/src/com/inmind/extends_exception_02/Demo01.java new file mode 100644 index 0000000..411f19f --- /dev/null +++ b/s_day05/src/com/inmind/extends_exception_02/Demo01.java @@ -0,0 +1,10 @@ +package com.inmind.extends_exception_02; +/* +继承关系中异常的处理 +如果父类方法声明出一编译异常,子类重写时如果不调用父类方法,可以不处理 +如果父类方法声明出一编译异常,子类重写时想要声明出异常时,子类方法只能声明出父类的异常或该异常的子类 +父类方法没有声明异常,子类重写父类该方法时也不可声明异常。此时子类中的异常只能try-catch +第三点事项只适用于编译时异常,如果是运行时异常,不受任何影响 + */ +public class Demo01 { +} diff --git a/s_day05/src/com/inmind/extends_exception_02/Fu.java b/s_day05/src/com/inmind/extends_exception_02/Fu.java new file mode 100644 index 0000000..2a84133 --- /dev/null +++ b/s_day05/src/com/inmind/extends_exception_02/Fu.java @@ -0,0 +1,14 @@ +package com.inmind.extends_exception_02; + +import java.io.IOException; + +public class Fu { + public void method() { + + } + + + public void method1() throws IndexOutOfBoundsException{ + + } +} diff --git a/s_day05/src/com/inmind/extends_exception_02/Zi.java b/s_day05/src/com/inmind/extends_exception_02/Zi.java new file mode 100644 index 0000000..a52ea35 --- /dev/null +++ b/s_day05/src/com/inmind/extends_exception_02/Zi.java @@ -0,0 +1,35 @@ +package com.inmind.extends_exception_02; + +import java.io.IOException; +import java.util.zip.ZipException; + +/* +继承关系中异常的处理的注意点: +如果父类方法声明出一编译异常,子类重写时如果不调用父类方法,可以不处理 +如果父类方法声明出一编译异常,子类重写时想要声明出异常时,子类方法只能声明出父类的异常或该异常的子类 +父类方法没有声明异常,子类重写父类该方法时也不可声明异常。此时子类中的异常只能try-catch +以上三点事项只适用于编译时异常,如果是运行时异常,不受任何影响 + + +总结: +1.编译时异常:强制使用功能时,必须处理指定异常,常用于调用第三方功能代码时的限制 +2.运行时异常,不强制必须处理,常用于程序中的业务功能处理 + */ +public class Zi extends Fu{ + + //如果父类方法声明出一编译异常,子类重写时想要声明出异常时,子类方法只能声明出父类的异常或该异常的子类 + @Override + public void method() { + try { + throw new IOException(); + } catch (IOException e) { + System.out.println(e); + } + } + + + @Override + public void method1() throws RuntimeException{ + super.method1(); + } +} diff --git a/s_day05/src/com/inmind/test_05/Account.java b/s_day05/src/com/inmind/test_05/Account.java new file mode 100644 index 0000000..d16f720 --- /dev/null +++ b/s_day05/src/com/inmind/test_05/Account.java @@ -0,0 +1,68 @@ +package com.inmind.test_05; + +/* +账户类 +存款:验证账户状态和金额有效性 +取款:验证密码(3 次错误锁定)、金额和余额 + */ +public class Account { + String id;//账户ID + String name;//账户名 + double balance;//余额 + int pwdErrors;//密码错误次数 + boolean locked;//是否锁定 + + static final int MaxPwdErrors = 3;//最大密码错误次数 + static final String PWD = "123456";//默认密码 + + public Account(String id, String name, double balance) { + this.id = id; + this.name = name; + this.balance = balance; + this.pwdErrors = 0; + this.locked = false; + } + + //存款:验证账户状态和金额有效性 + public void saveMoney(double amount) throws AccountLockedException,InvalidAmountException{ + //先判断账户有效性 + if (this.locked) { + throw new AccountLockedException(this.id+",这个账户已锁定"); + } + //判断金额 + if (amount <= 0) { + throw new InvalidAmountException("存款金额必须大于0"); + } + this.balance += amount; + System.out.println(this.name +"存款:"+amount+"元,当前余额:"+this.balance); + } + //取款:验证密码(3 次错误锁定)、金额和余额 + public void getMoney(double amount,String pwd) throws AccountLockedException,Exception { + //先判断账户有效性 + if (this.locked) { + throw new AccountLockedException(this.id+",这个账户已锁定"); + } + //密码的判断 + if (!PWD.equals(pwd)) { + pwdErrors++; + if (pwdErrors >= MaxPwdErrors) { + this.locked = true;//如果超过3次,账户锁定 + throw new AccountLockedException("密码错误3次,账户"+this.id+"已锁定"); + } + throw new Exception("密码错误,剩余次数:"+(MaxPwdErrors - this.pwdErrors)); + } + + //判断金额 + if (amount <= 0) { + throw new InvalidAmountException("取款金额必须大于0"); + } + //余额判定 + if (amount > this.balance) { + throw new NotEnoughException("余额不足,当前余额:"+this.balance); + } + + this.balance -= amount; + System.out.println(this.name +"取款:"+amount+",当前余额:"+this.balance); + } + +} diff --git a/s_day05/src/com/inmind/test_05/AccountLockedException.java b/s_day05/src/com/inmind/test_05/AccountLockedException.java new file mode 100644 index 0000000..74f9dfb --- /dev/null +++ b/s_day05/src/com/inmind/test_05/AccountLockedException.java @@ -0,0 +1,12 @@ +package com.inmind.test_05; +/* + 账户锁定异常 + */ +public class AccountLockedException extends BaseBankException{ + public AccountLockedException(){ + + } + public AccountLockedException(String message){ + super(message); + } +} diff --git a/s_day05/src/com/inmind/test_05/Bank.java b/s_day05/src/com/inmind/test_05/Bank.java new file mode 100644 index 0000000..60e5f26 --- /dev/null +++ b/s_day05/src/com/inmind/test_05/Bank.java @@ -0,0 +1,57 @@ +package com.inmind.test_05; +/* +银行类 +转账:校验双方账户、金额和限额,包含取款 + 存款原子操作 +单笔转账上限 50000 元 + */ +public class Bank { + private Account[] accounts;//账户数组 + private int count;//账户的数量 + + static final Double MAX_AMOUNT = 50000.0; + + public Bank(int size) { + accounts = new Account[size]; + count = 0; + } + + //创建账户 + public void addAccount(Account acc) { + //判断银行账户数量是否超过最大值 + if (count < accounts.length) { + accounts[count] = acc; + count++;//保存新的账户,账户数量自增+1 + } + } + + //查找账户 + public Account findAccount(String id)throws Exception { + for (Account account : accounts) { + if (account.id.equals(id)) { + return account; + } + } + throw new Exception("账户:"+id+"不存在"); + } + + //转账:校验双方账户、金额和限额,包含取款 + 存款原子操作 + public void transferMoney(String fromId, String toId, double amount,String pwd) throws Exception{ + //根据账户ID找到各自的账户 + Account fromAccount = findAccount(fromId); + Account toAccount = findAccount(toId); + //金额判断 + if (amount <= 0) { + throw new InvalidAmountException("转账金额必须大于0"); + } + + //判断限额 + if (amount > MAX_AMOUNT) { + throw new TransferLimitException("超过最大转账金额:"+MAX_AMOUNT); + } + //转账原子操作 + fromAccount.getMoney(amount,pwd); + toAccount.saveMoney(amount); + System.out.println("从账户"+fromAccount.name+",向账户"+toAccount.name+"转账"+amount+"元,成功"); + } + +} diff --git a/s_day05/src/com/inmind/test_05/BaseBankException.java b/s_day05/src/com/inmind/test_05/BaseBankException.java new file mode 100644 index 0000000..bf2d267 --- /dev/null +++ b/s_day05/src/com/inmind/test_05/BaseBankException.java @@ -0,0 +1,10 @@ +package com.inmind.test_05; + +//跟银行相关的基础异常类 +public class BaseBankException extends Exception{ + public BaseBankException() { + } + public BaseBankException(String message) { + super(message); + } +} diff --git a/s_day05/src/com/inmind/test_05/InvalidAmountException.java b/s_day05/src/com/inmind/test_05/InvalidAmountException.java new file mode 100644 index 0000000..941c042 --- /dev/null +++ b/s_day05/src/com/inmind/test_05/InvalidAmountException.java @@ -0,0 +1,13 @@ +package com.inmind.test_05; +/* + 金额为负数或零时抛出 + 非法金额异常 + */ +public class InvalidAmountException extends BaseBankException{ + public InvalidAmountException(){ + + } + public InvalidAmountException(String message){ + super(message); + } +} diff --git a/s_day05/src/com/inmind/test_05/NotEnoughException.java b/s_day05/src/com/inmind/test_05/NotEnoughException.java new file mode 100644 index 0000000..ec77a10 --- /dev/null +++ b/s_day05/src/com/inmind/test_05/NotEnoughException.java @@ -0,0 +1,14 @@ +package com.inmind.test_05; +/* + 自定义一个余额不足异常 + */ +public class NotEnoughException extends BaseBankException{ + public NotEnoughException(){ + + } + public NotEnoughException(String message){ + super(message); + } + + //独有的功能,将功能与当前类进行了业务绑定 +} diff --git a/s_day05/src/com/inmind/test_05/Test01.java b/s_day05/src/com/inmind/test_05/Test01.java new file mode 100644 index 0000000..a64dfba --- /dev/null +++ b/s_day05/src/com/inmind/test_05/Test01.java @@ -0,0 +1,68 @@ +package com.inmind.test_05; +/* +自定义异常(4 个): +//NotEnoughException:余额不足时抛出 +InvalidAmountException:金额为负数或零时抛出 +AccountLockedException:账户锁定时抛出 +TransferLimitException:转账超过限额时抛出 +核心功能: +存款:验证账户状态和金额有效性 +取款:验证密码(3 次错误锁定)、金额和余额 +转账:校验双方账户、金额和限额,包含取款 + 存款原子操作 +业务规则: +密码错误 3 次自动锁定账户 +单笔转账上限 50000 元 +不允许负金额交易 +锁定账户无法进行任何操作 + */ +public class Test01 { + public static void main(String[] args) { + Bank bank = new Bank(10); + try { + //银行业务 + //创建账户 + bank.addAccount(new Account("1001","张三",10000)); + bank.addAccount(new Account("1002","李四",5000)); + //正常操作 + Account accountZS = bank.findAccount("1001"); + accountZS.saveMoney(2000); + accountZS.getMoney(1000,"123456"); + + //测试异常 + try { + accountZS.getMoney(20000,"123456"); + } catch (NotEnoughException e) { + System.out.println("异常处理:"+e.getMessage()); + } + + //测试转账限额 + try { + bank.transferMoney("1001","1002",60000,"123456"); + } catch (TransferLimitException e) { + System.out.println("异常处理:"+e.getMessage()); + } + + //密码输错3次 + try { + accountZS.getMoney(2000,"1234"); + } catch (Exception e) { + System.out.println("异常处理:"+e.getMessage()); + } + + try { + accountZS.getMoney(2000,"1234"); + } catch (Exception e) { + System.out.println("异常处理:"+e.getMessage()); + } + + try { + accountZS.getMoney(2000,"1234"); + } catch (Exception e) { + System.out.println("异常处理:"+e.getMessage()); + } + + } catch (Exception e) { + System.out.println("系统错误"+e.getMessage()); + } + } +} diff --git a/s_day05/src/com/inmind/test_05/TransferLimitException.java b/s_day05/src/com/inmind/test_05/TransferLimitException.java new file mode 100644 index 0000000..d561e37 --- /dev/null +++ b/s_day05/src/com/inmind/test_05/TransferLimitException.java @@ -0,0 +1,12 @@ +package com.inmind.test_05; +/* + 转账超过限额异常 + */ +public class TransferLimitException extends BaseBankException{ + public TransferLimitException(){ + + } + public TransferLimitException(String message){ + super(message); + } +} diff --git a/s_day05/src/com/inmind/test_06/PaymentFaildException.java b/s_day05/src/com/inmind/test_06/PaymentFaildException.java new file mode 100644 index 0000000..fd6f595 --- /dev/null +++ b/s_day05/src/com/inmind/test_06/PaymentFaildException.java @@ -0,0 +1,45 @@ +package com.inmind.test_06; + +//支付异常 +public class PaymentFaildException extends Exception{ + //订单号 + private String orderId; + //支付金额 + private double amount; + //业务内部定义的错误码(PAY001 PAY002) + private String errorCode; + + public PaymentFaildException(String message,String orderId, double amount, String errorCode) { + super(message); + this.orderId = orderId; + this.amount = amount; + this.errorCode = errorCode; + } + + public String getOrderId() { + return orderId; + } + + + public double getAmount() { + return amount; + } + + + public String getErrorCode() { + return errorCode; + } + + //生成面向业务的异常消息,格式化为适合业务人员理解的字符串 + public String getBusinessMessage(){ + String msg = ""; + msg = "订单"+this.orderId+",支付失败(金额:"+amount+"),错误码:"+errorCode; + return msg; + } + + public void logToBusinessSystem() { + //实际项目中会使用日志框架(logback) + //输出包含业务标识的日志,便于追溯 + System.out.println("【业务日志:】"+getBusinessMessage()); + } +} diff --git a/s_day05/src/com/inmind/test_06/Test06.java b/s_day05/src/com/inmind/test_06/Test06.java new file mode 100644 index 0000000..9399035 --- /dev/null +++ b/s_day05/src/com/inmind/test_06/Test06.java @@ -0,0 +1,25 @@ +package com.inmind.test_06; +/* +14.2 自定义异常封装业务 + +支付异常类继承Exception,封装一点它的业务功能,给外部调用 + */ +public class Test06 { + public static void main(String[] args) { + try { + method(); + } catch (PaymentFaildException e) { + System.out.println(e.getMessage()); + String businessMessage = e.getBusinessMessage(); + System.out.println(businessMessage); + //进行封装之后的业务操作 + e.logToBusinessSystem(); + } + } + + //模拟一个订单失败操作 + private static void method() throws PaymentFaildException{ + //订单业务操作 + throw new PaymentFaildException("账户余额不足", "G00102", 299.9, "PAY_NOT_ENOUGH"); + } +} diff --git a/s_day05/src/com/inmind/thread_07/Demo01.java b/s_day05/src/com/inmind/thread_07/Demo01.java new file mode 100644 index 0000000..7a3cdda --- /dev/null +++ b/s_day05/src/com/inmind/thread_07/Demo01.java @@ -0,0 +1,16 @@ +package com.inmind.thread_07; +/* +了解主线程 + */ +public class Demo01 { + public static void main(String[] args) { + for (int i = 0; i < 100; i++) { + System.out.println("Helloworld"); + } + System.out.println("--------------------"); + for (int i = 0; i < 100; i++) { + System.out.println("HelloJava"); + } + System.out.println("程序结束"); + } +} diff --git a/s_day05/src/com/inmind/thread_07/Demo02.java b/s_day05/src/com/inmind/thread_07/Demo02.java new file mode 100644 index 0000000..bf5b301 --- /dev/null +++ b/s_day05/src/com/inmind/thread_07/Demo02.java @@ -0,0 +1,21 @@ +package com.inmind.thread_07; +/* +19.多线程的实现 +在java中使用一个类Thread,来表示一个线程 +启动多线程的方式一: +1.定义一个子类继承Thread +2.重写run方法 +3.创建子类对象,调用start方法才能启动线程 + */ +public class Demo02 { + public static void main(String[] args) { + //创建一个线程对象 + MyThread myThread = new MyThread(); + myThread.start();//start方法的作用:真的启动线程,该线程的任务就是直接执行自己的run方法 + System.out.println("----------------"); + for (int i = 0; i < 1000; i++) { + System.out.println("helloWorld"); + } + System.out.println("程序结束"); + } +} diff --git a/s_day05/src/com/inmind/thread_07/MyThread.java b/s_day05/src/com/inmind/thread_07/MyThread.java new file mode 100644 index 0000000..289c3fd --- /dev/null +++ b/s_day05/src/com/inmind/thread_07/MyThread.java @@ -0,0 +1,11 @@ +package com.inmind.thread_07; + +public class MyThread extends Thread{ + + @Override + public void run() { + for (int i = 0; i < 1000; i++) { + System.out.println("helloJava"); + } + } +} diff --git a/s_day06/src/com/inmind/callable_02/Demo.java b/s_day06/src/com/inmind/callable_02/Demo.java new file mode 100644 index 0000000..779cb7e --- /dev/null +++ b/s_day06/src/com/inmind/callable_02/Demo.java @@ -0,0 +1,33 @@ +package com.inmind.callable_02; + +import java.util.concurrent.ExecutionException; +import java.util.concurrent.FutureTask; + +/* + 我们主线程是否可以获取子线程运行结束后的执行结果??? + 可以,使用Callable + + FutureTask 是Runnable的实现类,同时可以包装Callable对象,就可以将Callable接口实现类作为Thread的目标任务去执行 + + FutureTask构造方法接收Callable对象,通过FutureTask作为参数传给Thread + */ +public class Demo { + public static void main(String[] args) { + //1.创建Callable实现类对象 + MyCallable myCallable = new MyCallable(); + //2.使用FutureTask包装Callable + FutureTask task = new FutureTask<>(myCallable); + //3.将FutureTask作为Runnable传递给Thread,并启动 + Thread thread = new Thread(task); + thread.start(); + //4.通过FutureTask获取子线程的执行结果 + System.out.println("正在等待任务执行结果......"); + try { + String threadResult = task.get();//阻塞当前的主线程,等子线程返回结果后再启动主线程运行 + System.out.println("子线程结果:"+threadResult); + System.out.println("程序结束"); + } catch (Exception e) { + e.printStackTrace(); + } + } +} diff --git a/s_day06/src/com/inmind/callable_02/MyCallable.java b/s_day06/src/com/inmind/callable_02/MyCallable.java new file mode 100644 index 0000000..45d94ca --- /dev/null +++ b/s_day06/src/com/inmind/callable_02/MyCallable.java @@ -0,0 +1,13 @@ +package com.inmind.callable_02; + +import java.util.concurrent.Callable; + +public class MyCallable implements Callable { + @Override + public String call() throws Exception { + for (int i = 0; i < 100; i++) { + System.out.println(Thread.currentThread().getName() + " " + i); + } + return "这是子线程中返回的结果"; + } +} diff --git a/s_day06/src/com/inmind/lock_07/Test.java b/s_day06/src/com/inmind/lock_07/Test.java new file mode 100644 index 0000000..5527fc0 --- /dev/null +++ b/s_day06/src/com/inmind/lock_07/Test.java @@ -0,0 +1,15 @@ +package com.inmind.lock_07; + +/* + + */ +public class Test { + public static void main(String[] args) { + //创建卖票的任务 + TicketTask task = new TicketTask(); + //交给3个售票窗口 + new Thread(task,"窗口1").start(); + new Thread(task,"窗口2").start(); + new Thread(task,"窗口3").start(); + } +} diff --git a/s_day06/src/com/inmind/lock_07/TicketTask.java b/s_day06/src/com/inmind/lock_07/TicketTask.java new file mode 100644 index 0000000..3e135c2 --- /dev/null +++ b/s_day06/src/com/inmind/lock_07/TicketTask.java @@ -0,0 +1,40 @@ +package com.inmind.lock_07; + +import java.util.concurrent.locks.Lock; +import java.util.concurrent.locks.ReentrantLock; + +/* +Lock接口,有一个常用的实现类ReentrantLock +常用方法: +void lock() 获得锁。 +void unlock() 释放锁。 + */ +public class TicketTask implements Runnable { + int ticketCount = 100;//100张电影票 + Lock lock = new ReentrantLock(); + + @Override + public void run() { + //有票就卖 + while (true) { +// synchronized(lock) { + lock.lock();//获取锁对象 + try { + if (ticketCount > 0) { + //卖票 + //模拟卖票耗时 + Thread.sleep(50); + System.out.println(Thread.currentThread().getName() + "正在卖第" + ticketCount + "张票"); + ticketCount--; + } else { + break; + } + } catch (InterruptedException e) { + e.printStackTrace(); + } finally { + lock.unlock();//释放锁,当一个线程执行完同步代码块,一定要将锁释放 + } + + } + } +} diff --git a/s_day06/src/com/inmind/noname_inner_thread_03/Demo01.java b/s_day06/src/com/inmind/noname_inner_thread_03/Demo01.java new file mode 100644 index 0000000..9fb769e --- /dev/null +++ b/s_day06/src/com/inmind/noname_inner_thread_03/Demo01.java @@ -0,0 +1,65 @@ +package com.inmind.noname_inner_thread_03; +/* +6.匿名内部类实现多线程(重点掌握) +匿名内部类的语法: + new 父类名|接口名(){ + 要重写的方法 + } +匿名内部类的作用:只要使用一次的类,不要单独定义。将父类或者接口的子类(实现类)的定义和对象的创建用一段代码操作完毕 + +多线程的启动方法: + 1.继承Thread + 2.实现Runnable + +所有的匿名内部类的写法都是多态 + */ +public class Demo01 { + public static void main(String[] args) { + //普通的线程创建方式一 + MyThread myThread = new MyThread(); + + //匿名内部类启动线程方式一 + Thread thread = new Thread(){ + @Override + public void run() { + System.out.println(Thread.currentThread().getName() + " 线程启动了" ); + } + }; + thread.start(); + //---------------------------------------------------------------------- + //使用匿名对象启动线程的方法 + new Thread(){ + @Override + public void run() { + System.out.println(Thread.currentThread().getName() + " 线程启动了" ); + } + }.start(); + //---------------------------------------------------------------------- + //匿名内部类启动多线程方式二(Runnable) + Runnable runnable = new Runnable() { + @Override + public void run() { + System.out.println(Thread.currentThread().getName() + " 线程启动了" ); + } + }; + Thread thread1 = new Thread(runnable); + thread1.start(); + //---------------------------------------------------------------------- + Thread thread2 = new Thread(new Runnable() { + @Override + public void run() { + System.out.println(Thread.currentThread().getName() + " 线程启动了" ); + } + }); + thread2.start(); + //---------------------------------------------------------- + new Thread(new Runnable() { + @Override + public void run() { + System.out.println(Thread.currentThread().getName() + " 线程启动了" ); + } + }).start(); + + System.out.println("程序结束"); + } +} diff --git a/s_day06/src/com/inmind/noname_inner_thread_03/MyThread.java b/s_day06/src/com/inmind/noname_inner_thread_03/MyThread.java new file mode 100644 index 0000000..e5272c5 --- /dev/null +++ b/s_day06/src/com/inmind/noname_inner_thread_03/MyThread.java @@ -0,0 +1,19 @@ +package com.inmind.noname_inner_thread_03; + +public class MyThread extends Thread{ + //属性 + + public MyThread() { + } + + public MyThread(String name) { + super(name); + } + + @Override + public void run() { + for (int i = 0; i < 3; i++) { + System.out.println(Thread.currentThread().getName() + " " + i); + } + } +} diff --git a/s_day06/src/com/inmind/provide_custom_08/BaoZi.java b/s_day06/src/com/inmind/provide_custom_08/BaoZi.java new file mode 100644 index 0000000..b7ba28d --- /dev/null +++ b/s_day06/src/com/inmind/provide_custom_08/BaoZi.java @@ -0,0 +1,6 @@ +package com.inmind.provide_custom_08; + +//该类的作用记录当时是否有包子(也用来在线程间进行通信) +public class BaoZi { + boolean flag = false; +} diff --git a/s_day06/src/com/inmind/provide_custom_08/BaoZiPu.java b/s_day06/src/com/inmind/provide_custom_08/BaoZiPu.java new file mode 100644 index 0000000..c1b75d8 --- /dev/null +++ b/s_day06/src/com/inmind/provide_custom_08/BaoZiPu.java @@ -0,0 +1,32 @@ +package com.inmind.provide_custom_08; + +//如果有包子,就等待,如果没有包子就做一个包子 +public class BaoZiPu implements Runnable{ + BaoZi baoZi; + + public BaoZiPu(BaoZi baoZi) { + this.baoZi = baoZi; + } + + @Override + public void run() { + while (true){ + synchronized (baoZi) { + //如果有包子,就等待,如果没有包子就做一个包子 + if (baoZi.flag) { + //有包子,就等着 + try { + baoZi.wait();//让当前线程无限等待,除非其他线程唤醒(吃货线程) + } catch (InterruptedException e) { + e.printStackTrace(); + } + }else{ + System.out.println("包子铺做了一个包子"); + baoZi.flag = true; + baoZi.notify();//唤醒其他线程,告知包子已经做了 + } + } + } + + } +} diff --git a/s_day06/src/com/inmind/provide_custom_08/ChiHuo.java b/s_day06/src/com/inmind/provide_custom_08/ChiHuo.java new file mode 100644 index 0000000..970237a --- /dev/null +++ b/s_day06/src/com/inmind/provide_custom_08/ChiHuo.java @@ -0,0 +1,29 @@ +package com.inmind.provide_custom_08; +//如果有包子就吃,没有就等着 +public class ChiHuo implements Runnable{ + BaoZi baozi; + + public ChiHuo(BaoZi baozi) { + this.baozi = baozi; + } + + @Override + public void run() { + while(true){ + //如果有包子就吃,没有就等着 + synchronized (baozi) { + if (baozi.flag) { + System.out.println("吃货吃了一个包子"); + baozi.flag = false; + baozi.notify(); + }else{ + try { + baozi.wait(); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + } + } + } +} diff --git a/s_day06/src/com/inmind/provide_custom_08/Demo01.java b/s_day06/src/com/inmind/provide_custom_08/Demo01.java new file mode 100644 index 0000000..bf62620 --- /dev/null +++ b/s_day06/src/com/inmind/provide_custom_08/Demo01.java @@ -0,0 +1,16 @@ +package com.inmind.provide_custom_08; +/* +等待唤醒中的方法 + void wait() 导致当前线程等待,直到另一个线程调用该对象的 notify()方法或 notifyAll()方法。 + void notify() 唤醒正在等待对象监视器(锁对象)的单个线程。 + void notifyAll() 唤醒正在等待对象监视器(锁对象)的所有线程。 + */ +public class Demo01 { + public static void main(String[] args) throws InterruptedException { + Object o = new Object(); + synchronized (o) { + o.wait();//能让当前主线程无限等待,除非其他线程中调用o的notify或notifyAll,唤醒主线程,它才会继续往下运行 + } + System.out.println("程序结束"); + } +} diff --git a/s_day06/src/com/inmind/provide_custom_08/StateDemo03.java b/s_day06/src/com/inmind/provide_custom_08/StateDemo03.java new file mode 100644 index 0000000..1727703 --- /dev/null +++ b/s_day06/src/com/inmind/provide_custom_08/StateDemo03.java @@ -0,0 +1,17 @@ +package com.inmind.provide_custom_08; +/* +线程状态。 线程可以处于以下状态之一: +NEW :新建状态,new Thread(),创建线程对象时 + +RUNNABLE :运行状态,thread.start(); + +BLOCKED :阻塞状态,遇到synchronized关键字,没有得到锁对象,线程处于阻塞状态 + +WAITING :无限等待状态,wait方法 + +TIMED_WAITING :计时等待,sleep,指定线程等待多少毫秒继续运行 + +TERMINATED :结束状态,正常的结束;stop方法 + */ +public class StateDemo03 { +} diff --git a/s_day06/src/com/inmind/provide_custom_08/Test02.java b/s_day06/src/com/inmind/provide_custom_08/Test02.java new file mode 100644 index 0000000..61119f1 --- /dev/null +++ b/s_day06/src/com/inmind/provide_custom_08/Test02.java @@ -0,0 +1,15 @@ +package com.inmind.provide_custom_08; + +public class Test02 { + public static void main(String[] args) { + //创建出一个共享数据对象包子对象 + BaoZi baoZi = new BaoZi(); + //创建出吃货和包子铺线程任务 + BaoZiPu baoZiPu = new BaoZiPu(baoZi); + ChiHuo chiHuo = new ChiHuo(baoZi); + //创建线程并启动 + new Thread(chiHuo).start(); + new Thread(baoZiPu).start(); + + } +} diff --git a/s_day06/src/com/inmind/synchornized_05/Test.java b/s_day06/src/com/inmind/synchornized_05/Test.java new file mode 100644 index 0000000..0b9081b --- /dev/null +++ b/s_day06/src/com/inmind/synchornized_05/Test.java @@ -0,0 +1,28 @@ +package com.inmind.synchornized_05; + +/* +在java中可以使用一个关键字synchornized来解决线程安全问题 + +synchornized修饰代码块和方法,修饰代码块之后被称为同步代码块,修饰了方法之后该方法就被称为同步方法 + +同步代码块的语法: +synchornized(锁对象){ + 具有线程安全问题的代码 +} + +同步代码块的作用:只有拥有锁对象的线程才能进入同步代码块去执行代码,如果没有锁对象就会被阻塞在synchornized关键字 + +锁对象:可以是java中的任意一个对象,Object String ArrayList + +注意:同步代码块中,锁对象永远只能是唯一的一个,不能多个 + */ +public class Test { + public static void main(String[] args) { + //创建卖票的任务 + TicketTask task = new TicketTask(); + //交给3个售票窗口 + new Thread(task,"窗口1").start(); + new Thread(task,"窗口2").start(); + new Thread(task,"窗口3").start(); + } +} diff --git a/s_day06/src/com/inmind/synchornized_05/TicketTask.java b/s_day06/src/com/inmind/synchornized_05/TicketTask.java new file mode 100644 index 0000000..9c1c8e4 --- /dev/null +++ b/s_day06/src/com/inmind/synchornized_05/TicketTask.java @@ -0,0 +1,30 @@ +package com.inmind.synchornized_05; +//卖票任务就是一个Runnable的实现类 +public class TicketTask implements Runnable { + int ticketCount = 100;//100张电影票 + Object lock = new Object();//创建了一个锁对象 + + @Override + public void run(){ + //有票就卖 + while(true) { +// synchronized(lock) { + synchronized(this) { + if (ticketCount > 0) { + //卖票 + //模拟卖票耗时 + try { + Thread.sleep(50); + } catch (InterruptedException e) { + e.printStackTrace(); + } + System.out.println(Thread.currentThread().getName() + "正在卖第" + ticketCount + "张票"); + ticketCount--; + }else{ + break; + } + } + + } + } +} diff --git a/s_day06/src/com/inmind/synchornized_method_06/Test.java b/s_day06/src/com/inmind/synchornized_method_06/Test.java new file mode 100644 index 0000000..2d61574 --- /dev/null +++ b/s_day06/src/com/inmind/synchornized_method_06/Test.java @@ -0,0 +1,25 @@ +package com.inmind.synchornized_method_06; + +/* +在java中可以使用一个关键字synchornized来解决线程安全问题 + +synchornized修饰代码块和方法,修饰代码块之后被称为同步代码块,修饰了方法之后该方法就被称为同步方法 + +同步方法的语法: +方法修饰符 synchornized 返回值类型 方法名(参数列表){ + 方法体 +} + +同步方法:就是在整个方法体的所有代码上加上同步代码块的功能 + + */ +public class Test { + public static void main(String[] args) { + //创建卖票的任务 + TicketTask task = new TicketTask(); + //交给3个售票窗口 + new Thread(task,"窗口1").start(); + new Thread(task,"窗口2").start(); + new Thread(task,"窗口3").start(); + } +} diff --git a/s_day06/src/com/inmind/synchornized_method_06/TicketTask.java b/s_day06/src/com/inmind/synchornized_method_06/TicketTask.java new file mode 100644 index 0000000..77cb968 --- /dev/null +++ b/s_day06/src/com/inmind/synchornized_method_06/TicketTask.java @@ -0,0 +1,45 @@ +package com.inmind.synchornized_method_06; +//卖票任务就是一个Runnable的实现类 +public class TicketTask implements Runnable { + int ticketCount = 100;//100张电影票 + Object lock = new Object();//创建了一个锁对象 + + @Override + public void run(){ + //有票就卖 + while(true) { +// synchronized(lock) { +// synchronized(this) { + sellTicket(); +// } + + if (ticketCount <= 0) { + break; + } + + } + } + + //同步方法来解决线程安全问题 + /* + 同步方法:就是在整个方法体的所有代码上加上同步代码块的功能 + + 同步方法中有没有锁对象呢??? + 同步成员方法的锁对象:this + 同步静态方法的锁对象:Class对象(反射) + */ + private synchronized void sellTicket() { + if (ticketCount > 0) { + //卖票 + //模拟卖票耗时 + try { + Thread.sleep(50); + } catch (InterruptedException e) { + e.printStackTrace(); + } + System.out.println(Thread.currentThread().getName() + "正在卖第" + ticketCount + "张票"); + ticketCount--; + } + } + +} diff --git a/s_day06/src/com/inmind/thread_01/Demo01.java b/s_day06/src/com/inmind/thread_01/Demo01.java new file mode 100644 index 0000000..a86c75f --- /dev/null +++ b/s_day06/src/com/inmind/thread_01/Demo01.java @@ -0,0 +1,19 @@ +package com.inmind.thread_01; +/* + 回顾Thread创建方式一: + 1.创建继承自Thread的子类 + 2.重写run方法(线程任务) + 3.创建子类对象,调用start方法 + */ +public class Demo01 { + public static void main(String[] args) { + //创建线程并启动 + MyThread myThread = new MyThread(); + myThread.start(); + System.out.println("------------------------"); + for (int i = 0; i < 1000; i++) { + System.out.println("hello JS"); + } + System.out.println("程序结束"); + } +} diff --git a/s_day06/src/com/inmind/thread_01/Demo02.java b/s_day06/src/com/inmind/thread_01/Demo02.java new file mode 100644 index 0000000..444db62 --- /dev/null +++ b/s_day06/src/com/inmind/thread_01/Demo02.java @@ -0,0 +1,39 @@ +package com.inmind.thread_01; +/* + 构造方法: + public Thread() :分配一个新的线程对象。 + public Thread(String name) :分配一个指定名字的新的线程对象。 + + 常用方法: + public String getName() :获取当前线程名称。 + public void start() :导致此线程开始执行; Java虚拟机调用此线程的run方法。 + public void run() :此线程要执行的任务在此处定义代码。 + public static void sleep(long millis) :使当前正在执行的线程以指定的毫秒数暂停(暂时停止执行)。 + public static Thread currentThread() :获取到当前正在执行的线程对象。(重点) + */ +public class Demo02 { + public static void main(String[] args) { + //创建2个线程对象 + MyThread thread1 = new MyThread("刘备"); + MyThread thread2 = new MyThread("关羽"); + + //启动线程 + thread1.start();//在栈内存开辟新的栈区,去执行对应线程对象的run方法,不能主动调用run方法 + thread2.start(); + + //查看2个线程的名称 + System.out.println(thread1.getName());//Thread-0 + System.out.println(thread2.getName());//Thread-1 + + //让主线程等2秒再执行 + try { + Thread.sleep(2000); + } catch (InterruptedException e) { + throw new RuntimeException(e); + } + + //主线程的名称是什么?? + Thread mainThread = Thread.currentThread(); + System.out.println("主线程的名称:"+mainThread.getName()); + } +} diff --git a/s_day06/src/com/inmind/thread_01/Demo03.java b/s_day06/src/com/inmind/thread_01/Demo03.java new file mode 100644 index 0000000..68db09f --- /dev/null +++ b/s_day06/src/com/inmind/thread_01/Demo03.java @@ -0,0 +1,22 @@ +package com.inmind.thread_01; +/* + 启动线程的第二种方式(重点): + 1.定义一个实现类实现Runnable接口 + 2.实现接口的run方法(线程任务) + 3.创建出实现类对象 + 4.创建线程对象将实现类对象(线程任务)作为,调用start方法 + */ +public class Demo03 { + public static void main(String[] args) { + //创建实现类对象 + RunnableImpl runnable = new RunnableImpl(); + //创建线程启动 + Thread thread = new Thread(runnable); + thread.start(); + System.out.println("---------------"); + for (int i = 0; i < 1000; i++) { + System.out.println(Thread.currentThread().getName() + ":" + i); + } + System.out.println("程序结束"); + } +} diff --git a/s_day06/src/com/inmind/thread_01/MyThread.java b/s_day06/src/com/inmind/thread_01/MyThread.java new file mode 100644 index 0000000..bea6a9c --- /dev/null +++ b/s_day06/src/com/inmind/thread_01/MyThread.java @@ -0,0 +1,19 @@ +package com.inmind.thread_01; + +public class MyThread extends Thread{ + //属性 + + public MyThread() { + } + + public MyThread(String name) { + super(name); + } + + @Override + public void run() { + for (int i = 0; i < 3; i++) { + System.out.println("hello java"); + } + } +} diff --git a/s_day06/src/com/inmind/thread_01/RunnableImpl.java b/s_day06/src/com/inmind/thread_01/RunnableImpl.java new file mode 100644 index 0000000..63612ac --- /dev/null +++ b/s_day06/src/com/inmind/thread_01/RunnableImpl.java @@ -0,0 +1,14 @@ +package com.inmind.thread_01; + +//注意:只有Thread类的子类才是一个线程类,当前Runnable实现类,只是一个定义了线程任务run方法的类,线程任务类 +public class RunnableImpl implements Runnable { + + //定义属性 + + @Override + public void run() { + for (int i = 0; i < 1000; i++) { + System.out.println(Thread.currentThread().getName() + ":" + i); + } + } +} diff --git a/s_day06/src/com/inmind/thread_pool_09/Demo01.java b/s_day06/src/com/inmind/thread_pool_09/Demo01.java new file mode 100644 index 0000000..c5c6f25 --- /dev/null +++ b/s_day06/src/com/inmind/thread_pool_09/Demo01.java @@ -0,0 +1,71 @@ +package com.inmind.thread_pool_09; + +import java.util.concurrent.*; + +/* +在java中使用一个接口表示线程池ExecutorService +如何获取线程池对象?? +方式一:直接创建实现类ThreadPoolExecutor 的对象 +方式二:Executors(线程池)的静态方法 + +方式一的构造方法: +ThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, + TimeUnit unit, BlockingQueue workQueue, ThreadFactory threadFactory, RejectedExecutionHandler handler) + +参数一:corePoolSize,指定线程池核心线程的数量 +参数二:maximumPoolSize,指定线程池的最大线程数量 +参数三:keepAliveTime,指定临时线程的存活时间 +参数四:unit,指定临时线程存活时间单位(秒,分,时,天) +参数五:workQueue 指定线程池的任务队列 +参数六:threadFactory,指定线程池的线程工厂 +参数七:handler,指定线程池的任务拒绝策略 + + +注意: + 1.临时线程什么时候会创建?? + 新任务提交到线程池,发现所有的核心线程都被占用,任务队列也满了,并且还可以创建临时线程时,才会创建新的临时线程 + + 2.什么时候会开始拒绝任务??? + 当所有的核心线程和临时线程都在忙,而且任务对了也都满了,新的任务还来,线程池就开始拒绝任务 + ------------------------------------------------------------------------------------------- +常用的API +void execute(Runnable command) 在将来某个时候执行给定的任务。 + Future submit(Callable task) 提交值返回任务以执行,并返回代表任务待处理结果的Future。 +void shutdown() 启动有序关闭,其中先前提交的任务将被执行,但不会接受任何新任务。 +List shutdownNow() 尝试停止所有主动执行的任务,停止等待任务的处理,并返回正在等待执行的任务列表。 + +----------------------------------------------------------------- +AbortPolicy:当线程池添加超负荷任务时,直接抛异常(默认策略) +DiscardOldestPolicy:丢弃任务,但不抛异常,不推荐 +CallerRunsPolicy:由主线程负责调用任务的run方法 +DiscardPolicy:也是直接丢弃 + + */ +public class Demo01 { + public static void main(String[] args) { + //线程池的多态 + ExecutorService threadPool = new ThreadPoolExecutor(3,5,8, + TimeUnit.SECONDS,new ArrayBlockingQueue<>(4), Executors.defaultThreadFactory() + ,new ThreadPoolExecutor.AbortPolicy()); + + //将runnable线程任务交给线程池去处理 + Task task = new Task(); + threadPool.execute(task); + threadPool.execute(task); + threadPool.execute(task); + //线程任务长时间占用线程,3个核心线程被占用,4个任务队列排满,就开始创建新的临时线程了 + threadPool.execute(task); + threadPool.execute(task); + threadPool.execute(task); + threadPool.execute(task);//会将任务放到任务队列 + threadPool.execute(task);//创建临时线程了 + threadPool.execute(task); +// threadPool.execute(task);//所有线程都被占用,任务队列也满了,开始拒绝 + + + //void shutdown() 启动有序关闭,其中先前提交的任务将被执行,但不会接受任何新任务。 + threadPool.shutdown(); + //List shutdownNow() 尝试停止所有主动执行的任务,停止等待任务的处理,并返回正在等待执行的任务列表。 +// threadPool.shutdownNow(); + } +} diff --git a/s_day06/src/com/inmind/thread_pool_09/Demo02.java b/s_day06/src/com/inmind/thread_pool_09/Demo02.java new file mode 100644 index 0000000..3dfe003 --- /dev/null +++ b/s_day06/src/com/inmind/thread_pool_09/Demo02.java @@ -0,0 +1,34 @@ +package com.inmind.thread_pool_09; + +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; + +/* + 22.线程池的创建--方式二 + Executors的静态方法: + 1.static ExecutorService newFixedThreadPool(int nThreads) 创建一个固定线程的线程池 + 2.static ExecutorService newSingleThreadExecutor() 创建一个只有一个线程的线程池,如果该线程出现异常,那么线程池主动创建一个新的替代 + 3.static ExecutorService newCachedThreadPool() 创建出随任务增加而增加线程的线程池,如果一个线程执行任务之后空闲了60s,这个线程就会被回收 + +注意:在实际开发中,不推荐使用Executors来创建线程池,工具类创建线程的底层其实就是ThreadPoolExecutor构造方法,只不过参数不同。 +咱们的线程池的参数,要根据不同的业务来动态调整(而不是写死) + */ +public class Demo02 { + public static void main(String[] args) { + ExecutorService threadPool = Executors.newFixedThreadPool(3); + + //将runnable线程任务交给线程池去处理 + Task task = new Task(); + threadPool.execute(task); + threadPool.execute(task); + threadPool.execute(task); + //线程任务长时间占用线程,3个核心线程被占用,4个任务队列排满,就开始创建新的临时线程了 + threadPool.execute(task); + threadPool.execute(task); + threadPool.execute(task); + threadPool.execute(task);//会将任务放到任务队列 + threadPool.execute(task);//创建临时线程了 + threadPool.execute(task); + threadPool.execute(task);//所有线程都被占用,任务队列也满了,开始拒绝 + } +} diff --git a/s_day06/src/com/inmind/thread_pool_09/Task.java b/s_day06/src/com/inmind/thread_pool_09/Task.java new file mode 100644 index 0000000..ed6b73e --- /dev/null +++ b/s_day06/src/com/inmind/thread_pool_09/Task.java @@ -0,0 +1,15 @@ +package com.inmind.thread_pool_09; + +public class Task implements Runnable{ + + @Override + public void run() { + System.out.println(Thread.currentThread().getName()+"执行了任务"); + + try { + Thread.sleep(1000); + } catch (InterruptedException e) { + throw new RuntimeException(e); + } + } +} diff --git a/s_day06/src/com/inmind/thread_pool_callable_10/Demo01.java b/s_day06/src/com/inmind/thread_pool_callable_10/Demo01.java new file mode 100644 index 0000000..9194866 --- /dev/null +++ b/s_day06/src/com/inmind/thread_pool_callable_10/Demo01.java @@ -0,0 +1,29 @@ +package com.inmind.thread_pool_callable_10; + +import java.util.concurrent.ExecutionException; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.concurrent.Future; + +/* +线程池:处理Callable任务 +Callable 接口 +Future 接口 + +注意:有返回值的子线程操作,它的返回值会封装在Future中,通过get方法来获取 + */ +public class Demo01 { + public static void main(String[] args) throws ExecutionException, InterruptedException { + //创建线程池对象 + ExecutorService threadPool = Executors.newFixedThreadPool(5); + //创建有返回值的线程任务类 + // Future submit(Callable task) 提交值返回任务以执行,并返回代表任务待处理结果的Future。 + Future future1 = threadPool.submit(new MyCallable(3)); + Future future2 = threadPool.submit(new MyCallable(5)); + Future future3 = threadPool.submit(new MyCallable(10)); + + System.out.println("任务1获取的结果是:"+future1.get()); + System.out.println("任务2获取的结果是:"+future2.get()); + System.out.println("任务3获取的结果是:"+future3.get()); + } +} diff --git a/s_day06/src/com/inmind/thread_pool_callable_10/MyCallable.java b/s_day06/src/com/inmind/thread_pool_callable_10/MyCallable.java new file mode 100644 index 0000000..ec5956b --- /dev/null +++ b/s_day06/src/com/inmind/thread_pool_callable_10/MyCallable.java @@ -0,0 +1,23 @@ +package com.inmind.thread_pool_callable_10; + +import java.util.concurrent.Callable; + +public class MyCallable implements Callable { + int sum = 0; + public MyCallable(int sum) { + if (sum>0) + this.sum = sum; + } + + @Override + public Integer call() throws Exception { + //计算出0~sum的累和 + int value = 0; + for (int i = 1; i <= sum; i++) { + value += i; + } + Thread.sleep(1000); + System.out.println(Thread.currentThread().getName()+"执行完累加操作,结果为:"+value); + return value; + } +} diff --git a/s_day06/src/com/inmind/thread_safe_04/Test.java b/s_day06/src/com/inmind/thread_safe_04/Test.java new file mode 100644 index 0000000..d509960 --- /dev/null +++ b/s_day06/src/com/inmind/thread_safe_04/Test.java @@ -0,0 +1,23 @@ +package com.inmind.thread_safe_04; +/* +7.卖票案例的实现 +注意:当多个线程去操作同一个数据时,就可能会发生线程安全问题 + +电影院要卖票,我们模拟电影院的卖票过程。假设要播放的电影是 “葫芦娃大战奥特曼”,本次电影的座位共100个(本场电影只能卖100张票)。 +我们来模拟电影院的售票窗口,实现多个窗口同时卖 “葫芦娃大战奥特曼”这场电影票(多个窗口一起卖这100张票) +需要窗口,采用线程对象来模拟;需要票,Runnable接口子类来模拟 + +实现分析: + 1.定义卖票任务,只有100张票,有票就卖 + 2.多窗口,定义多个线程同时卖票 + */ +public class Test { + public static void main(String[] args) { + //创建卖票的任务 + TicketTask task = new TicketTask(); + //交给3个售票窗口 + new Thread(task,"窗口1").start(); + new Thread(task,"窗口2").start(); + new Thread(task,"窗口3").start(); + } +} diff --git a/s_day06/src/com/inmind/thread_safe_04/TicketTask.java b/s_day06/src/com/inmind/thread_safe_04/TicketTask.java new file mode 100644 index 0000000..a05f9f8 --- /dev/null +++ b/s_day06/src/com/inmind/thread_safe_04/TicketTask.java @@ -0,0 +1,26 @@ +package com.inmind.thread_safe_04; +//卖票任务就是一个Runnable的实现类 +public class TicketTask implements Runnable { + int ticketCount = 100;//100张电影票 + + @Override + public void run(){ + //有票就卖 + while(true) { + if (ticketCount > 0) { + //卖票 + //模拟卖票耗时 + try { + Thread.sleep(5); + } catch (InterruptedException e) { + e.printStackTrace(); + } + System.out.println(Thread.currentThread().getName() + "正在卖第" + ticketCount + "张票"); + ticketCount--; + }else{ + break; + } + + } + } +} diff --git a/s_day07/src/com/inmind/functional_interface_02/ConsumerDemo02.java b/s_day07/src/com/inmind/functional_interface_02/ConsumerDemo02.java new file mode 100644 index 0000000..833cd07 --- /dev/null +++ b/s_day07/src/com/inmind/functional_interface_02/ConsumerDemo02.java @@ -0,0 +1,41 @@ +package com.inmind.functional_interface_02; + +import java.util.function.Consumer; + +/* +在jdk中,提供了一些常用的函数式接口供开发人员使用 +常用的函数式接口_Consumer +void accept(T t) 对给定的参数执行此操作。 + +注意: + 1.Consumer表示的是一个消费,只接收参数,没有返回值 + 2.什么时候要使用Consumer的接口?? + 当我们程序员,要定义一个函数式接口,接口中的方法只接收一个参数,没有返回值的方法,直接使用Consumer + + 需求:定义出一个使用常用函数式接口Consumer作为参数,并对字符串进行消费操作的方法(大写打印,小写打印) + */ +public class ConsumerDemo02 { + public static void main(String[] args) { + /*print(new Consumer() { + @Override + public void accept(String s) { + System.out.println(s.toUpperCase()); + } + },"aBcD");*/ + print(s->System.out.println(s.toUpperCase()),"aBcD"); + + /*print(new Consumer() { + @Override + public void accept(String str) { + System.out.println(str.toLowerCase()); + } + },"aBcD");*/ + print(ss -> System.out.println(ss.toLowerCase()), "aBcD"); + } + + //定义出一个使用常用函数式接口Consumer作为参数,并对字符串进行消费操作的方法(大写打印,小写打印) + public static void print(Consumer consumer, String str) { + //消费字符串 + consumer.accept(str); + } +} diff --git a/s_day07/src/com/inmind/functional_interface_02/ConsumerDemo03.java b/s_day07/src/com/inmind/functional_interface_02/ConsumerDemo03.java new file mode 100644 index 0000000..da4de08 --- /dev/null +++ b/s_day07/src/com/inmind/functional_interface_02/ConsumerDemo03.java @@ -0,0 +1,19 @@ +package com.inmind.functional_interface_02; + +import java.util.function.Consumer; + +/* + default Consumer andThen(Consumer after) 返回一个组成的 Consumer ,依次执行此操作,然后执行 after操作。 + 需求:我要使用消费者Consumer接口,对同一个字符串进行大写,和小写的消费操作 + */ +public class ConsumerDemo03 { + public static void main(String[] args) { + printStr(s-> System.out.println(s.toUpperCase()),s-> System.out.println(s.toLowerCase()),"AbCd"); + } + + public static void printStr(Consumer c1, Consumer c2,String s) { + /*c1.accept(s); + c2.accept(s);*/ + c1.andThen(c2).accept(s); + } +} diff --git a/s_day07/src/com/inmind/functional_interface_02/Demo01.java b/s_day07/src/com/inmind/functional_interface_02/Demo01.java new file mode 100644 index 0000000..145e2c4 --- /dev/null +++ b/s_day07/src/com/inmind/functional_interface_02/Demo01.java @@ -0,0 +1,52 @@ +package com.inmind.functional_interface_02; +/* +.自定义函数式接口:有且仅有一个必须重写的抽象方法的接口 + +在java中可以使用一个注解@FunctionalInferface,来验证一个接口是否是函数式接口 + +函数式接口的使用: + 1.作为参数类型 + 2.返回值类型 + */ +public class Demo01 { + public static void main(String[] args) { + int a = 10; + int b = 20; + //调用使用函数式接口的方法 + /*int result = getValue(new MyInterface() { + @Override + public int getSum(int a, int b) { + //求和的功能 + return a + b; + } + }, a, b);*/ +// int result = getValue((int i, int j)->{ return i + j;},a,b); + int result = getValue(( i, j)-> i + j,a,b); + System.out.println(result); + //------------------------------------------------- + //调用使用函数式接口作为返回值的方法 + MyInterface myInterface = getMyInterface(); + int value = getValue(myInterface, a, b); + System.out.println(value); + } + + //定义一个有整数返回值,参数列表式函数式接口,2个整数的静态方法 + public static int getValue(MyInterface myInterface, int a, int b) { + int result = myInterface.getSum(a, b); + return result; + } + + //定义出一个函数式接口作为返回值类型,参数列表定义为无参 + public static MyInterface getMyInterface() { + /*MyInterface myInterface = new MyInterface() { + @Override + public int getSum(int a, int b) { + return a*b; + } + };*/ +// MyInterface myInterface = (int a, int b)->{return a*b;}; + /*MyInterface myInterface = ( a, b)-> a*b; + return myInterface;*/ + return ( a, b)-> a*b; + } +} diff --git a/s_day07/src/com/inmind/functional_interface_02/FunctionDemo10.java b/s_day07/src/com/inmind/functional_interface_02/FunctionDemo10.java new file mode 100644 index 0000000..d4eea15 --- /dev/null +++ b/s_day07/src/com/inmind/functional_interface_02/FunctionDemo10.java @@ -0,0 +1,29 @@ +package com.inmind.functional_interface_02; + +import java.util.function.Function; + +/* +17.常用的函数式接口-Function +Interface Function:就是一个数据工厂,用来数据转换 +参数类型: +T:原料的类型--参数 +R:产品的类型--返回值 +抽象方法: +R apply(T t) 将此函数应用于给定的参数。 + +//需求:"100"--->100 +T:String +R:Integer + */ +public class FunctionDemo10 { + public static void main(String[] args) { + String s = "100"; +// method(t->{return Integer.parseInt(t);},s); + method(t-> Integer.parseInt(t),s); + } + //接收一个字符串,使用数据工厂Function,转换数据为Integer + public static void method(Function function,String str) { + Integer result = function.apply(str); + System.out.println(result); + } +} diff --git a/s_day07/src/com/inmind/functional_interface_02/FunctionDemo11.java b/s_day07/src/com/inmind/functional_interface_02/FunctionDemo11.java new file mode 100644 index 0000000..d5597b8 --- /dev/null +++ b/s_day07/src/com/inmind/functional_interface_02/FunctionDemo11.java @@ -0,0 +1,33 @@ +package com.inmind.functional_interface_02; + +import java.util.function.Function; + +/* +18. Function中的andThen方法 +default Function andThen(Function after) + 返回一个组合函数,首先将该函数应用于其输入,然后将 after函数应用于结果。 + + 需求: + 1."10"->10 + 2.10->100 + 分析: + 1.一个Function将“10”->10 + 2.一个Function将10->100 + */ +public class FunctionDemo11 { + public static void main(String[] args) { + String str = "10"; + method(s -> Integer.parseInt(s),i->i*10,str); + } + + public static void method(Function f1,Function f2,String s) { + /*//1.一个Function将“10”->10 + Integer result1 = f1.apply(s); + //2.一个Function将10->100 + Integer result2 = f2.apply(result1); + System.out.println(result2);*/ +// System.out.println(f2.apply(f1.apply(s))); + //使用f1的apply方法对s进行转换,再将它的结果作为f2的apply方法的参数进行转换 + System.out.println(f1.andThen(f2).andThen(f2).andThen(f2).apply(s)); + } +} diff --git a/s_day07/src/com/inmind/functional_interface_02/FunctionTest12.java b/s_day07/src/com/inmind/functional_interface_02/FunctionTest12.java new file mode 100644 index 0000000..b8d2011 --- /dev/null +++ b/s_day07/src/com/inmind/functional_interface_02/FunctionTest12.java @@ -0,0 +1,26 @@ +package com.inmind.functional_interface_02; + +import java.util.function.Function; + +/* +请使用Function进行函数模型的拼接,按照顺序需要执行的多个函数操作为: +"赵丽颖,20" +1. 将字符串截取数字年龄部分,得到字符串; +2. 将上一步的字符串转换成为int类型的数字;(String->integer) +3. 将上一步的int数字累加100,得到结果int数字。(integer->integer) + */ +public class FunctionTest12 { + public static void main(String[] args) { + String str = "赵丽颖,20"; + method(s -> Integer.parseInt(s.split(",")[1]),i->i+100,str); + } + + public static void method(Function f1, Function f2, String s) { + /*Integer result1 = f1.apply(s); + Integer result2 = f2.apply(result1); + System.out.println(result2);*/ + + Integer result = f1.andThen(f2).apply(s); + System.out.println(result); + } +} diff --git a/s_day07/src/com/inmind/functional_interface_02/MyInterface.java b/s_day07/src/com/inmind/functional_interface_02/MyInterface.java new file mode 100644 index 0000000..d1efc30 --- /dev/null +++ b/s_day07/src/com/inmind/functional_interface_02/MyInterface.java @@ -0,0 +1,11 @@ +package com.inmind.functional_interface_02; + +//函数式接口:有且仅有一个必须重写的抽象方法的接口 +@FunctionalInterface +public interface MyInterface { + //有参有返回值的方法 + int getSum(int a, int b); + /*boolean equals(Object obj); + String toString(); + int hashCode();*/ +} diff --git a/s_day07/src/com/inmind/functional_interface_02/MyInterface1.java b/s_day07/src/com/inmind/functional_interface_02/MyInterface1.java new file mode 100644 index 0000000..c9fb332 --- /dev/null +++ b/s_day07/src/com/inmind/functional_interface_02/MyInterface1.java @@ -0,0 +1,6 @@ +package com.inmind.functional_interface_02; + +@FunctionalInterface +public interface MyInterface1 { + void method1(int i); +} diff --git a/s_day07/src/com/inmind/functional_interface_02/MyInterface2.java b/s_day07/src/com/inmind/functional_interface_02/MyInterface2.java new file mode 100644 index 0000000..0d154fd --- /dev/null +++ b/s_day07/src/com/inmind/functional_interface_02/MyInterface2.java @@ -0,0 +1,6 @@ +package com.inmind.functional_interface_02; + +@FunctionalInterface +public interface MyInterface2 { + void method1(String i); +} diff --git a/s_day07/src/com/inmind/functional_interface_02/MyInterface3.java b/s_day07/src/com/inmind/functional_interface_02/MyInterface3.java new file mode 100644 index 0000000..b6df65e --- /dev/null +++ b/s_day07/src/com/inmind/functional_interface_02/MyInterface3.java @@ -0,0 +1,8 @@ +package com.inmind.functional_interface_02; + +import java.util.ArrayList; + +@FunctionalInterface +public interface MyInterface3 { + void method1(ArrayList i); +} diff --git a/s_day07/src/com/inmind/functional_interface_02/PredicateDemo05.java b/s_day07/src/com/inmind/functional_interface_02/PredicateDemo05.java new file mode 100644 index 0000000..f6935ad --- /dev/null +++ b/s_day07/src/com/inmind/functional_interface_02/PredicateDemo05.java @@ -0,0 +1,36 @@ +package com.inmind.functional_interface_02; + +import java.util.function.Predicate; + +/* +12.常用的函数式接口_Predicate +Interface Predicate +boolean test(T t) 用来判断或者筛选数据 +Predicate函数式接口的作用:用来进行数据筛选,判断指定的数据是否符合业务 + +什么时候要使用Predicat呢?? +当我们要定义一个有一个参数,并且返回值类型为boolean的函数式接口时,直接使用Predicate + +需求:使用Predicate接口判断指定的字符串长度是否>3(包含java) + */ +public class PredicateDemo05 { + public static void main(String[] args) { + //字符串长度是否>3 + /*method(new Predicate() { + + @Override + public boolean test(String s) { + return s.length()>3; + } + },"abcd");*/ + System.out.println(method(s -> s.length() > 3, "abcd")); + + //字符串包含java + System.out.println(method(ss -> ss.contains("java"), "woaijava")); + } + //定义一个返回值为boolean,参数是Predicate接口,String的静态方法 + public static boolean method(Predicate predicate,String str) { + boolean result = predicate.test(str); + return result; + } +} diff --git a/s_day07/src/com/inmind/functional_interface_02/PredicateDemo06.java b/s_day07/src/com/inmind/functional_interface_02/PredicateDemo06.java new file mode 100644 index 0000000..bb2c6ec --- /dev/null +++ b/s_day07/src/com/inmind/functional_interface_02/PredicateDemo06.java @@ -0,0 +1,25 @@ +package com.inmind.functional_interface_02; + +import java.util.function.Predicate; + +/* +Predicate的and方法 + +需求:对一个字符串,使用2个predicate,判断它是否以h开头,它的长度是否大于3 + +boolean test(T) + */ +public class PredicateDemo06 { + public static void main(String[] args) { +// method(s->{return s.startsWith("h");},s->s.length()>3,"hello java"); + method(s->s.startsWith("h"),s->s.length()>3,"hello java"); + } + + public static void method(Predicate p1, Predicate p2,String str) { + /*boolean results1 = p1.test(str); + boolean results2 = p2.test(str); + boolean result = results1 && results2; + System.out.println(result);*/ + System.out.println(p1.and(p2).test(str)); + } +} diff --git a/s_day07/src/com/inmind/functional_interface_02/PredicateDemo07.java b/s_day07/src/com/inmind/functional_interface_02/PredicateDemo07.java new file mode 100644 index 0000000..74f10ae --- /dev/null +++ b/s_day07/src/com/inmind/functional_interface_02/PredicateDemo07.java @@ -0,0 +1,24 @@ +package com.inmind.functional_interface_02; + +import java.util.function.Predicate; + +/* +Predicate的or方法 + +需求:对一个字符串,使用2个predicate,判断它是否以h开头或者它的长度是否大于3 + +boolean test(T) + */ +public class PredicateDemo07 { + public static void main(String[] args) { + method(s->s.startsWith("h"),s->s.length()>3,"hello"); + } + + public static void method(Predicate p1, Predicate p2,String str) { + /*boolean results1 = p1.test(str); + boolean results2 = p2.test(str); + boolean result = results1 || results2; + System.out.println(result);*/ + System.out.println(p1.or(p2).test(str)); + } +} diff --git a/s_day07/src/com/inmind/functional_interface_02/PredicateDemo08.java b/s_day07/src/com/inmind/functional_interface_02/PredicateDemo08.java new file mode 100644 index 0000000..dbe57e2 --- /dev/null +++ b/s_day07/src/com/inmind/functional_interface_02/PredicateDemo08.java @@ -0,0 +1,22 @@ +package com.inmind.functional_interface_02; + +import java.util.function.Predicate; + +/* +Predicate的negate方法 + +需求:对一个字符串,使用1个predicate,判断它是否以h开头,结果取反 + +boolean test(T) + */ +public class PredicateDemo08 { + public static void main(String[] args) { + method(s->s.startsWith("h"),"hello"); + } + + public static void method(Predicate p1,String str) { + /*boolean result = p1.test(str); + System.out.println(!result);*/ + System.out.println(p1.negate().test(str)); + } +} diff --git a/s_day07/src/com/inmind/functional_interface_02/PredicateTest09.java b/s_day07/src/com/inmind/functional_interface_02/PredicateTest09.java new file mode 100644 index 0000000..8bd5f06 --- /dev/null +++ b/s_day07/src/com/inmind/functional_interface_02/PredicateTest09.java @@ -0,0 +1,38 @@ +package com.inmind.functional_interface_02; + +import java.util.ArrayList; +import java.util.function.Predicate; + +/* +数组当中有多条“姓名+性别”的信息如下,请通过Predicate接口的拼装将符合要求的字符串筛选到集合ArrayList中,需要同时满足两个条件: + +1. 必须为女生; +2. 姓名为4个字 + +分析: + 1.一个predicate判断是否是女生 + 2.一个predicate判断名字是否长度为4 + */ +public class PredicateTest09 { + public static void main(String[] args) { + String[] array = { "迪丽热巴,女", "古力娜扎,女", "马尔扎哈,男", "赵丽颖,女" }; + //boolean test(T t) :t->{return xxx;} + mehtod(s->{ + String[] strs = s.split(","); + return strs[1].equals("女"); + },s->s.split(",")[0].length()==4,array); + } + + + public static void mehtod(Predicate p1, Predicate p2,String[] arr) { + //创建出保存数据的集合 + ArrayList list = new ArrayList<>(); + //遍历数组,判断是否满足2个条件,满足则保存到集合 + for (String s : arr) { + if (p1.and(p2).test(s)) {//判断2个条件是否满足 + list.add(s); + } + } + System.out.println(list); + } +} diff --git a/s_day07/src/com/inmind/functional_interface_02/SupplierDemo04.java b/s_day07/src/com/inmind/functional_interface_02/SupplierDemo04.java new file mode 100644 index 0000000..cde2c4a --- /dev/null +++ b/s_day07/src/com/inmind/functional_interface_02/SupplierDemo04.java @@ -0,0 +1,28 @@ +package com.inmind.functional_interface_02; + +import java.util.function.Supplier; + +/* +11.常用的函数式接口_Supplier + +Interface Supplier:表示生产者 +T:泛型,用来决定生产者生产的数据类型 +T get() 获得结果。 + +当我们开发人员,要定义一个无参,有返回值的函数式接口时,直接使用Supplier + + */ +public class SupplierDemo04 { + public static void main(String[] args) { + //给我生产一个字符串 +// getValue(()->{return "Hello World";}); + getValue(()->"Hello World"); + //给我生产一个整数 +// getValue(()->{return 100;}); + getValue(()-> 100); + } + //定义出一个用Supplier作为参数,将结果打印 + public static void getValue(Supplier supplier){ + System.out.println(supplier.get()); + } +} diff --git a/s_day07/src/com/inmind/lambda_01/Demo01.java b/s_day07/src/com/inmind/lambda_01/Demo01.java new file mode 100644 index 0000000..29ebe9a --- /dev/null +++ b/s_day07/src/com/inmind/lambda_01/Demo01.java @@ -0,0 +1,50 @@ +package com.inmind.lambda_01; +/* +使用匿名内部类实现多线程 + +匿名内部类的语法: + new 父类|父接口(){ + 要重写的方法 + } +线程的启动方式有2种: +1.继承Thread +2.实现Runnable接口(重点) +----------------------------------------------------------------- +函数式编程思想:重点关注做什么,而不是怎么做 + +为了编写线程任务代码,我们必须面向对象,new Runnable(),再重写run()(public void run()),其实 +我们只是要编写run方法中的方法体而已。 + +我们可以这么理解,函数式编程思想:做什么就是要重写的方法的方法体,而之前的对象创建,重写方法的语法都省略掉 + +-------------------------------------------------------------------------------- +Lambda的格式和前提条件 +函数式编程思想:重点关注做什么,而不是怎么做,在这个概念中做什么,实际上就是一个方法的方法体。 +针对一个方法而言,它有3个核心:1.参数列表 2.方法体 3.返回值 +Lambda表达式的所需语法的符号:();->;{} + +():参数列表 +->:参数列表用来调用哪段代码 +{}:方法体,根据是否有返回值,动态添加return + +Lambda表达式的前提条件: + 1.需要一个有且仅有一个必须实现抽象方法的接口(函数式接口) + 2.接口作为参数或者变量类型 + + */ +public class Demo01 { + public static void main(String[] args) { + new Thread(new Runnable() { + @Override + public void run() { + System.out.println(Thread.currentThread().getName()+"线程启动"); + } + }).start(); + //-------------------------以下就使用函数式编程思想优化以上代码(lambda表达式)------------------------------ + new Thread(() -> { + System.out.println(Thread.currentThread().getName() + "线程启动"); + }).start(); + ///------------------------------以下为lambda的简写形式---------------------- + new Thread(() -> System.out.println(Thread.currentThread().getName() + "线程启动")).start(); + } +} diff --git a/s_day07/src/com/inmind/lambda_01/Demo02.java b/s_day07/src/com/inmind/lambda_01/Demo02.java new file mode 100644 index 0000000..adaaf00 --- /dev/null +++ b/s_day07/src/com/inmind/lambda_01/Demo02.java @@ -0,0 +1,42 @@ +package com.inmind.lambda_01; + +import java.util.ArrayList; +import java.util.Collections; + +/* +5.使用Lambda表达式简化有参数有返回值的方法(比较器) + 使用比较器,对学生对象按成绩降序排序 + + +Lambda表达式的前提条件: + 1.需要一个有且仅有一个必须实现抽象方法的接口(函数式接口中可以有多个抽象方法) + 2.接口作为参数或者变量类型 + +扩展:为什么在一个接口中某些抽象方法不需要被重写??? +在一个类中单继承和多实现,单继承的方法优先于接口的方法定义,导致父类的方法如果有跟 +接口中定义的重名方法,那就相当于是默认重写 extends Object + + + */ +public class Demo02 { + public static void main(String[] args) { + ArrayList students = new ArrayList<>(); + students.add(new Student("Jack", 21)); + students.add(new Student("Tom", 22)); + students.add(new Student("Marty", 18)); + System.out.println(students); + + /*Collections.sort(students, new Comparator() { + @Override + public int compare(Student o1, Student o2) { + return o2.getAge() - o1.getAge(); + } + });*/ + //函数式编程思想lambda来实现 +// Collections.sort(students,(Student o1, Student o2)->{ return o1.getAge() - o2.getAge();}); + //-------------------------------以下为lambda的简写形式---------------------------------- + Collections.sort(students,(o1, o2)-> o2.getAge() - o1.getAge()); + + System.out.println(students); + } +} diff --git a/s_day07/src/com/inmind/lambda_01/Student.java b/s_day07/src/com/inmind/lambda_01/Student.java new file mode 100644 index 0000000..6cd298f --- /dev/null +++ b/s_day07/src/com/inmind/lambda_01/Student.java @@ -0,0 +1,35 @@ +package com.inmind.lambda_01; + +public class Student { + private String name; + private int age; + + public Student(String name, int age) { + this.name = name; + this.age = age; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public int getAge() { + return age; + } + + public void setAge(int age) { + this.age = age; + } + + @Override + public String toString() { + return "Student{" + + "name='" + name + '\'' + + ", age=" + age + + '}'; + } +} diff --git a/s_day07/src/com/inmind/stream_03/CollectDemo13.java b/s_day07/src/com/inmind/stream_03/CollectDemo13.java new file mode 100644 index 0000000..f2bffe1 --- /dev/null +++ b/s_day07/src/com/inmind/stream_03/CollectDemo13.java @@ -0,0 +1,21 @@ +package com.inmind.stream_03; + +import java.util.List; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +/* +33.Stream收集的练习 + 请通过Stream流的方式,将下面数组当中的元素添加(收集)到List集合当中: + */ +public class CollectDemo13 { + public static void main(String[] args) { + Integer[] arr = {1,2,3,4,5}; + //获取Stream的2种方法:1.单列集合的stream 2.Stream.of(T...) + /*Stream stream = Stream.of(arr); + List list = stream.collect(Collectors.toList());*/ + //Stream对数据进行高效的拷贝操作 + List list = Stream.of(arr).collect(Collectors.toList()); + System.out.println(list); + } +} diff --git a/s_day07/src/com/inmind/stream_03/ConcatDemo08.java b/s_day07/src/com/inmind/stream_03/ConcatDemo08.java new file mode 100644 index 0000000..c2ede9e --- /dev/null +++ b/s_day07/src/com/inmind/stream_03/ConcatDemo08.java @@ -0,0 +1,19 @@ +package com.inmind.stream_03; + +import java.util.stream.Stream; + +/* +28.Stream流中的常用方法_concat +static Stream concat(Stream a, Stream b) +合并2个流,生成一个新的流 + */ +public class ConcatDemo08 { + public static void main(String[] args) { + Stream stream1 = Stream.of(1, 2, 3, 4, 5); + Stream stream2 = Stream.of( 6, 7, 8, 9, 10); + + Stream stream = Stream.concat(stream1, stream2); +// stream.forEach(System.out::println); + stream.forEach(s-> System.out.println(s)); + } +} diff --git a/s_day07/src/com/inmind/stream_03/CountDemo05.java b/s_day07/src/com/inmind/stream_03/CountDemo05.java new file mode 100644 index 0000000..2fc5889 --- /dev/null +++ b/s_day07/src/com/inmind/stream_03/CountDemo05.java @@ -0,0 +1,15 @@ +package com.inmind.stream_03; + +import java.util.stream.Stream; + +/* +Stream流中的常用方法_count +long count() 返回此流中的元素数 + */ +public class CountDemo05 { + public static void main(String[] args) { + Stream stream = Stream.of(1, 2, 3, 4, 5); + long count = stream.count(); + System.out.println(count); + } +} diff --git a/s_day07/src/com/inmind/stream_03/Demo01.java b/s_day07/src/com/inmind/stream_03/Demo01.java new file mode 100644 index 0000000..778bee3 --- /dev/null +++ b/s_day07/src/com/inmind/stream_03/Demo01.java @@ -0,0 +1,46 @@ +package com.inmind.stream_03; + +import java.util.ArrayList; +import java.util.List; + +/* +20.传统操作集合和Stream流操作集合的对比 + +需求: +1. 首先筛选所有姓张的人; +2. 然后筛选名字有三个字的人; +3. 最后进行对结果进行打印输出。 + + + */ +public class Demo01 { + public static void main(String[] args) { + List list = new ArrayList<>(); + list.add("张无忌"); + list.add("周芷若"); + list.add("赵敏"); + list.add("张强"); + list.add("张三丰"); + + ArrayList zhangList = new ArrayList<>(); + //1. 首先筛选所有姓张的人; + for (String s : list) { + if (s.startsWith("张")) { + zhangList.add(s); + } + } + System.out.println(zhangList); + ArrayList newList = new ArrayList<>(); + //2. 然后筛选名字有三个字的人; + for (String s : zhangList) { + if (s.length() == 3) { + newList.add(s); + } + } + //3. 最后进行对结果进行打印输出 + System.out.println(newList); + System.out.println("------------------------------------------"); + //---------------------------------Stream流---------------------------------- + list.stream().filter(s->s.startsWith("张")).filter(s->s.length() == 3).forEach(s-> System.out.println(s)); + } +} diff --git a/s_day07/src/com/inmind/stream_03/FilterDemo04.java b/s_day07/src/com/inmind/stream_03/FilterDemo04.java new file mode 100644 index 0000000..08f7ec0 --- /dev/null +++ b/s_day07/src/com/inmind/stream_03/FilterDemo04.java @@ -0,0 +1,22 @@ +package com.inmind.stream_03; + +import java.util.stream.Stream; + +/* +24.Stream流中的常用方法_filter +Stream filter(Predicate predicate) 对指定的流进行过滤操作 +知识点回顾: + Predicate:接收一个参数,返回一个boolean的结果,用来进行数据筛选 + 抽象方法:boolean test(T t) ---> t->{return ...} + +filter的执行原理:它会将stream流中的每个元素,作为以上Lambda表达式的参数,执行方法体,如果返回的是true,那就会把当前元素保存在新流中,如果是false,舍弃数据 + + */ +public class FilterDemo04 { + public static void main(String[] args) { + Stream stream = Stream.of(1, 2, 3, 4, 5); + //只要大于3的数据 + Stream stream1 = stream.filter(t -> t > 3); + stream1.forEach(s-> System.out.println(s)); + } +} diff --git a/s_day07/src/com/inmind/stream_03/ForeachDemo03.java b/s_day07/src/com/inmind/stream_03/ForeachDemo03.java new file mode 100644 index 0000000..0b9f523 --- /dev/null +++ b/s_day07/src/com/inmind/stream_03/ForeachDemo03.java @@ -0,0 +1,26 @@ +package com.inmind.stream_03; + +import java.util.stream.Stream; + +/* +23.Stream流中的常用方法_forEach +void forEach(Consumer action) 对此流的每个元素执行操作。 + +知识点回顾: + Consumer:接收一个参数,没有返回值 + 抽象方法:void accept(T t) ---> t->{} + +foreach的执行原理:它会将Stream流中的每个元素,作为以上Consumer的参数执行方法体 + + */ +public class ForeachDemo03 { + public static void main(String[] args) { + //对流中每个元素进行打印消费 + Stream stream = Stream.of(1, 2, 3, 4, 5); + /*stream.forEach(i->{ + System.out.println(i); + });*/ + + stream.forEach(i->System.out.println(i)); + } +} diff --git a/s_day07/src/com/inmind/stream_03/LimitDemo06.java b/s_day07/src/com/inmind/stream_03/LimitDemo06.java new file mode 100644 index 0000000..ecc370c --- /dev/null +++ b/s_day07/src/com/inmind/stream_03/LimitDemo06.java @@ -0,0 +1,16 @@ +package com.inmind.stream_03; + +import java.util.stream.Stream; + +/* +26.Stream流中的常用方法_limit +Stream limit(long maxSize) 返回由此流的元素组成的流,截短长度不能超过 maxSize 。 +将制定的流的前几个元素,组成一个新的流 + */ +public class LimitDemo06 { + public static void main(String[] args) { + Stream stream = Stream.of(1, 2, 3, 4, 5, 6, 7); + Stream stream1 = stream.limit(5); + stream1.forEach(s-> System.out.println(s)); + } +} diff --git a/s_day07/src/com/inmind/stream_03/MapDemo09.java b/s_day07/src/com/inmind/stream_03/MapDemo09.java new file mode 100644 index 0000000..063c074 --- /dev/null +++ b/s_day07/src/com/inmind/stream_03/MapDemo09.java @@ -0,0 +1,29 @@ +package com.inmind.stream_03; + +import java.util.stream.Stream; + +/* +29.Stream中的常用方法_map + 将一种类型的流的数据,全部映射(转换)成另一种数据类型的流的方法 + Stream map(Function mapper) + + 知识点回顾: + Function:数据工厂,用来数据转换 + T:参数 + R:返回值 + 抽象方法: R apply(T t) + lambda表达式:t->{return } + map方法的执行过程:将流中的每个元素,作为参数传入以上Lambda表达式中,将转换的结果全部保存到新的流 + + map:可以进行数据的拷贝,或者将保存了对象数据的字符串直接转为自定义对象 + */ +public class MapDemo09 { + public static void main(String[] args) { + //{"10","100","12","32","55"}-->整数流 + Stream stream = Stream.of("10", "100", "12", "32", "55"); + Stream stream1 = stream.map(s -> { + return Integer.parseInt(s); + }); + stream1.forEach(System.out::println); + } +} diff --git a/s_day07/src/com/inmind/stream_03/Person.java b/s_day07/src/com/inmind/stream_03/Person.java new file mode 100644 index 0000000..1b0a58e --- /dev/null +++ b/s_day07/src/com/inmind/stream_03/Person.java @@ -0,0 +1,16 @@ +package com.inmind.stream_03; + +public class Person { + private String name; + + public Person(String name) { + this.name = name; + } + + @Override + public String toString() { + return "Person{" + + "name='" + name + '\'' + + '}'; + } +} diff --git a/s_day07/src/com/inmind/stream_03/SkipDemo07.java b/s_day07/src/com/inmind/stream_03/SkipDemo07.java new file mode 100644 index 0000000..474ee54 --- /dev/null +++ b/s_day07/src/com/inmind/stream_03/SkipDemo07.java @@ -0,0 +1,15 @@ +package com.inmind.stream_03; + +import java.util.stream.Stream; + +/* +27.Stream流中的常用方法_skip +Stream skip(long n) +跳过指定流的前几个元素,将剩下的元素组成新的流 + */ +public class SkipDemo07 { + public static void main(String[] args) { + Stream stream = Stream.of(1, 2, 3, 4, 5, 6, 7); + stream.skip(5).forEach(s-> System.out.println(s)); + } +} diff --git a/s_day07/src/com/inmind/stream_03/StreamDemo02.java b/s_day07/src/com/inmind/stream_03/StreamDemo02.java new file mode 100644 index 0000000..96fdbcf --- /dev/null +++ b/s_day07/src/com/inmind/stream_03/StreamDemo02.java @@ -0,0 +1,53 @@ +package com.inmind.stream_03; + +import java.util.*; +import java.util.stream.Stream; + +/* +22.获取Stream流的两种方式(重点) +Stream流的获取方式: + 1.单列集合Collection的stream方法,得到单列集合的stream流 + Collection接口 + default Stream stream() 返回一个序列 Stream与此集合作为其来源。 + 2.Stream接口的of方法,将多个数据组成一个流 + Stream接口 + static Stream of(T... values) 返回其元素是指定值的顺序排序流。 + */ +public class StreamDemo02 { + public static void main(String[] args) { + //1.单列集合获取流 + //list集合 + ArrayList list = new ArrayList<>(); + list.add("张无忌"); + list.add("周芷若"); + list.add("赵敏"); + list.add("张三丰"); + Stream stream = list.stream(); + System.out.println(stream); + //set集合 + HashSet set = new HashSet<>(); + set.add("张无忌"); + set.add("周芷若"); + set.add("赵敏"); + set.add("张三丰"); + Stream stream1 = set.stream(); + System.out.println(stream1); + + //Map双列集合没有定义stream方法,只能通过转为单列集合间接获取流 + //间接获取流:1.所有的键的集合keySet() 2.所有的值的集合values() 3.所有的键值对对象的集合 + HashMap map = new HashMap<>(); + map.put("刘备", "孙尚香"); + Set keys = map.keySet(); + Stream stream2 = keys.stream(); + + Collection values = map.values(); + Stream stream3 = values.stream(); + + Set> entries = map.entrySet(); + Stream> stream4 = entries.stream(); + + //2.Stream的of方法 + Stream stream5 = Stream.of(1, 2, 3, 4, 5); + Stream stream6 = Stream.of("a", "b", "c", "d"); + } +} diff --git a/s_day07/src/com/inmind/stream_03/StreamToArrayDemo11.java b/s_day07/src/com/inmind/stream_03/StreamToArrayDemo11.java new file mode 100644 index 0000000..879e13a --- /dev/null +++ b/s_day07/src/com/inmind/stream_03/StreamToArrayDemo11.java @@ -0,0 +1,26 @@ +package com.inmind.stream_03; + +import java.util.Arrays; +import java.util.stream.Stream; + +/* +31.把Stream中的数据收集到数组中 +Object[] toArray() 返回一个包含此流的元素的数组。 + A[] toArray(IntFunction generator) + */ +public class StreamToArrayDemo11 { + public static void main(String[] args) { + Stream stream = Stream.of(1, 2, 3, 4, 5, 6, 7, 8, 9, 10); + Object[] array = stream.toArray(); + System.out.println(Arrays.toString(array)); + //能不能在收集数据到数组中时,就确定类型?? + Stream stream1 = Stream.of(1, 2, 3, 4, 5, 6, 7, 8, 9, 10); + Integer[] array1 = stream1.toArray(i -> new Integer[i]); + System.out.println(Arrays.toString(array1)); + + Stream stream2 = Stream.of("1", "2", "3", "4", "5", "6", "7", "8", "9"); +// String[] array2 = stream2.toArray(s -> new String[s]); + String[] array2 = stream2.toArray(String[]::new); + System.out.println(Arrays.toString(array2)); + } +} diff --git a/s_day07/src/com/inmind/stream_03/StreamToCollectionDemo12.java b/s_day07/src/com/inmind/stream_03/StreamToCollectionDemo12.java new file mode 100644 index 0000000..7d2874c --- /dev/null +++ b/s_day07/src/com/inmind/stream_03/StreamToCollectionDemo12.java @@ -0,0 +1,27 @@ +package com.inmind.stream_03; + +import java.util.Collections; +import java.util.List; +import java.util.Set; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +/* +32.把Stream中的数据收集到集合 + collect(Collector collector) 使用 Collector对此流的元素执行 mutable reduction操作。 + Collector:表示收集者是一个接口,它的实现类对象,可以使用工具类直接获取 + Collectors: + toList:List集合收集者 + toSet:Set集合收集者 + */ +public class StreamToCollectionDemo12 { + public static void main(String[] args) { + Stream stream = Stream.of(1, 2, 3, 4, 5, 6, 7, 8, 9); + List list = stream.collect(Collectors.toList()); + System.out.println(list); + Stream stream1 = Stream.of(1, 2, 3, 4, 5, 6, 7, 8, 9,9,9,9,9); + Set sets = stream1.collect(Collectors.toSet()); + System.out.println(sets); + + } +} diff --git a/s_day07/src/com/inmind/stream_03/Test10.java b/s_day07/src/com/inmind/stream_03/Test10.java new file mode 100644 index 0000000..38cfddb --- /dev/null +++ b/s_day07/src/com/inmind/stream_03/Test10.java @@ -0,0 +1,115 @@ +package com.inmind.stream_03; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.stream.Stream; + +/* +现在有两个ArrayList集合存储队伍当中的多个成员姓名,要求使用传统的for循环(或增强for循环)依次进行以下若干操作步骤: + +1. 第一个队伍只要名字为3个字的成员姓名; +2. 第一个队伍筛选之后只要前3个人; +3. 第二个队伍只要姓张的成员姓名; +4. 第二个队伍筛选之后不要前2个人; +5. 将两个队伍合并为一个队伍; +6.根据姓名创建Person对象 +7. 打印整个队伍的Person信息。 + */ +public class Test10 { + public static void main(String[] args) { + List one = new ArrayList<>(); + one.add("迪丽热巴"); + one.add("宋远桥"); + one.add("苏星河"); + one.add("老子"); + one.add("庄子"); + one.add("孙子"); + one.add("洪七公"); + one.add("洪八公"); + + List two = new ArrayList<>(); + two.add("古力娜扎"); + two.add("张无忌"); + two.add("张三丰"); + two.add("赵丽颖"); + two.add("张二狗"); + two.add("张天爱"); + two.add("张三"); + + //1. 第一个队伍只要名字为3个字的成员姓名; + //2. 第一个队伍筛选之后只要前3个人; + ArrayList newOne = new ArrayList<>(); + for (String s : one) { + if (s.length() == 3) { + newOne.add(s); + } + } + ArrayList newOne1 = new ArrayList<>(); + for (int i = 0; i < newOne.size(); i++) { + if (i < 3) { + newOne1.add(newOne.get(i)); + } + } + System.out.println(newOne1); + + //3. 第二个队伍只要姓张的成员姓名; + //4. 第二个队伍筛选之后不要前2个人; + ArrayList newTwo = new ArrayList<>(); + for (String s : two) { + if (s.startsWith("张")) { + newTwo.add(s); + } + } + ArrayList newTwo1 = new ArrayList<>(); + for (int i = 0; i < newTwo.size(); i++) { + if (i >= 2) { + newTwo1.add(newTwo.get(i)); + } + } + System.out.println(newTwo1); + + //5. 将两个队伍合并为一个队伍; + newOne1.addAll(newTwo1); + System.out.println(newOne1); + + //6.根据姓名创建Person对象 + ArrayList personList = new ArrayList<>(); + for (String s : newOne1) { + personList.add(new Person(s)); + } + + //7. 打印整个队伍的Person信息。 + for (Person person : personList) { + System.out.println(person); + } + System.out.println("----------------------------------"); + //---------------------------------Stream------------------------------ + //1. 第一个队伍只要名字为3个字的成员姓名; + Stream stream = one.stream(); + Stream oneStream1 = stream.filter(s -> s.length() == 3); + //2. 第一个队伍筛选之后只要前3个人; + Stream oneStream2 = oneStream1.limit(3); + + //3. 第二个队伍只要姓张的成员姓名; + Stream twoStream1 = two.stream().filter(s -> s.startsWith("张")); + //4. 第二个队伍筛选之后不要前2个人; + Stream twoStream2 = twoStream1.skip(2); + + //5. 将两个队伍合并为一个队伍; + Stream newStream = Stream.concat(oneStream2, twoStream2); + //6.根据姓名创建Person对象 + Stream personStream = newStream.map(str -> { + return new Person(str); + }); + //7. 打印整个队伍的Person信息。 + personStream.forEach(System.out::println); + //-------------------------------------------------------------------- + System.out.println("-----------------------------------------------------------------"); + Stream.concat( + one.stream().filter(s -> s.length() == 3).limit(3), + two.stream().filter(s -> s.startsWith("张")).skip(2)) + .map(s->new Person(s)) + .forEach(System.out::println); + } +} diff --git a/s_day07/src/com/inmind/test_04/StreamTest.java b/s_day07/src/com/inmind/test_04/StreamTest.java new file mode 100644 index 0000000..1a6cfc0 --- /dev/null +++ b/s_day07/src/com/inmind/test_04/StreamTest.java @@ -0,0 +1,101 @@ +package com.inmind.test_04; + +import java.util.ArrayList; +import java.util.List; +import java.util.function.Consumer; +import java.util.function.Function; +import java.util.function.Predicate; +import java.util.function.Supplier; +import java.util.stream.Stream; + +/* +需求说明 +本案例模拟学生成绩管理系统,需要实现以下业务功能: + +生成测试学生数据(包含姓名、年龄、成绩) +打印所有学生的完整信息 +筛选并打印成绩及格(≥60 分)的学生 +统计 18 岁以上且成绩及格的学生数量 +提取并打印所有学生的姓名 +将学生成绩转换为等级(A/B/C/D)并展示 +获取并展示第 3-5 名学生信息(按原始顺序) +合并 "及格学生" 和 "前 2 名学生" 两个数据集并展示 + + +技术点说明 +Supplier 接口:用于提供学生数据列表,体现 "供给型" 功能 +Consumer 接口:用于消费学生对象(打印信息),体现 "消费型" 功能 +Predicate 接口:用于定义筛选条件(成绩及格、成年),体现 "判断型" 功能,包含条件组合(and) +Function 接口:用于数据转换(学生→姓名、成绩→等级),体现 "功能型" 功能 +Stream 方法: +forEach:遍历元素 +filter:按条件筛选 +count:统计元素数量 +map:元素转换 +skip:跳过指定数量元素 +limit:限制获取元素数量 +concat:合并两个流 + */ +public class StreamTest { + public static void main(String[] args) { + //使用Supplier生成学生数据 + Supplier> supplier = () ->{ + List list = new ArrayList(); + list.add(new Student("张三",18,85.5)); + list.add(new Student("李四",19,75.5)); + list.add(new Student("王五",20,65.5)); + list.add(new Student("赵六",22,85.5)); + list.add(new Student("田七",21,45.5)); + list.add(new Student("孙八",18,93.5)); + list.add(new Student("周九",19,95.5)); + list.add(new Student("吴十",20,35.5)); + return list; + }; + + //获取学生列表 + List students = supplier.get(); + //使用Consumer打印所有学生的完整信息 + Consumer printConsumer = student->System.out.println(student); + + //使用消费者对学生列表消费 + students.stream().forEach(printConsumer); + System.out.println("----------------------------------------"); + //使用Predicate得到筛选并打印成绩及格(≥60 分)的学生 +// Predicate predicate = student->{return student.getScore()>= 60;}; + Predicate predicate = student->student.getScore()>= 60; + students.stream().filter(predicate).forEach(printConsumer); + System.out.println("----------------------------------------"); + //统计 18 岁以上且成绩及格的学生数量 + Predicate isAdult = student -> student.getAge()>18; + long count = students.stream().filter(predicate.and(isAdult)).count(); + System.out.println("18 岁以上且成绩及格的学生数量:"+count); + //使用Function提取并打印所有学生的姓名(数据转换) + Function toNameFunction = student-> student.getName(); + students.stream().map(toNameFunction).forEach(s->System.out.println(s)); + System.out.println("----------------------------------------"); + //使用Function将学生成绩转换为等级(A/B/C/D)并展示 + Function toScoreFunction = student-> { + String level = "A"; + Double score = student.getScore(); + if (score >= 90) { + level = "A"; + }else if (score >= 80) { + level = "B"; + }else if (score >= 60) { + level = "C"; + }else{ + level = "D"; + } + return level; + }; + students.stream().map(toScoreFunction).forEach(s->System.out.println(s)); + System.out.println("----------------------------------------"); + //获取并展示第 3-5 名学生信息(按原始顺序) + students.stream().skip(2).limit(3).forEach(printConsumer); + System.out.println("----------------------------------------"); + //合并 "及格学生" 和 "前 2 名学生" 两个数据集并展示 + Stream stream1 = students.stream().filter(predicate); + Stream stream2 = students.stream().limit(2); + Stream.concat(stream1, stream2).forEach(printConsumer); + } +} diff --git a/s_day07/src/com/inmind/test_04/Student.java b/s_day07/src/com/inmind/test_04/Student.java new file mode 100644 index 0000000..029cd11 --- /dev/null +++ b/s_day07/src/com/inmind/test_04/Student.java @@ -0,0 +1,44 @@ +package com.inmind.test_04; + +public class Student { +// 包含姓名、年龄、成绩) + private String name; + private Integer age; + private Double score; + + public Student(String name, Integer age, Double score) { + this.name = name; + this.age = age; + this.score = score; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public Integer getAge() { + return age; + } + + public void setAge(Integer age) { + this.age = age; + } + + public Double getScore() { + return score; + } + + public void setScore(Double score) { + this.score = score; + } + + @Override + public String toString() { + return "姓名:"+name+",年龄:"+age+",成绩:"+score; + } +} + diff --git a/s_day08/src/com/inmind/digui_02/Demo01.java b/s_day08/src/com/inmind/digui_02/Demo01.java new file mode 100644 index 0000000..edb93bb --- /dev/null +++ b/s_day08/src/com/inmind/digui_02/Demo01.java @@ -0,0 +1,34 @@ +package com.inmind.digui_02; +/* +9.递归的概念 + +递归:一个方法直接或者间接调用字节 + 直接调用:A->A->A->A->A + 间接调用:A->B->A->B + + 递归代码必须要有结束条件,如果没有结束条件,那么一定会栈内存溢出错误 + +扩展: + 1.内存溢出:内存空间总共有4G,但是我们要开辟超出4G的空间,内存溢出 + 2.内存泄漏:一个对象已经不再使用了,但是它还占用着内存,无法释放 + */ +public class Demo01 { + static int i = 0; + + public static void main(String[] args) { + methodA(); + } + + public static void methodA(){ + System.out.println(i); + i++; + if (i >= 10000) { + return; + } + methodB(); + } + + public static void methodB(){ + methodA(); + } +} diff --git a/s_day08/src/com/inmind/digui_02/Demo02.java b/s_day08/src/com/inmind/digui_02/Demo02.java new file mode 100644 index 0000000..c1bd0ac --- /dev/null +++ b/s_day08/src/com/inmind/digui_02/Demo02.java @@ -0,0 +1,39 @@ +package com.inmind.digui_02; +/* +10.递归求阶乘的代码实现 +递归代码: + 1.自己调用自己 + 2.递归代码必须要有结束条件 + +阶乘: +5! = 5*4*3*2*1 +4! = 4*3*2*1 +3! = 3*2*1 +2! = 2*1 +1! = 1 + +阶乘的另一种实现方式: +5! = 5*4! +4! = 4*3! +3! = 3*2! +2! = 2*1! +1! = 1 + +求阶乘的数学规律是n! = n*(n-1)! + + */ +public class Demo02 { + public static void main(String[] args) { + //5的阶乘 + System.out.println(getJieCheng(3)); + } + + //递归求阶乘 + public static int getJieCheng(int n){ + if (n == 1) { + return 1; + } + //n! = n*(n-1)! + return n * getJieCheng(n - 1); + } +} diff --git a/s_day08/src/com/inmind/digui_02/Demo03.java b/s_day08/src/com/inmind/digui_02/Demo03.java new file mode 100644 index 0000000..d205f4e --- /dev/null +++ b/s_day08/src/com/inmind/digui_02/Demo03.java @@ -0,0 +1,36 @@ +package com.inmind.digui_02; +/* +12.递归求累和的练习 + +递归代码的实现: + 1.找出自己调用自己的规律 + 2.一定要有结束条件 + +比如 +5的累和:5+4+3+2+1 = 15 +4的累和:4+3+2+1 = 10 +3的累和:3+2+1 = 6 +2的累和:2+1 = 3 +1的累和:1 + +要用递归代码求出n的累和是多少??? +数学规律:n的累和:n+(n-1)的累和 +结束条件:1的累和是1 + + + + */ +public class Demo03 { + public static void main(String[] args) { + int result = getLeihe(100); + System.out.println(result); + } + + private static int getLeihe(int n) { + //结束条件 + if (n == 1) { + return 1; + } + return n+getLeihe(n-1); + } +} diff --git a/s_day08/src/com/inmind/digui_02/Demo04.java b/s_day08/src/com/inmind/digui_02/Demo04.java new file mode 100644 index 0000000..eb829e8 --- /dev/null +++ b/s_day08/src/com/inmind/digui_02/Demo04.java @@ -0,0 +1,44 @@ +package com.inmind.digui_02; + +import java.io.File; + +/* +13.递归遍历文件夹的练习(重点) + +需求:将D:\io_test里面的所有的子内容的名称全部打印出来 + */ +public class Demo04 { + public static void main(String[] args) { + File file = new File("D:\\io_test"); + System.out.println(file); + //定义出一个方法将制定文件夹里的内容遍历出来 + getFiles(file); + } + + private static void getFiles(File file) { + File[] files = file.listFiles(); + //遍历数组 + for (File f : files) { + if(f.isDirectory()) { + //是文件夹可能要进行再一次的遍历 + System.out.println(f.getName()); + getFiles(f); + }else{ + System.out.println(f.getName()); + } + } + } + + private static void getbFiles(File f) { + File[] files = f.listFiles(); + //遍历b文件夹 + for (File file : files) { + if (file.isDirectory()) { + //c文件夹,进行c文件夹的遍历,甚至还有更多更深层次的文件夹要操作 + + } else { + System.out.println(file.getName()); + } + } + } +} diff --git a/s_day08/src/com/inmind/digui_02/Test05.java b/s_day08/src/com/inmind/digui_02/Test05.java new file mode 100644 index 0000000..76a5829 --- /dev/null +++ b/s_day08/src/com/inmind/digui_02/Test05.java @@ -0,0 +1,36 @@ +package com.inmind.digui_02; + +import java.io.File; + +/* +14.练习_打印指定目录下所有的txt文件 + */ +public class Test05 { + public static void main(String[] args) { + File file = new File("D:\\io_test"); + getTxtFiles(file); + } + + private static void getTxtFiles(File file) { + if (file == null) { + return; + } + if (!file.isDirectory()) { + return; + } + + File[] files = file.listFiles(); + for (File f : files) { + if (f.isDirectory()) { + //继续递归遍历子文件夹 + getTxtFiles(f); + }else{ + //一定是文件,判断是否是.txt结尾 + String name = f.getName(); + if (name.endsWith(".txt")) { + System.out.println(name); + } + } + } + } +} diff --git a/s_day08/src/com/inmind/file_01/Demo01.java b/s_day08/src/com/inmind/file_01/Demo01.java new file mode 100644 index 0000000..4b4f920 --- /dev/null +++ b/s_day08/src/com/inmind/file_01/Demo01.java @@ -0,0 +1,41 @@ +package com.inmind.file_01; + +import java.io.File; + +/* + 1.File类的介绍 + 在java中定义了一个类File,用来表示计算机中的文件或文件夹 + 在英文中: + file:文件 + directory:目录 + path:路径 + + File,用来操作计算机中的文件或文件夹,在IO流中大量使用,文件下载,文件上传,文件复制 + ------------------------------------------------------------------- + 构造方法: + File(String pathname) 通过将给定的路径名字符串转换为抽象路径名来创建新的 File实例。 + File(String parent, String child) 从父路径名字符串和子路径名字符串创建新的 File实例。 + File(File parent, String child) 从父抽象路径名和子路径名字符串创建新的 File实例。 + + */ +public class Demo01 { + public static void main(String[] args) { + //File(String pathname) 通过将给定的路径名字符串转换为抽象路径名来创建新的 File实例。 + //D:\io_test\a.txt + File file = new File("D:\\io_test\\a.txt"); +// File file = new File("D:/io_test/a.txt"); + System.out.println(file); + + //File(String parent, String child) 从父路径名字符串和子路径名字符串创建新的 File实例。 + //D:\io_test\a.txt + //D:\io_test:父路径 + //a.txt:子路径 + File file1 = new File("D:/io_test", "a.txt"); + System.out.println(file1); + + //File(File parent, String child) 从父抽象路径名和子路径名字符串创建新的 File实例。 + File parentFile = new File("D:\\io_test"); + File bFile = new File(parentFile, "b"); + System.out.println(bFile); + } +} diff --git a/s_day08/src/com/inmind/file_01/Demo02.java b/s_day08/src/com/inmind/file_01/Demo02.java new file mode 100644 index 0000000..370fca8 --- /dev/null +++ b/s_day08/src/com/inmind/file_01/Demo02.java @@ -0,0 +1,28 @@ +package com.inmind.file_01; + +import java.io.File; + +/* +3.File类获取的方法 + public String getAbsolutePath() :返回此File的绝对路径名字符串。(重点) + public String getPath() :将此File转换为路径名字符串。(了解) + public String getName() :返回由此File表示的文件或目录的名称。(重点) + public long length() :返回由此File表示的文件的长度。 + + 扩展: + 1.在UTF-8中一个中文使用3个字节表示 + 2.在GBK中一个中文使用2个字节来表示 + 3.length()不能直接获取文件夹的字节数,只能遍历所有的文件相加 + */ +public class Demo02 { + public static void main(String[] args) { +// File file = new File("D:\\io_test\\a.txt"); + File file = new File("D:\\io_test\\b"); + System.out.println(file.getAbsolutePath()); + System.out.println(file.getPath()); + System.out.println(file.getName()); + System.out.println(file.length()); + System.out.println(file); + + } +} diff --git a/s_day08/src/com/inmind/file_01/Demo03.java b/s_day08/src/com/inmind/file_01/Demo03.java new file mode 100644 index 0000000..756bdd7 --- /dev/null +++ b/s_day08/src/com/inmind/file_01/Demo03.java @@ -0,0 +1,19 @@ +package com.inmind.file_01; + +import java.io.File; + +/* + 4.相对路径和绝对路径(重点) + 绝对路径:带有盘符的路径 D:\\io_test\\a.txt + 相对路径: 不带有盘符的路径 io_test\\b + + 注意:在javaSE中,相对路径是将当前工程路径作为父路径,拼接上子路径生成一个新的路径 + */ +public class Demo03 { + public static void main(String[] args) { + File file = new File("a.txt"); + System.out.println(file); + System.out.println(file.getPath()); + System.out.println(file.getAbsolutePath()); + } +} diff --git a/s_day08/src/com/inmind/file_01/Demo04.java b/s_day08/src/com/inmind/file_01/Demo04.java new file mode 100644 index 0000000..0b2bac3 --- /dev/null +++ b/s_day08/src/com/inmind/file_01/Demo04.java @@ -0,0 +1,31 @@ +package com.inmind.file_01; + +import java.io.File; + +/* +5.File中判断的方法 + public boolean exists() :此File表示的文件或目录是否实际存在。 + public boolean isDirectory() :此File表示的是否为目录。 + public boolean isFile() :此File表示的是否为文件。 + + 注意:对于不存在的File对象,所有的判断都是false + */ +public class Demo04 { + public static void main(String[] args) { + File file = new File("D:\\io_test\\a.txt"); + System.out.println(file.exists());//true + System.out.println(file.isDirectory());//false + System.out.println(file.isFile());//true + System.out.println("------------------------------------"); + File bFile = new File("D:\\io_test\\b"); + System.out.println(bFile.exists());//true + System.out.println(bFile.isDirectory());//true + System.out.println(bFile.isFile());//false + System.out.println("------------------------------------"); + File cFile = new File("D:\\io_test\\c"); + System.out.println(cFile.exists());//false + System.out.println(cFile.isDirectory());//false + System.out.println(cFile.isFile());//false + + } +} diff --git a/s_day08/src/com/inmind/file_01/Demo05.java b/s_day08/src/com/inmind/file_01/Demo05.java new file mode 100644 index 0000000..0ed75f9 --- /dev/null +++ b/s_day08/src/com/inmind/file_01/Demo05.java @@ -0,0 +1,32 @@ +package com.inmind.file_01; + +import java.io.File; +import java.io.IOException; + +/* + 6.File中的创建功能 + public boolean createNewFile() :当且仅当具有该名称的文件尚不存在时,创建一个新的空文件。(重点) + public boolean mkdir() :创建由此File表示的目录。 + public boolean mkdirs() :创建由此File表示的目录,包括任何必需但不存在的父目录。(重点) + */ +public class Demo05 { + public static void main(String[] args) throws IOException { + File file = new File("a.txt"); + /*System.out.println(file.exists()); + System.out.println(file.createNewFile());*/ + if (!file.exists()) { + file.createNewFile(); + } + File bfile = new File("b"); + System.out.println(bfile.mkdir()); + + + File bDir = new File("b.txt"); + System.out.println(bDir.mkdir()); + + //创建出一个c/a/ + //如果想要将对应不存在的父路径也一次性创建出来,那么要使用mkdirs + File file1 = new File("c\\a"); + System.out.println(file1.mkdirs()); + } +} diff --git a/s_day08/src/com/inmind/file_01/Demo06.java b/s_day08/src/com/inmind/file_01/Demo06.java new file mode 100644 index 0000000..fd88891 --- /dev/null +++ b/s_day08/src/com/inmind/file_01/Demo06.java @@ -0,0 +1,32 @@ +package com.inmind.file_01; + +import java.io.File; + +/* + public boolean delete() :删除由此File表示的文件或目录,返回删除成功与失败的结果 + + 注意点: + 1.如果一个文件夹中还有子内容,不能直接删除,必须先删除所有子内容,父文件夹才能删除 + 2.delete方法是物理删除,不能恢复的 + */ +public class Demo06 { + public static void main(String[] args) { + //删除文件 + File file = new File("a.txt"); + System.out.println(file.delete()); + File file1 = new File("a"); + System.out.println(file1.delete()); + + //删除文件夹 + File file2 = new File("b.txt"); + System.out.println(file2.delete()); + File file3 = new File("b"); + System.out.println(file3.delete()); + + //直接删除拥有子内容的文件夹 + File file4 = new File("c\\a"); + System.out.println(file4.delete()); + File file5 = new File("c"); + System.out.println(file5.delete()); + } +} diff --git a/s_day08/src/com/inmind/file_01/Demo07.java b/s_day08/src/com/inmind/file_01/Demo07.java new file mode 100644 index 0000000..bf48754 --- /dev/null +++ b/s_day08/src/com/inmind/file_01/Demo07.java @@ -0,0 +1,25 @@ +package com.inmind.file_01; + +import java.io.File; +import java.util.Arrays; + +/* + File类的遍历方法 + public String[] list() :返回一个String数组,表示该File目录中的所有子文件或目录的名称。 + public File[] listFiles() :返回一个File数组,表示该File目录中的所有的子文件或目录。 + */ +public class Demo07 { + public static void main(String[] args) { + //D:\io_test + File file = new File("D:\\io_test"); + //获取指定路径下的所有的文件或者文件夹的名称 + String[] names = file.list(); + System.out.println(Arrays.toString(names)); + System.out.println("------------------------"); + File[] files = file.listFiles(); + System.out.println(Arrays.toString(files)); + for (File f : files) { + System.out.println(f.getAbsolutePath()); + } + } +} diff --git a/s_day08/src/com/inmind/file_filter_03/Demo01.java b/s_day08/src/com/inmind/file_filter_03/Demo01.java new file mode 100644 index 0000000..21b38f5 --- /dev/null +++ b/s_day08/src/com/inmind/file_filter_03/Demo01.java @@ -0,0 +1,32 @@ +package com.inmind.file_filter_03; + +import java.io.File; +import java.util.Arrays; + +/* +15.过滤器的基本使用 +File[] listFiles(FileFilter filter) 返回一个抽象路径名数组,表示由此抽象路径名表示的满足指定过滤器的目录中的文件和目录。 + +FileFilter + boolean accept(File pathname) :pathname是一个文件或者文件夹对象,它就是当前调用listFiles方法的文件夹中每个子元素,将它们 + 依次作为File对象,传入accept方法,执行代码,得到boolean的结果,如果是true则满足条件,放入返回值中File[],如果是false则过滤掉 + +过滤器的基本使用: + 1.创建文件夹对象 + 2.定义一个自定义的文件过滤器实现类 + 3.调用listFiles(FileFilter filter) + + //需求:将制定目录的一级子内容中,使用文件顾虑,直接获取所有.txt文件 + */ +public class Demo01 { + public static void main(String[] args) { + //1.创建文件夹对象 + File file = new File("D:\\io_test"); + //2.定义一个自定义的文件过滤器实现类 + MyFileFilter myFileFilter = new MyFileFilter(); + //3.调用listFiles(FileFilter filter) + File[] files = file.listFiles(myFileFilter); + System.out.println(Arrays.toString(files)); + + } +} diff --git a/s_day08/src/com/inmind/file_filter_03/MyFileFilter.java b/s_day08/src/com/inmind/file_filter_03/MyFileFilter.java new file mode 100644 index 0000000..8ead0ac --- /dev/null +++ b/s_day08/src/com/inmind/file_filter_03/MyFileFilter.java @@ -0,0 +1,18 @@ +package com.inmind.file_filter_03; + +import java.io.File; +import java.io.FileFilter; + +public class MyFileFilter implements FileFilter { + @Override + public boolean accept(File pathname) { + return pathname.isFile()&&pathname.getName().endsWith(".txt"); + //业务操作是文件且以.txt结尾的,保留,否则过滤掉 + /*if (pathname.isFile()&&pathname.getName().endsWith(".txt")){ + return true; + }else { + return false; + }*/ + + } +} diff --git a/s_day08/src/com/inmind/file_filter_03/Test02.java b/s_day08/src/com/inmind/file_filter_03/Test02.java new file mode 100644 index 0000000..de0d78b --- /dev/null +++ b/s_day08/src/com/inmind/file_filter_03/Test02.java @@ -0,0 +1,47 @@ +package com.inmind.file_filter_03; + +import java.awt.print.Pageable; +import java.io.File; +import java.io.FileFilter; + +/* +14.练习_使用文件过滤器打印指定目录下所有的txt文件 + */ +public class Test02 { + public static void main(String[] args) { + File file = new File("D:\\io_test"); + getTxtFiles(file); + } + + private static void getTxtFiles(File file) { + if (file == null) { + return; + } + if (!file.isDirectory()) { + return; + } + + /*File[] files = file.listFiles(new FileFilter() { + @Override + public boolean accept(File pathname) { + //是文件夹和.txt文件则保留,否则舍弃 + return pathname.isDirectory()||(pathname.isFile()&&pathname.getName().endsWith(".txt")); + } + });*/ + /*File[] files = file.listFiles(pathname -> { + return pathname.isDirectory() || (pathname.isFile() && pathname.getName().endsWith(".txt")); + });*/ + File[] files = file.listFiles(pathname -> pathname.isDirectory() + || (pathname.isFile() && pathname.getName().endsWith(".txt"))); + for (File f : files) { + if (f.isDirectory()) { + //继续递归遍历子文件夹 + getTxtFiles(f); + }else{ + //一定是.txt文件 + String name = f.getName(); + System.out.println(name); + } + } + } +} diff --git a/s_day08/src/com/inmind/file_test_04/FileTest.java b/s_day08/src/com/inmind/file_test_04/FileTest.java new file mode 100644 index 0000000..ba532b6 --- /dev/null +++ b/s_day08/src/com/inmind/file_test_04/FileTest.java @@ -0,0 +1,303 @@ +package com.inmind.file_test_04; + +import java.io.File; +import java.io.IOException; +import java.text.SimpleDateFormat; +import java.util.ArrayList; +import java.util.Date; +import java.util.Scanner; + +/* +业务功能说明 +这个文件管理工具模拟了操作系统中文件管理器的核心功能,主要业务场景和功能包括: + +目录浏览功能 +展示当前目录下的所有文件和子目录 +按类型(先目录后文件)分类显示 +展示每个项目的名称、大小、修改时间等关键信息 +解决了中文显示对齐问题,提供清晰的视觉体验 + +目录导航功能 +支持绝对路径和相对路径切换 +支持 ".." 返回上一级目录的快捷操作 +提供路径有效性检查,防止错误导航 + +文件和目录创建 +支持创建新文件或新目录 +包含重名检查,避免覆盖现有项目 +处理创建过程中可能出现的异常 + +文件和目录删除 +支持删除单个文件或目录 +对于目录采用递归删除策略,先删除内容再删除目录本身 +包含删除确认步骤,防止误操作 + +文件搜索功能 +支持按名称关键词搜索 +提供两种搜索范围:当前目录和包含子目录 +区分显示搜索结果中的目录和文件 + +批量文件操作 +基于文件扩展名筛选特定类型文件 +支持批量删除筛选出的文件 +提供操作前预览,确保用户清楚操作对象 + */ +public class FileTest { + private static Scanner sc = new Scanner(System.in); + private static SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm"); + //当前系统默认的文件夹目录为用户目录 +// private static String currentPath = System.getProperty("user.home"); + private static String currentPath = "D:/io_test"; + + public static void main(String[] args) { + //循环显示主菜单,直到用户退出 + while (true) { + System.out.println("===== 文件管理工具 ====="); + System.out.println("当前路径: "+currentPath); + System.out.println("1. 浏览目录 2. 切换目录 3. 创建文件/目录"); + System.out.println("4. 删除项目 5. 搜索文件 6. 批量操作 7. 退出"); + System.out.println("请选择: "); + int choice = sc.nextInt(); + if (choice < 1 || choice > 7) { + System.out.println("输入选项有误,只能输入1~7的数字!!"); + continue; + } + + switch (choice) { + case 1: browseDirectory();break; + case 2: switchDirectory();break; + case 3: createItem();break; + case 4: deleteItem();break; + case 5: searchItem();break; + case 6: break; + case 7: + System.out.println("谢谢使用,再见"); + sc.close(); + return; + } + } + } + + /* + 文件搜索功能 + 支持按名称关键词搜索 + 提供两种搜索范围:当前目录和包含子目录 + 区分显示搜索结果中的目录和文件 + */ + private static void searchItem() { + System.out.println("输入搜索关键词: "); + sc.nextLine(); + String keyword = sc.nextLine().trim().toLowerCase(); + System.out.println("1.当前目录 2.包含子目录,请选择: "); + int choice = Integer.parseInt(sc.nextLine().trim()); + ArrayList searchFiles = new ArrayList<>(); + + if (choice == 1) { + File file = new File(currentPath); + File[] files = file.listFiles(); + for (File f : files) { + if (f.getName().contains(keyword)) { + searchFiles.add(f); + } + } + }else { + //递归搜索,要把搜索到的文件或者文件夹保存到指定集合 + searchSubItems(new File(currentPath),keyword,searchFiles); + } + + //显示最后的搜索结果 + System.out.println("找到 "+searchFiles.size()+" 个匹配项:"); + searchFiles.forEach(file->{ + System.out.println((file.isDirectory()?"【目录】":"【文件】")+" "+file.getAbsolutePath()); + }); + } + + private static void searchSubItems(File file, String keyword, ArrayList searchFiles) { + //如果不是目录,直接返回 + if (!file.isDirectory()) { + return; + } + File[] files = file.listFiles(); + + //遍历项目 + for (File f : files) { + if (f.getName().contains(keyword)) { + searchFiles.add(f); + } + //在遍历当前层子元素时,如果是文件夹还要进行递归搜索,保存数据到同一个集合 + if (f.isDirectory()) { + searchSubItems(f, keyword, searchFiles); + } + } + } + + /* + 文件和目录删除 + 支持删除单个文件或目录 + 对于目录采用递归删除策略,先删除内容再删除目录本身 + 包含删除确认步骤,防止误操作 + */ + private static void deleteItem() { + System.out.println("输入要删除的名称:"); + sc.nextLine(); + String name = sc.nextLine(); + //创建要删除的File对象 + File item = new File(currentPath + File.separator + name); + //判断是否存在 + if (!item.exists()) { + System.out.println("项目不存在"); + return; + } + //确认删除?? + System.out.println("确定删除? (y/n):"); + String choice = sc.nextLine().trim(); + if (choice.equals("y")) { + //执行删除 + boolean result = deleteProject(item); + System.out.println(result?"删除成功":"删除失败"); + }else{ + System.out.println("已取消"); + } + + } + + //递归删除 + private static boolean deleteProject(File item) { + //如果是目录,先删除所有子文件和子目录 + if (item.isDirectory()&&item.listFiles().length>0) { + File[] childFiles = item.listFiles(); + if (childFiles != null) { + for (File child : childFiles) { + //递归删除子项,如果有一项失败了则整体失败 + if (!deleteProject(child)) { + return false; + } + + } + } + } + + //直接删除文件或者空目录 + return item.delete(); + } + + /* + 文件和目录创建 + 支持创建新文件或新目录 + 包含重名检查,避免覆盖现有项目 + 处理创建过程中可能出现的异常 + */ + private static void createItem() { + System.out.println("1.创建文件 2.创建目录,请选择:"); + sc.nextLine(); + String type = sc.nextLine().trim(); + System.out.println("请输入名称:"); + String name = sc.nextLine().trim(); + + //验证文件名不能为空 + if (name.isEmpty()) { + System.out.println("名称不能为空"); + return; + } + //创建File对象 + File item = new File(currentPath + File.separator + name); + //检查同名问题 + if (item.exists()) { + System.out.println("已存在同名项目!!!"); + return; + } + try { + //根据类型创建 + boolean success = "1".equals(type)?item.createNewFile():item.mkdirs(); + System.out.println(success?"创建成功":"创建失败"); + } catch (IOException e) { + System.out.println("创建失败"+e.getMessage()); + } + + } + + //切换目录的方法 + private static void switchDirectory() { + System.out.println("输入目标路径(..返回上一级):"); + sc.nextLine(); + String path = sc.nextLine(); + //输入的新目录,可能是..,绝对路径,相对路径 + File newDir = path.equals("..") ? new File(currentPath).getParentFile() : + new File(path).isAbsolute() ? new File(path) : new File(currentPath + File.separator + path); + + //验证目录的有效性 + if (newDir != null&& newDir.exists()&&newDir.isDirectory()) { + currentPath = newDir.getAbsolutePath(); + System.out.println("已切换到:"+currentPath); + }else{ + System.out.println("目录不存在"); + } + + } + + //目录浏览功能 + //展示当前目录下的所有文件和子目录 + //按类型(先目录后文件)分类显示 + //展示每个项目的名称、大小、修改时间等关键信息 + //解决了中文显示对齐问题,提供清晰的视觉体验 + private static void browseDirectory() { + //创建出当前文件夹的File对象 + File dir = new File(currentPath); + //检查目录的是否有效 + if (!dir.exists()||!dir.isDirectory()) { + System.out.println("无效目录!"); + return; + } + + //获取目录下的所有的文件和目录 + File[] files = dir.listFiles(); + if (files == null||files.length==0) { + System.out.println("目录为空"); + return; + } + + //显示目录的内容标题大小等信息 + System.out.println("目录内容:"); + System.out.println("类型 名称 大小 修改时间"); + System.out.println("------------------------------------------------"); + //先显示子目录 + for (File item : files) { + if (item.isDirectory()) { + printItemInfo(item); + } + } + //显示子文件 + for (File item : files) { + if (item.isFile()) { + printItemInfo(item); + } + } + } + + private static void printItemInfo(File item) { + //确定类型 + String type = item.isDirectory() ? "目录" : "文件"; + //大小 + String size = item.isDirectory()?"-":item.length()+"B"; + //格式化修改时间 + String time = sdf.format(new Date(item.lastModified())); + //拼接打印信息,保持列对齐 + String line = padRight(type,6)+padRight(item.getName(),30)+padRight(size,15)+time; + System.out.println(line); + } + + //辅助方法:将字符串右对齐并填充空格,至制定长度 + private static String padRight(String str, int len) { + //如果字符串过长,截断并加空格 + if (str.length() >= len) { + return str.substring(0, len - 1) + " "; + } + //否则补全空格 + StringBuilder sb = new StringBuilder(str); + while (sb.length() < len) { + sb.append(" "); + } + return sb.toString(); + } + +} diff --git a/s_day09/src/com/inmind/input_02/Demo01.java b/s_day09/src/com/inmind/input_02/Demo01.java new file mode 100644 index 0000000..71a0b4b --- /dev/null +++ b/s_day09/src/com/inmind/input_02/Demo01.java @@ -0,0 +1,68 @@ +package com.inmind.input_02; + +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.IOException; + +/* +8.字节输入流以及相关API的介绍 +在java中使用抽象类InputStream来表示字节输入流 +常用的子类:FileInputStream +FileInputStream的作用;将硬盘中的文件的数据读取到内存 + +构造方法: + FileInputStream(File file) 通过打开与实际文件的连接来创建一个 FileInputStream ,该文件由文件系统中的 File对象 file命名。 + FileInputStream(String name) 通过打开与实际文件的连接来创建一个 FileInputStream ,该文件由文件系统中的路径名 name命名。 +常用方法: + int read() 从该输入流读取一个字节的数据。 + int read(byte[] b) 从该输入流读取最多 b.length个字节的数据到一个字节数组。 + void close() 关闭资源 + +字节输入流的基本使用: + 1.创建字节输入流对象,传递要读的file文件 + 2.调用读方法 + 3.资源释放 + */ +public class Demo01 { + public static void main(String[] args) throws IOException { + //1.创建字节输入流对象,传递要读的file文件 + /* + 注意: + 1.创建字节输入流对象时,文件不存在,直接报异常FileNotFoundException + 2.创建字节输出流对象时,文件不存在才会创建 + */ + FileInputStream fis = new FileInputStream("source.txt"); + //2.调用读方法 + //使用字节输入流一次读取一个字节 + /*int c = fis.read(); + System.out.println(c); + System.out.println((char) c); + + c = fis.read(); + System.out.println(c); + System.out.println((char) c); + + c = fis.read(); + System.out.println(c); + System.out.println((char) c); + + c = fis.read(); + System.out.println(c); + System.out.println((char) c);*/ + //使用while循环优化以上代码 + int c;//用来保存字节输入流读取到的一个字节数据 + + /* + (c = fis.read()) != -1)执行流程: + 1.fis.read() :从字节输入流中读取一个字节数据 + 2.c = fis.read():将读取到的一个字节数据保存到变量c中 + 3.(c = fis.read()) != -1):判断是否读取到字节数据了,如果读到,那么就继续操作 + */ + while ((c = fis.read()) != -1) { + System.out.print((char) c); + } + + //3.资源释放 + fis.close(); + } +} diff --git a/s_day09/src/com/inmind/input_02/Demo02.java b/s_day09/src/com/inmind/input_02/Demo02.java new file mode 100644 index 0000000..0f21978 --- /dev/null +++ b/s_day09/src/com/inmind/input_02/Demo02.java @@ -0,0 +1,52 @@ +package com.inmind.input_02; + +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.IOException; + +/* +10.使用字节输入流一次读取一个字节数组 + +int read(byte[] b) :一次最多从字节输入流中读取b的长度的字节数据,保存到数组中,返回读取到的字节的数量 + +//需求:使用字节输入流,将source.txt中的数据,一次读取一个字节数组的方法来读取打印 + */ +public class Demo02 { + public static void main(String[] args) throws IOException { + FileInputStream fis = new FileInputStream("source.txt"); + //一次读取2个字节的数据保存到数组中 + /*byte[] arr = new byte[2]; + int len = fis.read(arr); + System.out.println(len); + System.out.println(new String(arr,0,len)); + + + len = fis.read(arr); + System.out.println(len); + System.out.println(new String(arr,0,len)); + + len = fis.read(arr); + System.out.println(len); + System.out.println(new String(arr,0,len)); + + + len = fis.read(arr); + System.out.println(len); + System.out.println(new String(arr,0,len));*/ + + //使用while来优化这段代码 + byte[] arr = new byte[1024]; + int len;//用来记录读取到字节数组中,正确的字节数据的长度 + /* + ((len = fis.read(arr))!= -1)执行流程: + 1.is.read(arr) :从字节输入流中最多读取数组长度的字节数据保存在数组中,返回读取到的字节的数量 + 2.len = fis.read(arr):返回读取到的字节的数量保存到变量len中 + 3.(len = fis.read(arr))!= -1:判断是否读取到字节数据的数量,如果读取到,那么就获取多少个字节数据,如果没有-1则结束循环 + */ + while((len = fis.read(arr))!= -1){ + System.out.println(new String(arr,0,len)); + } + + fis.close(); + } +} diff --git a/s_day09/src/com/inmind/input_02/Test03.java b/s_day09/src/com/inmind/input_02/Test03.java new file mode 100644 index 0000000..d2ca65b --- /dev/null +++ b/s_day09/src/com/inmind/input_02/Test03.java @@ -0,0 +1,36 @@ +package com.inmind.input_02; + +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.FileOutputStream; +import java.io.IOException; + +/* +需求:将D:\io_test中的aa.jpg复制到bb.jpg中 + + */ +public class Test03 { + public static void main(String[] args) throws IOException { + //创建字节输入流读取源数据 + FileInputStream fis = new FileInputStream("D:\\io_test\\aa.jpg"); + //创建字节输出流写出数据到目标文件中 + FileOutputStream fos = new FileOutputStream("D:\\io_test\\cc.jpg"); + //方式一:一次读一个字节,立马写出一个字节,保证字节顺序 + /*int c;//保存读取到的字节数据 + while((c = fis.read()) != -1){ + fos.write(c); + }*/ + + //方式二:一次读一个字节数组,立马写出一个字节数组,注意一定是读几个字节,就写几个,保证字节顺序 + int len;//记录一次读取的字节数量 + byte[] buffer = new byte[1024]; + while((len = fis.read(buffer))!=-1){ + fos.write(buffer,0,len); +// fos.write(buffer); + } + + //资源释放 + fis.close(); + fos.close(); + } +} diff --git a/s_day09/src/com/inmind/io_exception_05/Demo01.java b/s_day09/src/com/inmind/io_exception_05/Demo01.java new file mode 100644 index 0000000..80008de --- /dev/null +++ b/s_day09/src/com/inmind/io_exception_05/Demo01.java @@ -0,0 +1,58 @@ +package com.inmind.io_exception_05; +/* +16.JDK7之前IO异常的处理方式(重点) + */ + +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.FileOutputStream; +import java.io.IOException; + +/* +需求:将D:\io_test中的aa.jpg复制到bb.jpg中 + + */ +public class Demo01 { + public static void main(String[] args) { + FileInputStream fis = null; + FileOutputStream fos = null; + try { + + //创建字节输入流读取源数据 + fis = new FileInputStream("D:\\io_test\\aa.jpg"); + //创建字节输出流写出数据到目标文件中 + fos = new FileOutputStream("D:\\io_test\\cc.jpg"); + + //方式二:一次读一个字节数组,立马写出一个字节数组,注意一定是读几个字节,就写几个,保证字节顺序 + int len;//记录一次读取的字节数量 + byte[] buffer = new byte[1024]; + while((len = fis.read(buffer))!=-1){ + fos.write(buffer,0,len); + } + + }catch (IOException e){ + e.printStackTrace(); + }finally { + //资源释放 + if(fis!=null){//排除空指针异常 + try { + fis.close(); + } catch (IOException e) { + throw new RuntimeException(e); + } + fis = null;//当流对象关闭,如何不设置为null,fis会引用这内存中的无用的流对象,产生内存泄漏 + } + + + if(fos!=null){ + try { + fos.close(); + } catch (IOException e) { + throw new RuntimeException(e); + } + fos = null; + } + } + } +} + diff --git a/s_day09/src/com/inmind/io_exception_05/Demo02.java b/s_day09/src/com/inmind/io_exception_05/Demo02.java new file mode 100644 index 0000000..abd0ed1 --- /dev/null +++ b/s_day09/src/com/inmind/io_exception_05/Demo02.java @@ -0,0 +1,21 @@ +package com.inmind.io_exception_05; + +import java.io.FileInputStream; +import java.io.IOException; + +/* +17.JDK7异常的处理方式 + */ +public class Demo02 { + public static void main(String[] args) { + //JDK7的语法糖,它会主动调用try()中流对象的close方法 + try (FileInputStream fis = new FileInputStream("source.txt");) { + int c;//用来保存字节输入流读取到的一个字节数据 + while ((c = fis.read()) != -1) { + System.out.print((char) c); + } + } catch (IOException e) { + e.printStackTrace(); + } + } +} diff --git a/s_day09/src/com/inmind/io_exception_05/Demo03.java b/s_day09/src/com/inmind/io_exception_05/Demo03.java new file mode 100644 index 0000000..defa287 --- /dev/null +++ b/s_day09/src/com/inmind/io_exception_05/Demo03.java @@ -0,0 +1,12 @@ +package com.inmind.io_exception_05; + +public class Demo03 { + public static void main(String[] args) { + try(Student s = new Student()){ + System.out.println("try中的代码执行了"); + }catch (Exception e) { + System.out.println("捕获了异常"); + } + System.out.println("程序结束"); + } +} diff --git a/s_day09/src/com/inmind/io_exception_05/Demo04.java b/s_day09/src/com/inmind/io_exception_05/Demo04.java new file mode 100644 index 0000000..9908c85 --- /dev/null +++ b/s_day09/src/com/inmind/io_exception_05/Demo04.java @@ -0,0 +1,25 @@ +package com.inmind.io_exception_05; + +import java.io.BufferedReader; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.IOException; + +/* +17.JDK9异常的处理方式(了解) + */ +public class Demo04 { + public static void main(String[] args) throws FileNotFoundException { + //JDK9的语法糖,它会主动调用try()中流对象的close方法 + FileInputStream fis = new FileInputStream("source.txt"); + try (fis) { + int c;//用来保存字节输入流读取到的一个字节数据 + while ((c = fis.read()) != -1) { + System.out.print((char) c); + } + } catch (IOException e) { + e.printStackTrace(); + } + + } +} diff --git a/s_day09/src/com/inmind/io_exception_05/Student.java b/s_day09/src/com/inmind/io_exception_05/Student.java new file mode 100644 index 0000000..4fe6353 --- /dev/null +++ b/s_day09/src/com/inmind/io_exception_05/Student.java @@ -0,0 +1,13 @@ +package com.inmind.io_exception_05; + +import java.io.Serializable; + +public class Student implements AutoCloseable, Serializable { + + private static final long serialVersionUID = -4320100095383836846L; + + @Override + public void close() throws Exception { + System.out.println("学生类的close方法执行了"); + } +} diff --git a/s_day09/src/com/inmind/output_01/Demo01.java b/s_day09/src/com/inmind/output_01/Demo01.java new file mode 100644 index 0000000..ce3106a --- /dev/null +++ b/s_day09/src/com/inmind/output_01/Demo01.java @@ -0,0 +1,60 @@ +package com.inmind.output_01; + +import java.io.FileNotFoundException; +import java.io.FileOutputStream; +import java.io.IOException; + +/* + IO流的分类以及所有的顶层父类 + IO流通过2种方式分类: + 1.按流向分: + 输入流 + 输出流 + 2.按传输的数据类型分: + 字节流 + 字符流 + 在java中,io流分类: + 字节输入流: InputStream + 字节输出流:OutputStream + + 字符输入流:Reader + 字符输出流:Writer + ------------------------------------------------------------------------- + 3.字节输出流的介绍以及相关的API + 在java中有一个抽象父类OutputStream表示字节输出 + 常用子类:FileOutputStream + 构造方法: + FileOutputStream(File file) 创建文件输出流以写入由指定的 File对象表示的文件。 + FileOutputStream(String name) 创建文件输出流以指定的名称写入文件。 + 常用方法: + void write(int b) 将指定的字节写入此文件输出流。 + void write(byte[] b) 将 b.length字节从指定的字节数组写入此文件输出流。 + void write(byte[] b, int off, int len) 将 len字节从指定的字节数组开始,从偏移量 off开始写入此文件输出流。 + void close() 释放任何系统资源。 + + 字节输出流的作用:将内存中的字节数据,写出到硬盘的文件中!! + 字节输出流的使用步骤: + 1.创建io流对象,传入要操作的文件 + 2.调用写方法 + 3.资源释放 + + */ +public class Demo01 { + public static void main(String[] args) throws IOException { + //1.创建io流对象,传入要操作的文件 + /* + 注意: + a.如果指定的字节输出流要操作的文件不存在,直接自动创建 + b.如果指定的字节输出流要操作的文件存在,默认会直接覆盖原本内容 + */ + FileOutputStream fos = new FileOutputStream("a.txt"); + //2.调用写方法(byte:-128~127) + //void write(int b) 将指定的字节写入此文件输出流 +// fos.write(97);//真的写出了一个字节数据,由于编辑器按照你ASCII码表来展示 + //注意:字节输出流的write,只能写字节,它有范围,如果超出byte的取值范围,发生数据强转 + //'中'%256得到1个字节内的数据,再展示 + fos.write('中'); + //3.资源释放 + fos.close(); + } +} diff --git a/s_day09/src/com/inmind/output_01/Demo02.java b/s_day09/src/com/inmind/output_01/Demo02.java new file mode 100644 index 0000000..b78faa1 --- /dev/null +++ b/s_day09/src/com/inmind/output_01/Demo02.java @@ -0,0 +1,11 @@ +package com.inmind.output_01; + +public class Demo02 { + public static void main(String[] args) { + System.out.println('中'); + System.out.println('中'+0); + System.out.println(('中'+0)%256); + System.out.println((char) 45); + + } +} diff --git a/s_day09/src/com/inmind/output_01/Demo03.java b/s_day09/src/com/inmind/output_01/Demo03.java new file mode 100644 index 0000000..401e896 --- /dev/null +++ b/s_day09/src/com/inmind/output_01/Demo03.java @@ -0,0 +1,40 @@ +package com.inmind.output_01; + +import java.util.Arrays; + +/* +5.字节数组和字符串的相互转换 + 字节数组--->字符串:构造方法 + String(byte[] bytes) 通过使用平台的默认字符集解码指定的字节数组来构造新的 String 。 + String(byte[] bytes, int offset, int length) 通过使用平台的默认字符集解码指定的字节子阵列来构造新的 String + 字符串--->字节数组:成员方法 + byte[] getBytes() 使用平台的默认字符集将该 String编码为一系列字节,将结果存储到新的字节数组中。 + + 注意: + 1.UTF-8,字母和数字只占1个字节,而一个中文占3个字节 + 2.GBK,字母和数字只占1个字节,而一个中文占2个字节 + */ +public class Demo03 { + public static void main(String[] args) { + //1.字符串转字节数组 + //定义一个String + String str = "abc"; + //获取字符串对应的字节数组 + byte[] bytes = str.getBytes(); + System.out.println(bytes.length); + System.out.println(Arrays.toString(bytes)); + + String str1 = "中国"; + byte[] bytes1 = str1.getBytes(); + System.out.println(bytes1.length); + System.out.println(Arrays.toString(bytes1)); + System.out.println("-----------------------------"); + //2.字节数组转字符串 + String newStr = new String(bytes1); + System.out.println(newStr); + //我想要一个国字 + //String(byte[] bytes, int offset, int length) + String s = new String(bytes1, 0, 3); + System.out.println(s); + } +} diff --git a/s_day09/src/com/inmind/output_01/Demo04.java b/s_day09/src/com/inmind/output_01/Demo04.java new file mode 100644 index 0000000..fe3b44f --- /dev/null +++ b/s_day09/src/com/inmind/output_01/Demo04.java @@ -0,0 +1,35 @@ +package com.inmind.output_01; + +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.FileOutputStream; +import java.io.IOException; + +/* +6.文件的续写并写出字节数组 + 续写:默认会在原本文件中的数据覆盖,但是我们想拼接输入 + 使用续写的构造方法 + 构造方法: + FileOutputStream(File file, boolean append) 创建文件输出流以写入由指定的 File对象表示的文件。 + FileOutputStream(String name, boolean append) 创建文件输出流以指定的名称写入文件。 + 传入true:继续拼接,续写 + void write(byte[] b) 将 b.length字节从指定的字节数组写入此文件输出流。 + void write(byte[] b, int off, int len) 将 len字节从指定的字节数组开始,从偏移量 off开始写入此文件输出流。 + ------------------------------------------------------------------------ + 文件的换行: + Windows:\r\n + linux:\n + mac:\r + + */ +public class Demo04 { + public static void main(String[] args) throws IOException { +// FileOutputStream fos = new FileOutputStream("a.txt",true); + FileOutputStream fos = new FileOutputStream("a.txt"); +// fos.write("我是谁我在哪我在干嘛".getBytes(),18,12); +// fos.write("我是谁\r\n我在哪\r\n我在干嘛".getBytes()); +// fos.write("我是谁\n我在哪\n我在干嘛".getBytes()); + fos.write(("我是谁"+System.lineSeparator()+"我在哪"+System.lineSeparator()+"我在干嘛").getBytes()); + fos.close(); + } +} diff --git a/s_day09/src/com/inmind/properties_06/Demo01.java b/s_day09/src/com/inmind/properties_06/Demo01.java new file mode 100644 index 0000000..8543fdd --- /dev/null +++ b/s_day09/src/com/inmind/properties_06/Demo01.java @@ -0,0 +1,39 @@ +package com.inmind.properties_06; + +import java.util.Properties; +import java.util.Set; + +/* +19.Properties 的特点与基本使用(重点) + + 构造方法 + public Properties() :创建一个空的属性列表。 + + 常用的存储方法 + public Object setProperty(String key, String value) : 保存一对属性。 + public String getProperty(String key) :使用此属性列表中指定的键搜索属性值。 + public Set stringPropertyNames() :所有键的名称的集合。 + + 注意: + 1.Properties类似一个HashMap + 2.它真正的作用,能够将指定的配置文件的信息读取到Properties的对象 + */ +public class Demo01 { + public static void main(String[] args) { + //基本操作 + Properties properties = new Properties(); + + //保存属性键值对 + properties.setProperty("username", "admin"); + properties.setProperty("password", "123456"); + System.out.println(properties); + + //获取属性值 + System.out.println(properties.getProperty("username")); + System.out.println(properties.getProperty("username1")); + + //获取属性的键值 + Set set = properties.stringPropertyNames(); + System.out.println(set); + } +} diff --git a/s_day09/src/com/inmind/properties_06/Demo02.java b/s_day09/src/com/inmind/properties_06/Demo02.java new file mode 100644 index 0000000..d5a7344 --- /dev/null +++ b/s_day09/src/com/inmind/properties_06/Demo02.java @@ -0,0 +1,26 @@ +package com.inmind.properties_06; + +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.io.InputStreamReader; +import java.util.Properties; + +/* +20.Properties与流相关的功能(从文件中读取键值对)(重点) + +void load(InputStream inStream) 从输入字节流读取属性列表(键和元素对)。 + */ +public class Demo02 { + public static void main(String[] args) throws IOException { + Properties properties = new Properties(); + //将配置文件的键值对,加载到属性集对象中 + FileInputStream fis = new FileInputStream("demo02.properties"); + InputStreamReader isr = new InputStreamReader(fis, "utf-8"); + properties.load(isr); + + System.out.println(properties); + System.out.println(properties.getProperty("classroom")); + fis.close(); + } +} diff --git a/s_day09/src/com/inmind/reader_03/Demo01.java b/s_day09/src/com/inmind/reader_03/Demo01.java new file mode 100644 index 0000000..3ad0ed4 --- /dev/null +++ b/s_day09/src/com/inmind/reader_03/Demo01.java @@ -0,0 +1,55 @@ +package com.inmind.reader_03; + +import java.io.FileNotFoundException; +import java.io.FileReader; +import java.io.IOException; + +/* +12.字符流的读取一个字符 +在java使用一个抽象父类Reader表示字符输入流 +常用子类:FileReader +构造方法: +FileReader(File file) 创建一个新的 FileReader ,给出 File读取。 +FileReader(String fileName) 创建一个新的 FileReader ,给定要读取的文件的名称。 + +常用方法: +abstract void close() 关闭资源 + +int read() 读一个字符,返回了读取到的字符数据 +int read(char[] cbuf) 将字符读入数组。 + + +使用步骤: + 1.创建对象 + 2.调用读方法 + 3.释放资源 + */ +public class Demo01 { + public static void main(String[] args) throws IOException { + //1.创建对象 + FileReader fr = new FileReader("source2.txt"); + //2.调用读方法 + /*int ch = fr.read(); + System.out.println((char) ch); + + ch = fr.read(); + System.out.println((char) ch); + + ch = fr.read(); + System.out.println((char) ch); + + ch = fr.read(); + System.out.println((char) ch); + + ch = fr.read(); + System.out.println( ch);*/ + + int ch;//用来保存字符输入流读取到的一个字符 + while((ch = fr.read())!=-1){ + System.out.print((char)ch); + } + + //3.释放资源 + fr.close(); + } +} diff --git a/s_day09/src/com/inmind/reader_03/Demo02.java b/s_day09/src/com/inmind/reader_03/Demo02.java new file mode 100644 index 0000000..67f7e49 --- /dev/null +++ b/s_day09/src/com/inmind/reader_03/Demo02.java @@ -0,0 +1,21 @@ +package com.inmind.reader_03; + +import java.io.FileNotFoundException; +import java.io.FileReader; +import java.io.IOException; + +/* +13.字符流一次读取一个字符数组 +int read(char[] cbuf) 将字符读入数组中,返回读取到的字符的个数 + */ +public class Demo02 { + public static void main(String[] args) throws IOException { + FileReader fr = new FileReader("source2.txt"); + char[] buf = new char[2]; + int len; + while((len = fr.read(buf))!=-1){ + System.out.print(new String(buf,0,len)); + } + fr.close(); + } +} diff --git a/s_day09/src/com/inmind/writer_04/Demo01.java b/s_day09/src/com/inmind/writer_04/Demo01.java new file mode 100644 index 0000000..ff96602 --- /dev/null +++ b/s_day09/src/com/inmind/writer_04/Demo01.java @@ -0,0 +1,53 @@ +package com.inmind.writer_04; + +import java.io.FileWriter; +import java.io.IOException; + +/* +14.字符输出流写数据 +在java中使用一个抽象的类Writer表示字符输出流 +常用子类:FileWriter + +构造方法: +FileWriter(File file) 给一个File对象构造一个FileWriter对象。 +FileWriter(String fileName) 构造一个给定文件名的FileWriter对象。 + +FileWriter(File file, boolean append) 给一个File对象构造一个FileWriter对象。 +FileWriter(String fileName, boolean append) 构造一个FileWriter对象,给出一个带有布尔值的文件名,表示是否附加写入的数据。 + + +常用方法: +abstract void close() 关闭资源 +abstract void flush() 刷新流。 + + +void write(char[] cbuf) 写入一个字符数组。 +abstract void write(char[] cbuf, int off, int len) 写入字符数组的一部分。 +void write(int c) 写一个字符 +void write(String str) 写一个字符串 +void write(String str, int off, int len) 写一个字符串的一部分。 + 使用步骤: + 1.创建对象 + 2.调用写方法 + 3.刷新 + 4.释放资源 + */ +public class Demo01 { + public static void main(String[] args) throws IOException { + //1.创建对象 + FileWriter fw = new FileWriter("target.txt"); + //2.调用写方法 + String s = "我是谁我在哪我在干嘛"; + fw.write(s); + //在一次输出流的操作中,多次的write操作,是拼接 + fw.write('中'); + char[] chars = {'国', '很', '美', '好'}; + fw.write(chars); + fw.write(chars,2,2);//美好 + fw.write(s,0,3);//我是谁 + + //3.刷新 + //4.释放资源 + fw.close(); + } +} diff --git a/s_day09/src/com/inmind/writer_04/Demo02.java b/s_day09/src/com/inmind/writer_04/Demo02.java new file mode 100644 index 0000000..ebc389d --- /dev/null +++ b/s_day09/src/com/inmind/writer_04/Demo02.java @@ -0,0 +1,34 @@ +package com.inmind.writer_04; + +import java.io.FileWriter; +import java.io.IOException; + +/* +15.刷新和关闭方法的区别 + +abstract void close() 关闭资源 +abstract void flush() 刷新流。 + +注意: + 1.字符输出流,数据是会保存缓冲区的,如果要及时地输出到文件中,那就需要刷新flush + 2.close()方法:释放资源之前,默认调用一次flush方法,将缓冲区中的数据刷新到硬盘上 + 3.flush()方法:将缓冲区中的数据刷新到硬盘上 + */ +public class Demo02 { + public static void main(String[] args) throws IOException { + //1.创建对象 + FileWriter fw = new FileWriter("target.txt"); + + fw.write("我是谁"); + fw.flush(); + + fw.write("我在哪"); + fw.flush(); + + fw.write("我在干嘛"); + + //当我们想将数据及时输出,但是io流还不想关闭,就调用flush + fw.close(); + + } +} diff --git a/s_day10/src/com/inmind/buffered_01/Demo01.java b/s_day10/src/com/inmind/buffered_01/Demo01.java new file mode 100644 index 0000000..d5d196d --- /dev/null +++ b/s_day10/src/com/inmind/buffered_01/Demo01.java @@ -0,0 +1,38 @@ +package com.inmind.buffered_01; + +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.FileOutputStream; +import java.io.IOException; + +/* +4个流本身没有读写功能,都是基于昨天的字节流字符流,进行读写操作,所以今天的流只要区分它的功能是什么,对应的API与昨天基本一致 + + +1.缓冲流的介绍 +缓冲流:基于字节字符流,本身本身没有读写功能,底层封装了一8192长度的缓冲区(数组),提高读写效率,也叫高效流 + +字节缓冲流: BufferedInputStream BufferedOutputStream +字符缓冲流: BufferedReader BufferedWriter + + */ +public class Demo01 { + public static void main(String[] args) throws IOException { + //需求使用昨天的字节流进行文件复制,查看复制效率,对比缓冲流的时间消耗 + //字节输入输出流一次读写一个字节查看效果 + FileInputStream fis = new FileInputStream("aa.jpg"); + FileOutputStream fos = new FileOutputStream("bb.jpg"); + + long start = System.currentTimeMillis(); + int b; + while ((b = fis.read())!=-1) { + fos.write(b); + } + + long end = System.currentTimeMillis(); + System.out.println("普通字节流一次读取一个字节消耗的时间:"+(end-start)+"毫秒"); + fis.close(); + fos.close(); + + } +} diff --git a/s_day10/src/com/inmind/buffered_01/Demo02.java b/s_day10/src/com/inmind/buffered_01/Demo02.java new file mode 100644 index 0000000..52eaf05 --- /dev/null +++ b/s_day10/src/com/inmind/buffered_01/Demo02.java @@ -0,0 +1,36 @@ +package com.inmind.buffered_01; + +import java.io.*; + +/* +3.字节缓冲流的基本使用以及使用缓冲流复制文件(一次读写一个字节) + 字节缓冲输入流:BufferedInputStream + 构造方法: + BufferedInputStream(InputStream in) 创建一个 BufferedInputStream并保存其参数,输入流 in供以后使用。 + 常用方法: + int read() :读取一个字节数据 + int read(byte[] bytes) : 读取一个字节数组 + + */ +public class Demo02 { + //使用缓冲流一次读写一个字节,复制aa.jpg + public static void main(String[] args) throws IOException { + //创建字节缓冲输入流 + BufferedInputStream bis = new BufferedInputStream(new FileInputStream("aa.jpg")); + //创建字节缓冲输出流 + BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("cc.jpg")); + + //一次读写一个字节复制 + long start = System.currentTimeMillis(); + int b; + while ((b = bis.read())!=-1) { + bos.write(b); + } + + long end = System.currentTimeMillis(); + System.out.println("字节缓冲流一次读取一个字节消耗的时间:"+(end-start)+"毫秒"); + bis.close(); + bos.close(); + } + +} diff --git a/s_day10/src/com/inmind/buffered_01/Demo03.java b/s_day10/src/com/inmind/buffered_01/Demo03.java new file mode 100644 index 0000000..0f598f7 --- /dev/null +++ b/s_day10/src/com/inmind/buffered_01/Demo03.java @@ -0,0 +1,26 @@ +package com.inmind.buffered_01; + +import java.io.*; + +/* +4.字节缓冲流一次读写一个字节数组的方式复制文件 + */ +public class Demo03 { + public static void main(String[] args) throws IOException { + //创建字节缓冲流 + BufferedInputStream bis = new BufferedInputStream(new FileInputStream("aa.jpg")); + BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("dd.jpg")); + //一次读写一个字节数组 + byte[] buf = new byte[1024]; + //int read(byte[] bytes) : 读取一个字节数组 + int len; + long start = System.currentTimeMillis(); + while ((len = bis.read(buf)) != -1) { + bos.write(buf, 0, len); + } + long end = System.currentTimeMillis(); + System.out.println("字节缓冲流一次读取一个字节1024数组消耗的时间:"+(end-start)+"毫秒"); + bis.close(); + bos.close(); + } +} diff --git a/s_day10/src/com/inmind/buffered_01/Demo04.java b/s_day10/src/com/inmind/buffered_01/Demo04.java new file mode 100644 index 0000000..e6c4910 --- /dev/null +++ b/s_day10/src/com/inmind/buffered_01/Demo04.java @@ -0,0 +1,49 @@ +package com.inmind.buffered_01; + +import java.io.*; + +/* +5.字符缓冲流的基本使用 +字符缓冲流: BufferedReader , BufferedWriter +字符缓冲输入流:BufferedReader +构造方法 +BufferedReader(Reader in) 创建使用默认大小的输入缓冲区的缓冲字符输入流。 + +常用方法: +int read() 读一个字符 +int read(char[] cbuf) 将字符读入数组。 + + +字符缓冲输出流:BufferedWriter +构造方法: +BufferedWriter(Writer out) 创建使用默认大小的输出缓冲区的缓冲字符输出流。 + +常用方法: +void write(int c) 写一个字符 +void write(char[] cbuf) 写入字符数组的一部分。 +void write(char[] cbuf, int off, int len) 写入字符数组的一部分。 +void write(String s) 写一个字符串的一部分。 +void write(String s, int off, int len) 写一个字符串的一部分。 + + */ +public class Demo04 { + public static void main(String[] args) throws IOException { + //使用字符缓冲输入流,一次读取一个字符(字符数组)读取文件 + BufferedReader br = new BufferedReader(new FileReader("dest1.txt")); + char[] buf = new char[1024]; + int len; + while ((len = br.read(buf)) != -1) { + System.out.print(new String(buf, 0, len)); + } + } + + private static void buffer_char_out() throws IOException { + //使用字符缓冲输出流,输出一些内容到文件中 + BufferedWriter bw = new BufferedWriter(new FileWriter("dest1.txt",true)); + bw.write("真的和昨天一样"); + bw.flush(); + bw.write(System.lineSeparator()+"API基本一致"); + bw.flush(); + bw.close(); + } +} diff --git a/s_day10/src/com/inmind/buffered_01/Demo05.java b/s_day10/src/com/inmind/buffered_01/Demo05.java new file mode 100644 index 0000000..fc08e16 --- /dev/null +++ b/s_day10/src/com/inmind/buffered_01/Demo05.java @@ -0,0 +1,47 @@ +package com.inmind.buffered_01; + +import java.io.*; + +/* +6.字符缓冲流中特有的功能 +BufferedWriter: newLine 它能够进行多个系统之间的换行的兼容 + +BufferedReader: readLine 它能够将文件中的内容按一行文本来读取 +String readLine() 读一行文字。 + */ +public class Demo05 { + public static void main(String[] args) throws IOException { + //使用字符缓冲输入流,一次读取一行内容 + BufferedReader br = new BufferedReader(new FileReader("dest2.txt")); + /*String line = br.readLine(); + System.out.println(line); + + line = br.readLine(); + System.out.println(line); + + line = br.readLine(); + System.out.println(line); + + line = br.readLine(); + System.out.println(line);*/ + + //使用while来优化以上代码 + String line;//定义一个字符串变量,来接收一行文本 + while((line = br.readLine())!= null){ + System.out.println(line); + } + + br.close(); + } + + private static void nextLine_demo() throws IOException { + //使用字符缓冲输出流,输出内容 + BufferedWriter bw = new BufferedWriter(new FileWriter("dest2.txt")); + bw.write("我是谁"); + bw.newLine(); + bw.write("我在哪"); + bw.newLine(); + bw.write("我在干嘛"); + bw.close(); + } +} diff --git a/s_day10/src/com/inmind/buffered_01/Test06.java b/s_day10/src/com/inmind/buffered_01/Test06.java new file mode 100644 index 0000000..eb8772d --- /dev/null +++ b/s_day10/src/com/inmind/buffered_01/Test06.java @@ -0,0 +1,41 @@ +package com.inmind.buffered_01; + +import java.io.*; +import java.util.HashMap; + +/* +使用缓冲流读取csb.txt的内容,帮我排序,重新输出给csb1.txt + +实现分析: + 1.使用字符缓冲输入流读取每行内容 + 2.每行的内容,按照.切割,左侧序号,右侧是内容,可以保存到Map(自定义类) + 3.按顺序(排序),使用字符缓冲输出流输出每行内容 + + */ +public class Test06 { + public static void main(String[] args) throws IOException { + HashMap maps = new HashMap<>(); + //1.使用字符缓冲输入流读取每行内容 + BufferedReader br = new BufferedReader(new FileReader("csb.txt")); + String line; + while ((line = br.readLine()) != null) { + //line:9.今当远离,临表涕零,不知所言。 + //2.每行的内容,按照.切割,左侧序号,右侧是内容,可以保存到Map(自定义类) + String[] strArr = line.split("\\."); + maps.put(Integer.parseInt(strArr[0]), line); + } + System.out.println(maps); + br.close(); + + //3.按顺序(排序),使用字符缓冲输出流输出每行内容 + BufferedWriter bw = new BufferedWriter(new FileWriter("csb1.txt")); + //直接遍历1~9 + for (int i = 1; i <= 9; i++) { + String s = maps.get(i); + bw.write(s); + bw.newLine(); + bw.flush(); + } + bw.close(); + } +} diff --git a/s_day10/src/com/inmind/object_03/Demo01.java b/s_day10/src/com/inmind/object_03/Demo01.java new file mode 100644 index 0000000..2a39c54 --- /dev/null +++ b/s_day10/src/com/inmind/object_03/Demo01.java @@ -0,0 +1,30 @@ +package com.inmind.object_03; + +import java.io.FileNotFoundException; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.ObjectOutputStream; + +/* +14.序列化流保存对象(ObjectOutputStream) +构造方法: + ObjectOutputStream(OutputStream out) 创建一个写入指定的OutputStream的ObjectOutputStream。 + + 常用方法: + void writeObject(Object obj) 将指定的对象写入ObjectOutputStream。 + + + */ +public class Demo01 { + public static void main(String[] args) throws IOException { + Student s = new Student("李四", 22,"3204878787787878"); + Student.classRoom = "1903"; + System.out.println(s); + //获取序列化流对象,写出对象(将对象保存到文件中) + //注意:如果要序列化对象,对应的类,必须支持序列化操作,也就是实现Serializable,类似一个标记的功能,表示可以序列化 + ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("student2.txt")); + oos.writeObject(s); + + oos.close(); + } +} diff --git a/s_day10/src/com/inmind/object_03/Demo02.java b/s_day10/src/com/inmind/object_03/Demo02.java new file mode 100644 index 0000000..547fcc9 --- /dev/null +++ b/s_day10/src/com/inmind/object_03/Demo02.java @@ -0,0 +1,33 @@ +package com.inmind.object_03; + +import java.io.*; + +/* +15.反序列化流读取对象(ObjectInputStream) +构造方法: + ObjectInputStream(InputStream in) 创建从指定的InputStream读取的ObjectInputStream。 + +常用方法: + Object readObject() 从ObjectInputStream读取一个对象。 + +注意: + 1.静态内容只跟类有关,跟对象无关,所以序列化时静态内容不能被保存的 + 2.transient表示瞬态,瞬间的值,被它修饰的成员变量,就不能序列化 + */ +public class Demo02 { + public static void main(String[] args) throws IOException, ClassNotFoundException { + //使用反序列化流读取之前保存的学生对象 + ObjectInputStream ois = new ObjectInputStream(new FileInputStream("student2.txt")); + + Object o = ois.readObject(); + + if (o instanceof Student) { + Student s = (Student) o; + System.out.println("student对象:"+s); + } + + System.out.println(o); + + ois.close(); + } +} diff --git a/s_day10/src/com/inmind/object_03/Student.java b/s_day10/src/com/inmind/object_03/Student.java new file mode 100644 index 0000000..139a2c6 --- /dev/null +++ b/s_day10/src/com/inmind/object_03/Student.java @@ -0,0 +1,38 @@ +package com.inmind.object_03; + +import java.io.Serializable; + +public class Student implements Serializable { + + private static final long serialVersionUID = 9175676844224255981L; + String name; + int age; + //transient表示瞬态,瞬间的值,不能序列化 + transient String idCard;//当一个属性既不能定义为static,也不能进行序列化操作,那就使用transient来修饰 + + static String classRoom; + + public Student(String name, int age, String idCard) { + this.name = name; + this.age = age; + this.idCard = idCard; + } + + @Override + public String toString() { + return "Student{" + + "name='" + name + '\'' + + ", age=" + age + + ", idCard=" + idCard + + ", classRoom=" + classRoom + + '}'; + } + + public void method(){ + + } + + public void method1(){ + + } +} diff --git a/s_day10/src/com/inmind/object_03/Test03.java b/s_day10/src/com/inmind/object_03/Test03.java new file mode 100644 index 0000000..ad4e630 --- /dev/null +++ b/s_day10/src/com/inmind/object_03/Test03.java @@ -0,0 +1,35 @@ +package com.inmind.object_03; + +import java.io.*; +import java.util.ArrayList; + +/* +18.序列化流的练习 + +需求: +1. 将存有多个自定义对象的集合序列化操作,保存到list.txt文件中。 +2. 反序列化list.txt ,并遍历集合,打印对象信息。 + */ +public class Test03 { + public static void main(String[] args) throws IOException, ClassNotFoundException { + ArrayList lists = new ArrayList<>(); + lists.add(new Student("李四", 22, "3204878787787878")); + lists.add(new Student("王五", 24, "3204878787787878")); + lists.add(new Student("赵六", 23, "3204878787787878")); + + ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("list.txt")); + oos.writeObject(lists); + oos.close(); + + //直接反序列化集合 + ObjectInputStream ois = new ObjectInputStream(new FileInputStream("list.txt")); + Object o = ois.readObject(); + if (o instanceof ArrayList) { + ArrayList list = (ArrayList) o; + for (Student student : list) { + System.out.println(student); + } + } + ois.close(); + } +} diff --git a/s_day10/src/com/inmind/printstream_04/Demo01.java b/s_day10/src/com/inmind/printstream_04/Demo01.java new file mode 100644 index 0000000..dc2a46d --- /dev/null +++ b/s_day10/src/com/inmind/printstream_04/Demo01.java @@ -0,0 +1,27 @@ +package com.inmind.printstream_04; + +import java.io.FileNotFoundException; +import java.io.PrintStream; + +/* +19.打印流的基本使用(PrintStream)(了解) +构造方法 +PrintStream(String fileName) 使用指定的文件名创建新的打印流,无需自动换行 + +常用方法: +print():直接输出内容,但不换行 +println():直接输出内容,但换行 + */ +public class Demo01 { + public static void main(String[] args) throws FileNotFoundException { + //往相对路径dest3.txt中打印字符串 + PrintStream ps = new PrintStream("dest4.txt"); + + /*//调用打印方法 + ps.println("你好java"); + ps.print("Hello World"); + ps.close();*/ + System.setOut(ps);//修改系统级别的打印位置 + System.out.println("这是修改了打印流位置的系统级别的打印输出"); + } +} diff --git a/s_day10/src/com/inmind/transfer_02/Demo01.java b/s_day10/src/com/inmind/transfer_02/Demo01.java new file mode 100644 index 0000000..f794d60 --- /dev/null +++ b/s_day10/src/com/inmind/transfer_02/Demo01.java @@ -0,0 +1,24 @@ +package com.inmind.transfer_02; + +import java.io.FileNotFoundException; +import java.io.FileReader; +import java.io.IOException; + +/* +8.使用FileReader读取中文产生的乱码问题 + +出现乱码的原因:中文数据在读写操作的前后的编码方式不一致 + + */ +public class Demo01 { + public static void main(String[] args) throws IOException { + //使用字符输入流,读取D:\io_test\file_gbk.txt + FileReader fr = new FileReader("D:\\io_test\\file_gbk.txt"); + char[] buf = new char[1024]; + int len; + while ((len = fr.read(buf))!=-1){ + System.out.println(new String(buf,0,len)); + } + fr.close(); + } +} diff --git a/s_day10/src/com/inmind/transfer_02/Demo02.java b/s_day10/src/com/inmind/transfer_02/Demo02.java new file mode 100644 index 0000000..49fda1b --- /dev/null +++ b/s_day10/src/com/inmind/transfer_02/Demo02.java @@ -0,0 +1,27 @@ +package com.inmind.transfer_02; +/* +9.编码表的介绍 +编码:将字符转换成字节(类似加密) +解码:将字节转换成字符(类似解密) + +编码表:将每个国家的文件和二进制对应起来 + +ASCII 使用1个字节表示字符(第一位一定是0表示正数),0~127 +ISO-8859-1 使用1个字节表示字符,包扩了ASCII的,表示拉丁,欧洲的语言,不包含中文 + +gb2312: 使用2个字节表示1个字符,7000个简体中文和符号 +big5: 使用2个字节表示繁体字,片假名 + +GBK(国标码),使用2个字节表示1个字符,涵盖2万多个中文,繁体字完全兼容ASCII + +unicode(万国码) u+0000到U+10FFFF的字符,包含110万字符,包含所有国家的文字 + +utf-8 :使用1,2,3,4个字节表示字符(3个字节表示1个中文) + +utf-16 :使用2 ,4个字节表示字符 + +utf-32 :使用4个字节表示字符,比较占用内存 + + */ +public class Demo02 { +} diff --git a/s_day10/src/com/inmind/transfer_02/Demo03.java b/s_day10/src/com/inmind/transfer_02/Demo03.java new file mode 100644 index 0000000..46eeca8 --- /dev/null +++ b/s_day10/src/com/inmind/transfer_02/Demo03.java @@ -0,0 +1,48 @@ +package com.inmind.transfer_02; + +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.io.InputStreamReader; + +/* +10.转换流_指定编码读取(InputStreamReader) +InputStreamReader是从字节流到字符流的桥梁:解码 + +构造方法: + InputStreamReader(InputStream in) 创建一个使用默认字符集的InputStreamReader。 + InputStreamReader(InputStream in, String charsetName) 创建一个使用命名字符集的InputStreamReader。 + +常用方法: + close() + int read(); + int read(char[] chars) + + */ +public class Demo03 { + public static void main(String[] args) throws IOException { + //使用转换输入流,读取D:\io_test\file_utf8.txt + FileInputStream fis = new FileInputStream("D:\\io_test\\file_utf8.txt"); +// InputStreamReader isr = new InputStreamReader(fis,"utf-8");//指定utf-8 + InputStreamReader isr = new InputStreamReader(fis); + char[] buf = new char[1024]; + int len = 0; + while ((len = isr.read(buf)) != -1) { + System.out.println(new String(buf, 0, len)); + } + isr.close(); + } + + private static void read_gbk() throws IOException { + //使用转换输入流,读取D:\io_test\file_gbk.txt +// InputStreamReader isr = new InputStreamReader(new FileInputStream("D:\\io_test\\file_gbk.txt"));//默认utf-8 + FileInputStream fis = new FileInputStream("D:\\io_test\\file_gbk.txt"); + InputStreamReader isr = new InputStreamReader(fis,"GBK");//指定GBK + char[] buf = new char[1024]; + int len = 0; + while ((len = isr.read(buf)) != -1) { + System.out.println(new String(buf, 0, len)); + } + isr.close(); + } +} diff --git a/s_day10/src/com/inmind/transfer_02/Demo04.java b/s_day10/src/com/inmind/transfer_02/Demo04.java new file mode 100644 index 0000000..4ebeeec --- /dev/null +++ b/s_day10/src/com/inmind/transfer_02/Demo04.java @@ -0,0 +1,41 @@ +package com.inmind.transfer_02; + +import java.io.*; +import java.nio.charset.Charset; + +/* +11.转换流_按照指定编码写数据(OutputStreamWriter) +OutputStreamWriter是从字符流到字节流的桥梁: 编码 + +构造方法: + OutputStreamWriter(OutputStream out) 创建一个使用默认字符编码的OutputStreamWriter。 + OutputStreamWriter(OutputStream out, String charsetName) 创建一个使用命名字符集的OutputStreamWriter。 + +常用方法: + close + flush + 5个写方法 + + + */ +public class Demo04 { + public static void main(String[] args) throws IOException { + //使用转换输出流,指定utf-8编码方式输出内容到文件中 + FileOutputStream fos = new FileOutputStream("D:\\io_test\\file_utf8_3.txt"); +// OutputStreamWriter osw = new OutputStreamWriter(fos, "utf-8"); + OutputStreamWriter osw = new OutputStreamWriter(fos);//不指定具体的编码方式,采用默认 + osw.write("中国"); + osw.flush(); + osw.close(); + + } + + private static void write_gbk() throws IOException { + ////使用转换输出流,指定GBK编码方式输出内容到文件中 + FileOutputStream fos = new FileOutputStream("D:\\io_test\\file_3.txt"); + OutputStreamWriter osw = new OutputStreamWriter(fos, "GBK"); + osw.write("好的"); + osw.flush(); + osw.close(); + } +} diff --git a/s_day11/src/com/inmind/circle_upload_05/UploadClientDemo01.java b/s_day11/src/com/inmind/circle_upload_05/UploadClientDemo01.java new file mode 100644 index 0000000..2f29751 --- /dev/null +++ b/s_day11/src/com/inmind/circle_upload_05/UploadClientDemo01.java @@ -0,0 +1,45 @@ +package com.inmind.circle_upload_05; + +import java.io.FileInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.net.Socket; + +/* +文件上传客户端的实现步骤: +1.创建字节输入流读取图片的字节数据 +2.创建客户端对象指定服务器的IP和端口 +3.获取客户端的字节输出流,将图片的字节数据边读边写,作为请求数据,发送给服务器 +4.获取客户端的字节输入流,接收服务器的响应数据 +5.资源释放 + */ +public class UploadClientDemo01 { + public static void main(String[] args) throws IOException { + //1.创建字节输入流读取图片的字节数据 + FileInputStream fis = new FileInputStream("aa.jpg"); + + //2.创建客户端对象指定服务器的IP和端口 + Socket socket = new Socket("192.168.23.34", 10086); + + OutputStream os = socket.getOutputStream();//发送请求数据 + byte[] buf = new byte[1024]; + int len; + + //3.获取客户端的字节输出流,将图片的字节数据边读边写,作为请求数据,发送给服务器 + while ((len = fis.read(buf)) != -1) { + os.write(buf, 0, len); + } + System.out.println("客户端上传了图片"); + socket.shutdownOutput();//设置请求数据的结束标记 + + //4.获取客户端的字节输入流,接收服务器的响应数据 + InputStream is = socket.getInputStream(); + while ((len = is.read(buf)) != -1) { + System.out.println(new String(buf, 0, len)); + } + System.out.println("客户端接收到了响应的结果"); + //5.资源释放 + socket.close(); + } +} diff --git a/s_day11/src/com/inmind/circle_upload_05/UploadServerDemo02.java b/s_day11/src/com/inmind/circle_upload_05/UploadServerDemo02.java new file mode 100644 index 0000000..275361b --- /dev/null +++ b/s_day11/src/com/inmind/circle_upload_05/UploadServerDemo02.java @@ -0,0 +1,48 @@ +package com.inmind.circle_upload_05; + + +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.net.ServerSocket; +import java.net.Socket; + +/* + 文件上传的服务端的实现步骤: + 1.创建一个服务端对象,接收请求 + 2.获取客户端socket对象的字节输入流,接收请求数据(图片字节数据) + 3.创建字节输出流,边读边写到硬盘中 + 4.获取客户端的socket对象字节输出流,发送响应数据(上传成功) + 5.资源释放 + */ +public class UploadServerDemo02 { + public static void main(String[] args) throws IOException { + //1.创建一个服务端对象,接收请求 + ServerSocket serverSocket = new ServerSocket(10086); + System.out.println("服务器启动了"); + while (true) { + Socket clientSocket = serverSocket.accept();//接收对应的客户端的请求,客户端有很多 + System.out.println(clientSocket.getInetAddress().getHostAddress()); + + //2.获取客户端socket对象的字节输入流,接收请求数据(图片字节数据) + InputStream is = clientSocket.getInputStream(); + byte[] buffer = new byte[1024]; + int len; + //3.创建字节输出流,边读边写到硬盘中 + FileOutputStream fos = new FileOutputStream("D:\\io_test\\upload\\"+System.currentTimeMillis()+".jpg"); + while ((len = is.read(buffer)) != -1) { + fos.write(buffer, 0, len); + } + fos.close(); + System.out.println("服务器保存了上传的图片"); + //4.获取客户端的socket对象字节输出流,发送响应数据(上传成功) + OutputStream os = clientSocket.getOutputStream(); + os.write("上传成功".getBytes()); + System.out.println("服务器响应了结果给客户端"); + //5.资源释放 + clientSocket.close(); +// serverSocket.close();//注意:服务器不应该停止,得不断接收请求 + } + } +} diff --git a/s_day11/src/com/inmind/lambda_upload_07/UploadServerDemo02.java b/s_day11/src/com/inmind/lambda_upload_07/UploadServerDemo02.java new file mode 100644 index 0000000..65224cc --- /dev/null +++ b/s_day11/src/com/inmind/lambda_upload_07/UploadServerDemo02.java @@ -0,0 +1,68 @@ +package com.inmind.lambda_upload_07; + + +import com.inmind.thread_upload_06.UploadTask; + +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.net.ServerSocket; +import java.net.Socket; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; + +/* +多线程的启动方式: +1.继承Thread +2.实现Runnable +3.线程池 + */ +public class UploadServerDemo02 { + public static void main(String[] args) throws IOException { + //1.创建一个服务端对象,接收请求 + ServerSocket serverSocket = new ServerSocket(10086); + //使用线程池进行上传的优化 + ExecutorService executorService = Executors.newFixedThreadPool(5); + System.out.println("服务器启动了"); + while (true) { + final Socket clientSocket = serverSocket.accept();//接收对应的客户端的请求,客户端有很多 + //new Thread(new UploadTask(clientSocket)).start(); + executorService.execute(()->{ + + try { + //接收到一个客户端请求,就执行该客户端相关的操作 + System.out.println(clientSocket.getInetAddress().getHostAddress()); + + //2.获取客户端socket对象的字节输入流,接收请求数据(图片字节数据) + InputStream is = clientSocket.getInputStream(); + byte[] buffer = new byte[1024]; + int len; + //3.创建字节输出流,边读边写到硬盘中 + FileOutputStream fos = new FileOutputStream("D:\\io_test\\upload\\"+System.currentTimeMillis()+".jpg"); + while ((len = is.read(buffer)) != -1) { + fos.write(buffer, 0, len); + } + fos.close(); + System.out.println("服务器保存了上传的图片"); + //4.获取客户端的socket对象字节输出流,发送响应数据(上传成功) + OutputStream os = clientSocket.getOutputStream(); + os.write("上传成功".getBytes()); + System.out.println("服务器响应了结果给客户端"); + } catch (IOException e) { + throw new RuntimeException(e); + } finally { + //5.资源释放 + if (clientSocket != null) { + try { + clientSocket.close(); + } catch (IOException e) { + throw new RuntimeException(e); + } +// clientSocket = null; + } + } + }); + } + } +} diff --git a/s_day11/src/com/inmind/tcp_03/TcpClientDemo01.java b/s_day11/src/com/inmind/tcp_03/TcpClientDemo01.java new file mode 100644 index 0000000..590811f --- /dev/null +++ b/s_day11/src/com/inmind/tcp_03/TcpClientDemo01.java @@ -0,0 +1,52 @@ +package com.inmind.tcp_03; + +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.net.Socket; + +/* + 在java中使用一个类Socket表示客户端 + 构造方法: + Socket(String host, int port) 创建流套接字并将其连接到指定主机上的指定端口号。 + + 常用方法: + void close() 关闭此套接字。 + InetAddress getInetAddress() 返回套接字所连接的地址。 + InputStream getInputStream() 返回此套接字的输入流.(接收响应数据的) + OutputStream getOutputStream() 返回此套接字的输出流。 (发送请求) + void shutdownOutput() 禁用此套接字的输出流 (设置了一个发送请求数据的结束标记) + + +客户端的实现步骤: + 1.创建客户端对象 + 2.获取字节输出流,发送请求数据 + 3.获取字节输入流,接收响应数据 + 4.释放资源 + +需求:实现TCP的一发一收功能 + + */ +public class TcpClientDemo01 { + public static void main(String[] args) throws IOException { + //1.创建客户端对象 + //Socket(String host, int port) 创建流套接字并将其连接到指定主机上的指定端口号。 + Socket socket = new Socket("192.168.23.34", 10000); + //2.获取字节输出流,发送请求数据 + OutputStream os = socket.getOutputStream(); + os.write("淘宝的官网".getBytes()); + + //当发送完毕请求数据,要设置结束的标记 + socket.shutdownOutput(); + + //3.获取字节输入流,接收响应数据 + InputStream is = socket.getInputStream(); + byte[] buffer = new byte[1024]; + int len; + while ((len = is.read(buffer)) != -1){ + System.out.println(new String(buffer,0,len)); + } + //4.释放资源 + socket.close(); + } +} diff --git a/s_day11/src/com/inmind/tcp_03/TcpServerDemo02.java b/s_day11/src/com/inmind/tcp_03/TcpServerDemo02.java new file mode 100644 index 0000000..7f850fb --- /dev/null +++ b/s_day11/src/com/inmind/tcp_03/TcpServerDemo02.java @@ -0,0 +1,58 @@ +package com.inmind.tcp_03; + +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.net.ServerSocket; +import java.net.Socket; + +/* +在java中使用一个类表示服务端ServerSocket +构造方法: +ServerSocket(int port) 创建绑定到指定端口的服务器套接字。 + +常用方法: +Socket accept() 侦听要连接到客户端请求并接受它。 + void close() 关闭此套接字。 + InetAddress getInetAddress() 返回套接字所连接的地址。 + InputStream getInputStream() 返回此套接字的输入流.(接收响应数据的) + OutputStream getOutputStream() 返回此套接字的输出流。 (发送请求) + void shutdownOutput() 禁用此套接字的输出流 (设置了一个发送请求数据的结束标记) +void close() 关闭此套接字。 + +服务器实现步骤: +1.创建服务器对象 +2.接收客户端请求 +3.获取请求数据 +4.业务逻辑代码 +5.发送响应数据 +6.释放资源 + */ +public class TcpServerDemo02 { + public static void main(String[] args) throws IOException { + //1.创建服务器对象 + //ServerSocket(int port) 创建绑定到指定端口的服务器套接字。 + ServerSocket serverSocket = new ServerSocket(10000); + System.out.println("服务器启动了"); + //2.接收客户端请求 + Socket clientSocket = serverSocket.accept();//阻塞方法 + //3.获取请求数据 + InputStream is = clientSocket.getInputStream(); + byte[] buffer = new byte[1024]; + int len; + while ((len = is.read(buffer)) != -1) { + System.out.println(new String(buffer, 0, len)); + } + + //4.业务逻辑代码 + String result = "www.taobao.com"; + + //5.发送响应数据 + OutputStream os = clientSocket.getOutputStream(); + os.write(result.getBytes()); + + //6.释放资源 + clientSocket.close(); + serverSocket.close(); + } +} diff --git a/s_day11/src/com/inmind/test_09/ChatClient.java b/s_day11/src/com/inmind/test_09/ChatClient.java new file mode 100644 index 0000000..5b43e3c --- /dev/null +++ b/s_day11/src/com/inmind/test_09/ChatClient.java @@ -0,0 +1,120 @@ +package com.inmind.test_09; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStreamReader; +import java.io.PrintWriter; +import java.net.Socket; + +/* +多人实时聊天系统业务需求 +一、系统概述 +本系统旨在实现一个基于 Java Socket 技术的多人实时聊天系统,支持多个客户端通过网络连接到同一台服务器,实现消息的实时发送与接收,满足用户间的即时文字交流需求。 + +二、核心功能需求 +1. 客户端功能 +用户身份标识:客户端启动时,需提示用户输入用户名;若用户未输入或输入为空,系统自动为其分配 “匿名用户” 身份。 +服务器连接:默认连接本地(localhost)端口为 12345 的聊天服务器,连接成功后提示用户可开始聊天。 +消息发送:用户可通过控制台输入文字消息,输入后系统自动将消息发送至服务器;支持输入 “exit”(不区分大小写)主动退出聊天。 +消息接收:实时接收服务器广播的所有消息(包括其他用户发送的消息、用户加入 / 离开通知等),并在控制台展示。 + + + */ +public class ChatClient { + private String serverAddress;//服务器地址 + private int serverPort;//服务器端口号 + private String username;//客户端用户名 + + public ChatClient(String serverAddress, int serverPort, String username) { + this.serverAddress = serverAddress; + this.serverPort = serverPort; + this.username = username; + } + + //定义一个方法,开始聊天 + public void startChat(){ + //创建客户端 + try (Socket socket = new Socket(serverAddress, serverPort)) { + //初始化输入流,用于读取服务器发送的消息 + BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream())); + //初始化输出流,用于向服务器发送消息 + PrintWriter out = new PrintWriter(socket.getOutputStream(), true); + + //发送用户名到服务器 + out.println(username); + + //启动接收消息的线程(子线程不断接收消息,展示到控制) + new Thread(new ReceiveHandler(in)).start(); + + //读取控制台输入的流 + BufferedReader consoleIn = new BufferedReader(new InputStreamReader(System.in)); + + String input;//用户输入的内容 + while ((input = consoleIn.readLine()) != null) { + out.println(input); + + //如果输入了"exit",退出聊天 + if ("exit".equals(input)) { + break; + } + } + + consoleIn.close(); + in.close(); + out.close(); + }catch (Exception e){ + e.printStackTrace(); + } + } + + //成员内部类,定义接收服务器的消息的线程类 + private class ReceiveHandler implements Runnable{ + private BufferedReader in; + + public ReceiveHandler(BufferedReader in) { + this.in = in; + } + + @Override + public void run() { + try { + String message;//用来接收服务器响应的数据 + while ((message = in.readLine()) != null) { + System.out.println(message); + } + } catch (IOException e) { + e.printStackTrace(); + } + } + } + + + //客户端主方法 + public static void main(String[] args) { + //默认连接本机 +// String serverAddress = "127.0.0.1"; + String serverAddress = "localhost"; + int serverPort = 12345; + + //获取用户输入的用户名 + System.out.println("请输入用户名,连接服务器,进行多人聊天"); + BufferedReader consoleIn = new BufferedReader(new InputStreamReader(System.in)); + try { + String username = consoleIn.readLine(); + if (username == null || username.trim().isEmpty()) { + username = "匿名用户"; + } + + System.out.println("连接到服务器"); + //创建客户端对象,启动聊天 + ChatClient chatClient = new ChatClient(serverAddress, serverPort, username); + System.out.println("连接成功!输入消息开始聊天,输入exit退出。"); + chatClient.startChat(); + } catch (IOException e) { + System.out.println("获取用户名失败!!!"); + } + + + } + +} diff --git a/s_day11/src/com/inmind/test_09/ChatServer.java b/s_day11/src/com/inmind/test_09/ChatServer.java new file mode 100644 index 0000000..c0e1d64 --- /dev/null +++ b/s_day11/src/com/inmind/test_09/ChatServer.java @@ -0,0 +1,111 @@ +package com.inmind.test_09; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStreamReader; +import java.io.PrintWriter; +import java.net.ServerSocket; +import java.net.Socket; +import java.util.HashSet; +import java.util.Set; + +/* +2. 服务器功能 +端口监听:服务器启动后,持续监听 12345 端口,等待客户端连接。 +客户端管理:支持多客户端同时连接,维护所有在线客户端的输出流集合,用于消息广播。 +消息广播:接收任意客户端发送的消息后,立即向所有在线客户端(包括发送者)广播该消息(格式为 “用户名:消息内容”)。 +状态通知:当有新用户加入聊天时,向所有在线客户端广播 “用户名 加入了聊天!”;当用户退出聊天时,广播 “用户名 离开了聊天!”。 +资源清理:用户退出后,自动从客户端集合中移除其输出流,并关闭对应的客户端连接,释放资源。 + + */ +public class ChatServer { + private static final int PORT = 12345; + //存储所有客户端输出流的集合,用于广播消息 + private static Set clientWriters = new HashSet<>(); + + public static void main(String[] args) { + System.out.println("多人聊天服务器启动,监听端口:"+PORT); + + try (ServerSocket serverSocket = new ServerSocket(PORT)) { + while (true) { + Socket clientSocket = serverSocket.accept(); + System.out.println("新客户端连接:"+clientSocket); + + //创建printWriter用于向客户端发送消息 + PrintWriter out = new PrintWriter(clientSocket.getOutputStream(), true); + + clientWriters.add(out);//保存了每个客户端的响应输出流 + + //为每个客户端开启一个新的线程,接收客户端的消息,广播给所有的客户端 + new Thread(new ClientHanlder(clientSocket,out)).start(); + + } + + + } catch (Exception e) { + throw new RuntimeException(e); + } + } + + //客户端处理线程,负责接收客户端的消息,广播给所有的客户端 + private static class ClientHanlder implements Runnable { + private Socket clientSocket;//客户端socket + private PrintWriter out;//直接向客户端输出消息 + private String username;//客户端的用户名 + + public ClientHanlder(Socket clientSocket, PrintWriter out) { + this.clientSocket = clientSocket; + this.out = out; + } + + @Override + public void run() { + try { + //读取客户端发送的数据 + BufferedReader in = new BufferedReader(new InputStreamReader(clientSocket.getInputStream())); + + //读取客户端的用户名 + String username = in.readLine(); + System.out.println(username+"用户,加入了聊天"); + //广播新用户加入聊天 + broadcastMsg(username+"用户,加入了聊天"); + //循环读取客户端发送的消息 + String input; + while ((input = in.readLine()) != null) { + //如果用户输入exit,退出循环,结束聊天线程 + if ("exit".equals(input)) { + break; + } + //广播用户发送的消息 + broadcastMsg(username+":"+input); + } + + //用户退出时处理 + System.out.println(username+",离开了聊天"); + broadcastMsg(username+",离开了聊天!!!"); + } catch (IOException e) { + System.out.println("通信错误"); + } finally { + clientWriters.remove(out);//用户退出,对应的客户端的响应输出流也要删除 + //资源释放 + if (clientSocket != null) { + try { + clientSocket.close(); + } catch (IOException e) { + throw new RuntimeException(e); + } + } + } + + + } + + //遍历每个客户端,打印输出消息 + private void broadcastMsg(String msg) { + for (PrintWriter clientWriter : clientWriters) { + clientWriter.println(msg); + } + } + } + +} diff --git a/s_day11/src/com/inmind/thread_upload_06/UploadClientDemo01.java b/s_day11/src/com/inmind/thread_upload_06/UploadClientDemo01.java new file mode 100644 index 0000000..287bfb7 --- /dev/null +++ b/s_day11/src/com/inmind/thread_upload_06/UploadClientDemo01.java @@ -0,0 +1,45 @@ +package com.inmind.thread_upload_06; + +import java.io.FileInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.net.Socket; + +/* +文件上传客户端的实现步骤: +1.创建字节输入流读取图片的字节数据 +2.创建客户端对象指定服务器的IP和端口 +3.获取客户端的字节输出流,将图片的字节数据边读边写,作为请求数据,发送给服务器 +4.获取客户端的字节输入流,接收服务器的响应数据 +5.资源释放 + */ +public class UploadClientDemo01 { + public static void main(String[] args) throws IOException { + //1.创建字节输入流读取图片的字节数据 + FileInputStream fis = new FileInputStream("aa.jpg"); + + //2.创建客户端对象指定服务器的IP和端口 + Socket socket = new Socket("192.168.23.34", 10086); + + OutputStream os = socket.getOutputStream();//发送请求数据 + byte[] buf = new byte[1024]; + int len; + + //3.获取客户端的字节输出流,将图片的字节数据边读边写,作为请求数据,发送给服务器 + while ((len = fis.read(buf)) != -1) { + os.write(buf, 0, len); + } + System.out.println("客户端上传了图片"); + socket.shutdownOutput();//设置请求数据的结束标记 + + //4.获取客户端的字节输入流,接收服务器的响应数据 + InputStream is = socket.getInputStream(); + while ((len = is.read(buf)) != -1) { + System.out.println(new String(buf, 0, len)); + } + System.out.println("客户端接收到了响应的结果"); + //5.资源释放 + socket.close(); + } +} diff --git a/s_day11/src/com/inmind/thread_upload_06/UploadServerDemo02.java b/s_day11/src/com/inmind/thread_upload_06/UploadServerDemo02.java new file mode 100644 index 0000000..2ddc7db --- /dev/null +++ b/s_day11/src/com/inmind/thread_upload_06/UploadServerDemo02.java @@ -0,0 +1,32 @@ +package com.inmind.thread_upload_06; + + +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.net.ServerSocket; +import java.net.Socket; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; + +/* +多线程的启动方式: +1.继承Thread +2.实现Runnable +3.线程池 + */ +public class UploadServerDemo02 { + public static void main(String[] args) throws IOException { + //1.创建一个服务端对象,接收请求 + ServerSocket serverSocket = new ServerSocket(10086); + //使用线程池进行上传的优化 + ExecutorService executorService = Executors.newFixedThreadPool(5); + System.out.println("服务器启动了"); + while (true) { + Socket clientSocket = serverSocket.accept();//接收对应的客户端的请求,客户端有很多 + //new Thread(new UploadTask(clientSocket)).start(); + executorService.execute(new UploadTask(clientSocket)); + } + } +} diff --git a/s_day11/src/com/inmind/thread_upload_06/UploadTask.java b/s_day11/src/com/inmind/thread_upload_06/UploadTask.java new file mode 100644 index 0000000..5263278 --- /dev/null +++ b/s_day11/src/com/inmind/thread_upload_06/UploadTask.java @@ -0,0 +1,51 @@ +package com.inmind.thread_upload_06; + +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.net.Socket; + +public class UploadTask implements Runnable { + private Socket clientSocket; + + public UploadTask(Socket clientSocket) { + this.clientSocket = clientSocket; + } + + @Override + public void run() { + try { + //接收到一个客户端请求,就执行该客户端相关的操作 + System.out.println(clientSocket.getInetAddress().getHostAddress()); + + //2.获取客户端socket对象的字节输入流,接收请求数据(图片字节数据) + InputStream is = clientSocket.getInputStream(); + byte[] buffer = new byte[1024]; + int len; + //3.创建字节输出流,边读边写到硬盘中 + FileOutputStream fos = new FileOutputStream("D:\\io_test\\upload\\"+System.currentTimeMillis()+".jpg"); + while ((len = is.read(buffer)) != -1) { + fos.write(buffer, 0, len); + } + fos.close(); + System.out.println("服务器保存了上传的图片"); + //4.获取客户端的socket对象字节输出流,发送响应数据(上传成功) + OutputStream os = clientSocket.getOutputStream(); + os.write("上传成功".getBytes()); + System.out.println("服务器响应了结果给客户端"); + } catch (IOException e) { + throw new RuntimeException(e); + } finally { + //5.资源释放 + if (clientSocket != null) { + try { + clientSocket.close(); + } catch (IOException e) { + throw new RuntimeException(e); + } + clientSocket = null; + } + } + } +} diff --git a/s_day11/src/com/inmind/udp_01/ClientDemo01.java b/s_day11/src/com/inmind/udp_01/ClientDemo01.java new file mode 100644 index 0000000..7f1df41 --- /dev/null +++ b/s_day11/src/com/inmind/udp_01/ClientDemo01.java @@ -0,0 +1,44 @@ +package com.inmind.udp_01; + +import java.io.IOException; +import java.net.*; + +/* +在java中使用DatagramSocket来表示UDP的客户端和服务端 +构造方法 +DatagramSocket() 创建客户端的Socket对象,系统会随机分配一个端口号。 +DatagramSocket(int port) 创建服务端的Socket对象,并指定端口号。 + +常用方法: +void send(DatagramPacket p) 发送数据包 +void receive(DatagramPacket p) 使用数据包接收数据 + +DatagramPacket :数据包 +DatagramPacket(byte[] buf, int length, InetAddress address, int port) 创建发出去的数据包对象 +DatagramPacket(byte[] buf, int length) 创建接收数据的数据包对象 +int getLength() 返回要发送的数据的长度或接收到的数据的长度 + +需求:使用UDP实现快速通信,实现1发1收 + */ +public class ClientDemo01 { + public static void main(String[] args) throws IOException { + //1.创建客户端对象(丢飞饼人) + DatagramSocket socket = new DatagramSocket();//随机分配端口 + + //2.创建数据包对象,封装要发出去的数据(创建一个飞饼) + /* + DatagramPacket(byte[] buf, int length, InetAddress address, int port) 创建发出去的数据包对象 + 参数一:封装要发出去的数据的字节数组 + 参数二:发送出去的字节数 + 参数三:服务端的IP地址(找到服务器) + 参数四:服务端的程序的端口号 + */ + byte[] bytes = "我爱java,java爱我".getBytes(); + DatagramPacket packet = new DatagramPacket(bytes, bytes.length, InetAddress.getLocalHost(), 10022); + + //3.客户端正式发送这个数据包出去 + socket.send(packet); + System.out.println("客户端数据发送完毕~~~"); + socket.close(); + } +} diff --git a/s_day11/src/com/inmind/udp_01/ServerDemo02.java b/s_day11/src/com/inmind/udp_01/ServerDemo02.java new file mode 100644 index 0000000..5f2d65b --- /dev/null +++ b/s_day11/src/com/inmind/udp_01/ServerDemo02.java @@ -0,0 +1,48 @@ +package com.inmind.udp_01; + +import java.io.IOException; +import java.net.DatagramPacket; +import java.net.DatagramSocket; +import java.net.SocketException; + +/* +作为UDP服务端,接收客户端发送的数据 + +在java中使用DatagramSocket来表示UDP的客户端和服务端 +构造方法 +DatagramSocket(int port) 创建服务端的Socket对象,并指定端口号。 + +常用方法: +void receive(DatagramPacket p) 使用数据包接收数据 + +DatagramPacket :数据包 +DatagramPacket(byte[] buf, int length) 创建接收数据的数据包对象 +int getLength() 返回要发送的数据的长度或接收到的数据的长度 + +需求:创建服务器,接收客户端的数据 + */ +public class ServerDemo02 { + public static void main(String[] args) throws IOException { + System.out.println("服务端启动了"); + + //1.创建服务端的对象 + DatagramSocket socket = new DatagramSocket(10022); + //2.创建出一个数据包对象,用于接收数据(飞饼) + //DatagramPacket(byte[] buf, int length) 创建接收数据的数据包对象 + byte[] buf = new byte[1024*64]; + DatagramPacket packet = new DatagramPacket(buf, buf.length); + + //3.服务器开始正式使用数据包,接收客户端发来的数据 + socket.receive(packet);//阻塞功能,接收数据 + + //4.从字节数组中,把接收到的数据直接打印展示(接收多少就打印多少数据) + int dataLength = packet.getLength(); + String result = new String(buf, 0, dataLength); + //获取数据包的ip地址,和端口号 + System.out.println(packet.getPort()); + System.out.println(packet.getAddress().getHostAddress()); + + System.out.println(result); + socket.close(); + } +} diff --git a/s_day11/src/com/inmind/udps_02/ClientDemo01.java b/s_day11/src/com/inmind/udps_02/ClientDemo01.java new file mode 100644 index 0000000..ee6aa2f --- /dev/null +++ b/s_day11/src/com/inmind/udps_02/ClientDemo01.java @@ -0,0 +1,50 @@ +package com.inmind.udps_02; + +import java.io.IOException; +import java.net.DatagramPacket; +import java.net.DatagramSocket; +import java.net.InetAddress; +import java.util.Scanner; + +/* + +需求:使用UDP实现快速通信,实现多发多收 + */ +public class ClientDemo01 { + public static void main(String[] args) throws IOException { + //1.创建客户端对象(丢飞饼人) + DatagramSocket socket = new DatagramSocket();//随机分配端口 + + //增加一个sc对象,手动输入要发送的数据 + Scanner sc = new Scanner(System.in); + + while (true) { + System.out.println("请输入要发送的内容:"); + String msg = sc.nextLine(); + + //如果输入exit,表示程序退出 + if ("exit".equals(msg)) { + System.out.println("谢谢使用,退出成功!!"); + socket.close(); + break; + } + + //2.创建数据包对象,封装要发出去的数据(创建一个飞饼) + /* + DatagramPacket(byte[] buf, int length, InetAddress address, int port) 创建发出去的数据包对象 + 参数一:封装要发出去的数据的字节数组 + 参数二:发送出去的字节数 + 参数三:服务端的IP地址(找到服务器) + 参数四:服务端的程序的端口号 + */ + byte[] bytes = msg.getBytes(); +// DatagramPacket packet = new DatagramPacket(bytes, bytes.length, InetAddress.getLocalHost(), 10022); + //static InetAddress getByName(String host) 确定主机名称的IP地址。 + DatagramPacket packet = new DatagramPacket(bytes, bytes.length, InetAddress.getByName("192.168.23.34"), 10022); + + //3.客户端正式发送这个数据包出去 + socket.send(packet); + + } + } +} diff --git a/s_day11/src/com/inmind/udps_02/ServerDemo02.java b/s_day11/src/com/inmind/udps_02/ServerDemo02.java new file mode 100644 index 0000000..758b8aa --- /dev/null +++ b/s_day11/src/com/inmind/udps_02/ServerDemo02.java @@ -0,0 +1,49 @@ +package com.inmind.udps_02; + +import java.io.IOException; +import java.net.DatagramPacket; +import java.net.DatagramSocket; + +/* +作为UDP服务端,接收客户端发送的数据 + +在java中使用DatagramSocket来表示UDP的客户端和服务端 +构造方法 +DatagramSocket(int port) 创建服务端的Socket对象,并指定端口号。 + +常用方法: +void receive(DatagramPacket p) 使用数据包接收数据 + +DatagramPacket :数据包 +DatagramPacket(byte[] buf, int length) 创建接收数据的数据包对象 +int getLength() 返回要发送的数据的长度或接收到的数据的长度 + +需求:创建服务器,接收客户端的数据 + */ +public class ServerDemo02 { + public static void main(String[] args) throws IOException { + System.out.println("服务端启动了"); + + //1.创建服务端的对象 + DatagramSocket socket = new DatagramSocket(10022); + //2.创建出一个数据包对象,用于接收数据(飞饼) + //DatagramPacket(byte[] buf, int length) 创建接收数据的数据包对象 + byte[] buf = new byte[1024*64]; + while (true) { + DatagramPacket packet = new DatagramPacket(buf, buf.length); + + //3.服务器开始正式使用数据包,接收客户端发来的数据 + socket.receive(packet);//阻塞功能,接收数据 + + //4.从字节数组中,把接收到的数据直接打印展示(接收多少就打印多少数据) + int dataLength = packet.getLength(); + String result = new String(buf, 0, dataLength); + //获取数据包的ip地址,和端口号 + System.out.println(packet.getPort()); + System.out.println(packet.getAddress().getHostAddress()); + + System.out.println(result); + } +// socket.close(); + } +} diff --git a/s_day11/src/com/inmind/upload_04/UploadClientDemo01.java b/s_day11/src/com/inmind/upload_04/UploadClientDemo01.java new file mode 100644 index 0000000..d96518d --- /dev/null +++ b/s_day11/src/com/inmind/upload_04/UploadClientDemo01.java @@ -0,0 +1,42 @@ +package com.inmind.upload_04; + +import java.io.*; +import java.net.Socket; + +/* +文件上传客户端的实现步骤: +1.创建字节输入流读取图片的字节数据 +2.创建客户端对象指定服务器的IP和端口 +3.获取客户端的字节输出流,将图片的字节数据边读边写,作为请求数据,发送给服务器 +4.获取客户端的字节输入流,接收服务器的响应数据 +5.资源释放 + */ +public class UploadClientDemo01 { + public static void main(String[] args) throws IOException { + //1.创建字节输入流读取图片的字节数据 + FileInputStream fis = new FileInputStream("aa.jpg"); + + //2.创建客户端对象指定服务器的IP和端口 + Socket socket = new Socket("192.168.23.34", 10086); + + OutputStream os = socket.getOutputStream();//发送请求数据 + byte[] buf = new byte[1024]; + int len; + + //3.获取客户端的字节输出流,将图片的字节数据边读边写,作为请求数据,发送给服务器 + while ((len = fis.read(buf)) != -1) { + os.write(buf, 0, len); + } + System.out.println("客户端上传了图片"); + socket.shutdownOutput();//设置请求数据的结束标记 + + //4.获取客户端的字节输入流,接收服务器的响应数据 + InputStream is = socket.getInputStream(); + while ((len = is.read(buf)) != -1) { + System.out.println(new String(buf, 0, len)); + } + System.out.println("客户端接收到了响应的结果"); + //5.资源释放 + socket.close(); + } +} diff --git a/s_day11/src/com/inmind/upload_04/UploadServerDemo02.java b/s_day11/src/com/inmind/upload_04/UploadServerDemo02.java new file mode 100644 index 0000000..75716fc --- /dev/null +++ b/s_day11/src/com/inmind/upload_04/UploadServerDemo02.java @@ -0,0 +1,46 @@ +package com.inmind.upload_04; + + +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.net.ServerSocket; +import java.net.Socket; + +/* + 文件上传的服务端的实现步骤: + 1.创建一个服务端对象,接收请求 + 2.获取客户端socket对象的字节输入流,接收请求数据(图片字节数据) + 3.创建字节输出流,边读边写到硬盘中 + 4.获取客户端的socket对象字节输出流,发送响应数据(上传成功) + 5.资源释放 + */ +public class UploadServerDemo02 { + public static void main(String[] args) throws IOException { + //1.创建一个服务端对象,接收请求 + ServerSocket serverSocket = new ServerSocket(10086); + System.out.println("服务器启动了"); + Socket clientSocket = serverSocket.accept(); + System.out.println(clientSocket.getInetAddress().getHostAddress()); + + //2.获取客户端socket对象的字节输入流,接收请求数据(图片字节数据) + InputStream is = clientSocket.getInputStream(); + byte[] buffer = new byte[1024]; + int len; + //3.创建字节输出流,边读边写到硬盘中 + FileOutputStream fos = new FileOutputStream("D:\\io_test\\upload\\"+System.currentTimeMillis()+".jpg"); + while ((len = is.read(buffer)) != -1) { + fos.write(buffer, 0, len); + } + fos.close(); + System.out.println("服务器保存了上传的图片"); + //4.获取客户端的socket对象字节输出流,发送响应数据(上传成功) + OutputStream os = clientSocket.getOutputStream(); + os.write("上传成功".getBytes()); + System.out.println("服务器响应了结果给客户端"); + //5.资源释放 + clientSocket.close(); + serverSocket.close(); + } +} diff --git a/s_day11/src/com/inmind/web_08/WeServerDemo.java b/s_day11/src/com/inmind/web_08/WeServerDemo.java new file mode 100644 index 0000000..1d86774 --- /dev/null +++ b/s_day11/src/com/inmind/web_08/WeServerDemo.java @@ -0,0 +1,38 @@ +package com.inmind.web_08; + +import java.io.FileInputStream; +import java.io.IOException; +import java.io.OutputStream; +import java.net.ServerSocket; +import java.net.Socket; + +/* +模拟服务器: + 接收到一个请求,返回页面 + */ +public class WeServerDemo { + public static void main(String[] args) throws IOException { + ServerSocket serverSocket = new ServerSocket(10088); + + while (true) { + Socket socket = serverSocket.accept(); + System.out.println("接收到一个请求"); + OutputStream os = socket.getOutputStream(); + + //因为请求的是一个浏览器,基于http协议,所以要遵守这个规范 + //写回去的前三行,必须是固定的 + os.write("HTTP/1.1 200 OK\r\n".getBytes());// 第一行 + os.write("Content-Type:text/html\r\n\r\n".getBytes());//第二行 第三行(空行) + + //将工程中的html页面响应给浏览器展示 + FileInputStream fis = new FileInputStream("index.html"); + byte[] buffer = new byte[1024]; + int len; + while ((len = fis.read(buffer)) != -1) { + os.write(buffer, 0, len); + } + fis.close(); + socket.close(); + } + } +} diff --git a/s_day12.rar b/s_day12.rar new file mode 100644 index 0000000..4e00603 Binary files /dev/null and b/s_day12.rar differ diff --git a/s_day12/src/com/inmind/annotation_03/Demo01.java b/s_day12/src/com/inmind/annotation_03/Demo01.java new file mode 100644 index 0000000..aee5de5 --- /dev/null +++ b/s_day12/src/com/inmind/annotation_03/Demo01.java @@ -0,0 +1,16 @@ +package com.inmind.annotation_03; +/* +8.JDK中的注解 +@Override :验证重写 +@FunctionalInterface:验证是否是函数式接口 +@Deprecated(since="9"):设置方法为过时方法 + +注解就是一个特殊的接口 + +java中的引用类型:类,接口,注解,枚举,数组 + */ + +public class Demo01 { + + public static void main(String[] args) {} +} diff --git a/s_day12/src/com/inmind/annotation_03/Demo02.java b/s_day12/src/com/inmind/annotation_03/Demo02.java new file mode 100644 index 0000000..1301421 --- /dev/null +++ b/s_day12/src/com/inmind/annotation_03/Demo02.java @@ -0,0 +1,17 @@ +package com.inmind.annotation_03; +/* + 元注解:用来修饰注解的注解 + @Target:设置某一个注解的作用范围 + ElementType.TYPE + ElementType.FIELD + ElementType.METHOD + ElementType.CONSTRUCTOR + ElementType.ANNOTATION_TYPE + @Retention:设置某一个注解的生命周期 + RetentionPolicy.SOURCE 编译时期有效 + RetentionPolicy.CLASS 编译后运行前有效 + RetentionPolicy.RUNTIME 运行时有效(比较常用,结合反射使用) + + */ +public class Demo02 { +} diff --git a/s_day12/src/com/inmind/annotation_03/MyAnnotation.java b/s_day12/src/com/inmind/annotation_03/MyAnnotation.java new file mode 100644 index 0000000..80431d0 --- /dev/null +++ b/s_day12/src/com/inmind/annotation_03/MyAnnotation.java @@ -0,0 +1,33 @@ +package com.inmind.annotation_03; + +import com.inmind.reflect_02.Student; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; +import java.util.ArrayList; +@Retention(RetentionPolicy.RUNTIME)//设置自定义注解运行时有效 +@Target(value = {ElementType.TYPE,ElementType.FIELD,ElementType.METHOD,ElementType.CONSTRUCTOR}) +public @interface MyAnnotation { + String name() default "张三"; //name属性 + int value(); +} +/* +自定义注解 +1.注解的关键字:@interface + +2.注解中可以定义属性 + 定义属性的格式:数据类型 属性名(); + 设置默认值的属性的格式:数据类型 属性名() default 属性值; +3.注解的属性的类型有限制 + 八大基本数据类型,String Class 注解 枚举 + 以上类型的一维数组 +4.注解中有一个特殊的属性名 value + 当属性赋值时,如果只有一个value属性在赋值,那么value = 省略!!! + +5.注解如何使用:它 可以修饰类,构造器,属性,方法,注解,参数 + +6.注解在使用时,属性值必须赋值,默认值可以覆盖 + + */ diff --git a/s_day12/src/com/inmind/annotation_03/ParseAnnotationDemo03.java b/s_day12/src/com/inmind/annotation_03/ParseAnnotationDemo03.java new file mode 100644 index 0000000..2ecfbef --- /dev/null +++ b/s_day12/src/com/inmind/annotation_03/ParseAnnotationDemo03.java @@ -0,0 +1,51 @@ +package com.inmind.annotation_03; + + +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; + +/* +解析注解 +AnnotatedElement接口:定义了与注解解析相关的方法,常用方法以下四个: + +1. boolean isAnnotationPresent(Class annotationClass); + 判断当前对象是否有指定的注解,有则返回true,否则返回false。 +2. T getAnnotation(Class annotationClass); + 获得当前对象上指定的注解对象。 +3. Annotation[] getAnnotations(); + 获得当前对象及其从父类上继承的所有的注解对象。 +4. Annotation[] getDeclaredAnnotations(); + 获得当前对象上所有的注解对象,不包括父类的。 + */ +public class ParseAnnotationDemo03 { + public static void main(String[] args) throws NoSuchMethodException, InstantiationException, IllegalAccessException, InvocationTargetException { + /* + 需求: + 1.使用反射获取私有的show方法上的MyAnnotation的注解的value属性值 + 2.将value的值作为show方法的参数,让show方法执行起来 + 分析: + 1.获取私有的Show方法的Method对象 + 2.判断下该show方法上,是否有MyAnnotation注解 + 3.如果有该注解,获取MyAnnotation注解对象,获取它的value值 + 4.调用Method对象的invoke,将value作为参数 + */ + Class clazz = Student.class; + //1.获取私有的Show方法的Method对象 + Method showMethod = clazz.getDeclaredMethod("show", int.class); +// showMethod.setAccessible(true); + //2.判断下该show方法上,是否有MyAnnotation注解 + //boolean isAnnotationPresent(Class annotationClass);判断当前对象是否有指定的注解,有则返回true,否则返回false。 + System.out.println(showMethod); + boolean res = showMethod.isAnnotationPresent(MyAnnotation.class); + System.out.println(res); + if (res) { + //3.如果有该注解,获取MyAnnotation注解对象,获取它的value值 + //T getAnnotation(Class annotationClass);获得当前对象上指定的注解对象。 + MyAnnotation annotation = showMethod.getAnnotation(MyAnnotation.class); + int value = annotation.value(); + //4.调用Method对象的invoke,将value作为参数 + showMethod.setAccessible(true); + System.out.println(showMethod.invoke(clazz.newInstance(), value)); + } + } +} diff --git a/s_day12/src/com/inmind/annotation_03/Student.java b/s_day12/src/com/inmind/annotation_03/Student.java new file mode 100644 index 0000000..ccdf364 --- /dev/null +++ b/s_day12/src/com/inmind/annotation_03/Student.java @@ -0,0 +1,40 @@ +package com.inmind.annotation_03; + + +import org.junit.Test; + +@MyAnnotation(name = "李四",value = 1) +public class Student { + @MyAnnotation(value = 1) + String name = null; + int age; + + public Student() { + + } + + @MyAnnotation(1) + private Student(String name, int age) { + this.name = name; + this.age = age; + } + + @MyAnnotation(1) + public void show(){ + System.out.println("无参无返回值的show方法执行了"); + } + + @MyAnnotation(20) + private int show(int i){ + System.out.println("有参有返回值的静态show方法执行了"); + return i+100; + } + + @Override + public String toString() { + return "Student{" + + "name='" + name + '\'' + + ", age=" + age + + '}'; + } +} diff --git a/s_day12/src/com/inmind/custom_junit_04/Demo01.java b/s_day12/src/com/inmind/custom_junit_04/Demo01.java new file mode 100644 index 0000000..dc69cb6 --- /dev/null +++ b/s_day12/src/com/inmind/custom_junit_04/Demo01.java @@ -0,0 +1,26 @@ +package com.inmind.custom_junit_04; +/* +12.自定义简单的Junit框架 + +分析: +1.自定义@MyTest +2.获取一个类中的所有的方法 +3.判断每个方法上是否有MyTest注解 +4.如果有就让对应的方法执行起来 + */ +public class Demo01 { + + public void method1(){ + System.out.println("这是要测试的功能代码1"); + } + + @MyTest + public void method2(){ + System.out.println("这是要测试的功能代码2"); + } + + @MyTest + public void method3(){ + System.out.println("这是要测试的功能代码3"); + } +} diff --git a/s_day12/src/com/inmind/custom_junit_04/MyTest.java b/s_day12/src/com/inmind/custom_junit_04/MyTest.java new file mode 100644 index 0000000..4351ea4 --- /dev/null +++ b/s_day12/src/com/inmind/custom_junit_04/MyTest.java @@ -0,0 +1,11 @@ +package com.inmind.custom_junit_04; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +@Retention(RetentionPolicy.RUNTIME) +@Target(ElementType.METHOD) +public @interface MyTest { +} diff --git a/s_day12/src/com/inmind/custom_junit_04/ParseMyTest.java b/s_day12/src/com/inmind/custom_junit_04/ParseMyTest.java new file mode 100644 index 0000000..6968e87 --- /dev/null +++ b/s_day12/src/com/inmind/custom_junit_04/ParseMyTest.java @@ -0,0 +1,23 @@ +package com.inmind.custom_junit_04; + +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; + +public class ParseMyTest { + public static void main(String[] args) throws InstantiationException, IllegalAccessException, InvocationTargetException { + //2.获取一个类中的所有的方法 + Class clazz = Demo01.class; + Method[] methods = clazz.getMethods(); + System.out.println(methods.length); + //3.判断每个方法上是否有MyTest注解 + for (Method method : methods) { + boolean res = method.isAnnotationPresent(MyTest.class); + if (res) { + //4.如果有就让对应的方法执行起来 + method.invoke(clazz.newInstance()); + } + + } + + } +} diff --git a/s_day12/src/com/inmind/enum_05/Demo01.java b/s_day12/src/com/inmind/enum_05/Demo01.java new file mode 100644 index 0000000..9129df8 --- /dev/null +++ b/s_day12/src/com/inmind/enum_05/Demo01.java @@ -0,0 +1,11 @@ +package com.inmind.enum_05; + +public class Demo01 { + public static void main(String[] args) { + EnumA a = EnumA.B; +// EnumA.A = null; + System.out.println(a); + + System.out.println(EnumA.A.getName()); + } +} diff --git a/s_day12/src/com/inmind/enum_05/Demo02.java b/s_day12/src/com/inmind/enum_05/Demo02.java new file mode 100644 index 0000000..c086d2d --- /dev/null +++ b/s_day12/src/com/inmind/enum_05/Demo02.java @@ -0,0 +1,31 @@ +package com.inmind.enum_05; +/* + 枚举类的作用:定义一组固定的,有限的常量集合,用来明确取值范围的场景 + */ +public class Demo02 { + //switch语句中要使用常用,就可以使用枚举 + enum WeekDay{ + MONDAY,TUESDAY,WEDNESDAY,THURSDAY,FRIDAY,SATURDAY,SUNDAY + } + + + public static void main(String[] args) { + printWeekDayInfo(WeekDay.FRIDAY); + printWeekDayInfo(WeekDay.MONDAY); + printWeekDayInfo(WeekDay.SUNDAY); + } + + //使用switch处理枚举类 + public static void printWeekDayInfo(WeekDay weekDay) { + switch (weekDay) { + case MONDAY: System.out.println("周一");break; + case TUESDAY: System.out.println("周2");break; + case WEDNESDAY: System.out.println("周3");break; + case THURSDAY: System.out.println("周4");break; + case FRIDAY: System.out.println("周5");break; + case SATURDAY: System.out.println("周6");break; + case SUNDAY: System.out.println("周日");break; + } + } + +} diff --git a/s_day12/src/com/inmind/enum_05/Demo03.java b/s_day12/src/com/inmind/enum_05/Demo03.java new file mode 100644 index 0000000..e5dd74e --- /dev/null +++ b/s_day12/src/com/inmind/enum_05/Demo03.java @@ -0,0 +1,11 @@ +package com.inmind.enum_05; + +public class Demo03 { + public static void main(String[] args) { + //使用httpStatus枚举 + System.out.println("http状态信息"); + HttpStatus status = HttpStatus.INTERNAL_SERVER_ERROR; + System.out.println("状态码:"+status.getCode()); + System.out.println("描述:"+status.getDescription()); + } +} diff --git a/s_day12/src/com/inmind/enum_05/EnumA.java b/s_day12/src/com/inmind/enum_05/EnumA.java new file mode 100644 index 0000000..7858ebc --- /dev/null +++ b/s_day12/src/com/inmind/enum_05/EnumA.java @@ -0,0 +1,31 @@ +package com.inmind.enum_05; +/* +enum是一种特殊的类 +1.枚举类的第一行只能罗列一些名称,这些名称都是常量,并且每个常量都是该枚举类的一个对象(枚举常量本质上就是该枚举类型的实例对象,编译器 +会自动为它添加上public static final修饰符) +2.枚举类的构造方法都是私有的,因为枚举类对外不能创建对象 +3.枚举类都是最终类,不能被继承 +4.枚举类中,第二行开始,可以定义类的各种成员 + +枚举的作用:就是一个长度有限,内容固定的常量集合 + */ +public enum EnumA { + A("张三"),B,C,D,E("李四"); + private String name; + + EnumA() { + this("null"); + } + + EnumA(String name) { + this.name = name; + } + + public String getName() { + return name; + } + + /*public void setName(String name) { + this.name = name; + }*/ +} diff --git a/s_day12/src/com/inmind/enum_05/HttpStatus.java b/s_day12/src/com/inmind/enum_05/HttpStatus.java new file mode 100644 index 0000000..6877f61 --- /dev/null +++ b/s_day12/src/com/inmind/enum_05/HttpStatus.java @@ -0,0 +1,26 @@ +package com.inmind.enum_05; + +public enum HttpStatus { + OK(200, "OK"), + BAD_REQUEST(400, "请求参数错误"), + UNAUTHORIZED(401,"未授权访问"), + FORBIDDEN(403,"禁止访问"), + NOT_FOUND(404,"资源不存在"), + INTERNAL_SERVER_ERROR(500,"服务器内部错误,联系管理员"); + + private int code;//状态 + private String description;//状态描述 + + HttpStatus(int code, String description) { + this.code = code; + this.description = description; + } + + public int getCode() { + return code; + } + + public String getDescription() { + return description; + } +} diff --git a/s_day12/src/com/inmind/junit_01/Demo01.java b/s_day12/src/com/inmind/junit_01/Demo01.java new file mode 100644 index 0000000..9e8ad76 --- /dev/null +++ b/s_day12/src/com/inmind/junit_01/Demo01.java @@ -0,0 +1,84 @@ +package com.inmind.junit_01; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +/* +Junit测试框架 + +框架:就是将一些工具类,抽象父类,接口,以及它们的实现类封装到一个jar包,帮助我们程序员快速高效地实现一些功能 + +Junit测试框架:帮助程序员快速高效测试功能代码 + +Junit测试框架是一个第三方的框架,如果要使用非JDK提供的功能,必须要导包。 + +junit测试框架的使用步骤: +1.先定义出不同的功能方法,将要测试的代码放入各自方法中 +2.在要测试的功能方法上添加注解@Test +3.可以在方法中直接右键运行或者方法外右键运行全部 + +junit测试框架的常用注解 + a.@Test:设置当前方法是否要进行测试 + b.@Before: 设置测试每个方法之前,要添加的执行代码 + c.@After: 设置测试每个方法之后,要添加的执行代码 + +junit框架的注意事项: +1.方法必须是public +2.必须是无参 +3.必须无返回值 + + +junit测试框架如何实现的?? +注解(自定义注解)+反射(识别注解+解析注解) + + */ +public class Demo01 { + + @Test + public void method1(){ + //获取当前时间 + //1.模拟功能1 + int a = 1/1; + //获取当前时间 + //计算功能代码耗费的时间 + } + + + + private long start; + + @Before + public void before(){ + //获取功能方法执行之前的毫秒值 + System.out.println("功能测试开始了......"); + start = System.currentTimeMillis(); + } + + + @After + public void after(){ + //获取功能方法执行之后的毫秒值 + System.out.println("功能测试结束了......"); + long end = System.currentTimeMillis(); + System.out.println("当前功能方法消耗了:"+(end-start)+" 毫秒"); + } + + + + + + @Test + public void method2(){ + //2.模拟功能2 + int[] arr = {1,2,3}; + System.out.println(arr[1]); + } + + @Test + public void method3(){ + //3.模拟功能3 + System.out.println("这是业务测试功能"); + } + +} diff --git a/s_day12/src/com/inmind/reflect_02/ConstructorDemo03.java b/s_day12/src/com/inmind/reflect_02/ConstructorDemo03.java new file mode 100644 index 0000000..0ce1808 --- /dev/null +++ b/s_day12/src/com/inmind/reflect_02/ConstructorDemo03.java @@ -0,0 +1,75 @@ +package com.inmind.reflect_02; + +import org.junit.Test; + +import java.lang.reflect.Constructor; +import java.lang.reflect.InvocationTargetException; + +/* +5.反射操作构造器(创建对象) +Class Constructor + +总结: + 构造器如何获取呢?? + Class对象的2个API: + getConstructor:获取public的构造器 + getDeclaredConstructor:获取所有定义过的构造器 + 构造器的作用:创建对象 + constructor.setAccessible(true); + Object o = constructor.newInstance("张三", 18); + + */ +public class ConstructorDemo03 { + public static void main(String[] args) { + //普通的构造方法创建对象 + Student student = new Student(); + System.out.println(student); + } + + /* + 直接使用Class反射API创建出学生对象 + */ + @Test + public void method1() throws ClassNotFoundException, InstantiationException, IllegalAccessException { + Class clazz = Class.forName("com.inmind.reflect_02.Student"); + + //底层:调用指定类的无参构造方法创建出对象 + Object o = clazz.newInstance(); + System.out.println(o); + } + + /* + 获取无参构造器对象,创建出学生对象 + */ + @Test + public void method2() throws ClassNotFoundException, NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException { + Class clazz = Class.forName("com.inmind.reflect_02.Student"); + //Constructor[] getConstructors() 返回一个包含 Constructor对象的数组, Constructor对象反映了由该 Class对象表示的类的所有公共构造函数。 + //Constructor getConstructor(Class... parameterTypes) 返回一个 Constructor对象,该对象反映由该 Class对象表示的类的指定公共构造函数。 + Constructor constructor = clazz.getConstructor(); + //public T newInstance(Object ... initargs),initargs就是对应构造器的参数,如果有就传入 + Object o = constructor.newInstance(); + System.out.println(o); + } + + /* + 获取私有的满参构造方法,并创建学生对象 + */ + @Test + public void method3() throws ClassNotFoundException, NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException { + Class clazz = Class.forName("com.inmind.reflect_02.Student"); + //获取私有的满参构造器对象 + //getConstructor:只能获取public修饰的构造方法 +// Constructor constructor = clazz.getConstructor(String.class, int.class); + //Constructor getDeclaredConstructor(Class... parameterTypes):获取已经定义过的构造方法 + Constructor constructor = clazz.getDeclaredConstructor(String.class, int.class); + + //暴力反射,修改它的访问权限 + //void setAccessible(boolean flag) + constructor.setAccessible(true); + + //使用构造器对象创建学生对象 + Object o = constructor.newInstance("张三", 18); + System.out.println(o); + } +} diff --git a/s_day12/src/com/inmind/reflect_02/Demo01.java b/s_day12/src/com/inmind/reflect_02/Demo01.java new file mode 100644 index 0000000..b72f700 --- /dev/null +++ b/s_day12/src/com/inmind/reflect_02/Demo01.java @@ -0,0 +1,40 @@ +package com.inmind.reflect_02; +/* + 反射:在程序运行时,操作类(构造方法,成员方法,属性) + + 反射前提是Class对象 + + Class类的实例表示正在运行的Java应用程序中的类和接口,可以理解为是对象的设计图 + + Class对象的三种获取方式 + 1.Class.forName("全类名") 常用于框架的初始化操作(jdbc注册驱动) + 全类名:包名+类名 + 2.类名.class 常用于反射API中作为参数 + + 3.对象名.getClass() 常用于类型判断 + + */ +public class Demo01 { + public static void main(String[] args) throws ClassNotFoundException { + //Class对象的获取方式一 + Class clazz = Class.forName("com.inmind.reflect_02.Student"); + System.out.println(clazz); + + //Class对象的获取方式二 + Class clazz1 = Student.class; + System.out.println(clazz1); + + //Class对象的获取方式三 + Student student = new Student(); + Class clazz2 = student.getClass(); + System.out.println(clazz2); + + System.out.println(clazz1 == clazz2); + System.out.println(clazz == clazz1); + + //Class对象的常用方法: + System.out.println(clazz.getName()); + System.out.println(clazz.getSimpleName()); + + } +} diff --git a/s_day12/src/com/inmind/reflect_02/Demo02.java b/s_day12/src/com/inmind/reflect_02/Demo02.java new file mode 100644 index 0000000..6ff2046 --- /dev/null +++ b/s_day12/src/com/inmind/reflect_02/Demo02.java @@ -0,0 +1,17 @@ +package com.inmind.reflect_02; +/* +4.预定义对象(了解) +没有.class文件的Class对象,就是预定义对象 + */ +public class Demo02 { + public static void main(String[] args) { + //基本数据类型,数组是否也有Class对象呢??? + Class intClazz = int.class; + System.out.println(intClazz); + Class byteClazz = byte.class; + System.out.println(byteClazz); + + Class clazz = int[].class; + System.out.println(clazz); + } +} diff --git a/s_day12/src/com/inmind/reflect_02/FieldDemo05.java b/s_day12/src/com/inmind/reflect_02/FieldDemo05.java new file mode 100644 index 0000000..7a36c7a --- /dev/null +++ b/s_day12/src/com/inmind/reflect_02/FieldDemo05.java @@ -0,0 +1,43 @@ +package com.inmind.reflect_02; + +import org.junit.Test; + +import java.lang.reflect.Field; + +/* +7.反射操作属性 +属性的作用:赋值 / 取值 +Field对象的set/get方法 + */ +public class FieldDemo05 { + public static void main(String[] args) { + //普通的属性操作 + Student student = new Student(); + //赋值操作:1.对象名 2.属性名 3.属性值 + student.name = "张三"; + //取值操作:1.对象名 2.属性名 + System.out.println(student.name); + } + + + /* + 反射操作name属性 + */ + @Test + public void method1() throws NoSuchFieldException, IllegalAccessException { + Student s = new Student(); + System.out.println(s); + Class clazz = s.getClass(); + + //获取name属性对象 + Field nameField = clazz.getDeclaredField("name"); + System.out.println(nameField.getName()); + //赋值 + nameField.set(s,"李四"); + System.out.println(s); + //取值 + Object o = nameField.get(s); + System.out.println(o); + + } +} diff --git a/s_day12/src/com/inmind/reflect_02/MethodDemo04.java b/s_day12/src/com/inmind/reflect_02/MethodDemo04.java new file mode 100644 index 0000000..f0a202b --- /dev/null +++ b/s_day12/src/com/inmind/reflect_02/MethodDemo04.java @@ -0,0 +1,81 @@ +package com.inmind.reflect_02; + +import org.junit.Test; + +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; + +/* +6.反射操作方法 + +总结: + 1.如何获取方法对象?? + 通过Class对象 + Method getMethod() + Method getDeclaredMethod + 2. 方法对象的作用:用来执行,调用,获取返回值 + + 3.方法对象如何执行 + public Object invoke(Object obj, Object... args) + 参数一:要执行方法的对象(学生对象),如果是静态方法就不需要对象调用,直接给null + 参数二:调用该方法时所需的参数 + + + + */ +public class MethodDemo04 { + public static void main(String[] args) { + //普通调用方法 + Student student = new Student(); + //一个成员方法要被执行需要的三个元素:1.对象名 2.方法名 3.参数 + student.show(); + } + + /* + 反射获取无参无返回值的show方法,并调用它 + */ + @Test + public void method1() throws NoSuchMethodException, InstantiationException, IllegalAccessException, InvocationTargetException { + Class clazz = Student.class; + //使用Method表示一个方法对象 + /* + Method getMethod(String name, Class... parameterTypes) + Method[] getMethods() + + Method getDeclaredMethod(String name, Class... parameterTypes) + Method getDeclaredMethods() + */ + Method showMethod = clazz.getMethod("show"); + + //调用它 + //public Object invoke(Object obj, Object... args) + showMethod.invoke(clazz.newInstance()); + } + + /* + 反射获取私有的有参有返回值的show方法,并执行 + */ + @Test + public void method2() throws NoSuchMethodException, InstantiationException, IllegalAccessException, InvocationTargetException { + Class clazz = Student.class; + /* + ethod getDeclaredMethod(String name, Class... parameterTypes) + 参数一:要获取的方法名 + 参数二:该方法的参数列表的类型 + */ + Method showMethod = clazz.getDeclaredMethod("show", int.class); + + //设置该方法可以访问 + showMethod.setAccessible(true); + //执行方法 + /* + public Object invoke(Object obj, Object... args) + 参数一:要执行方法的对象(学生对象) + 参数二:调用该方法时所需的参数 + */ +// Object result = showMethod.invoke(clazz.newInstance(), 10); + Object result = showMethod.invoke(null, 10); + System.out.println(result); + } + +} diff --git a/s_day12/src/com/inmind/reflect_02/Student.java b/s_day12/src/com/inmind/reflect_02/Student.java new file mode 100644 index 0000000..d5cba79 --- /dev/null +++ b/s_day12/src/com/inmind/reflect_02/Student.java @@ -0,0 +1,33 @@ +package com.inmind.reflect_02; + + +public class Student { + String name = null; + int age; + + public Student() { + + } + + private Student(String name, int age) { + this.name = name; + this.age = age; + } + + public void show(){ + System.out.println("无参无返回值的show方法执行了"); + } + + private static int show(int i){ + System.out.println("有参有返回值的静态show方法执行了"); + return i+100; + } + + @Override + public String toString() { + return "Student{" + + "name='" + name + '\'' + + ", age=" + age + + '}'; + } +} diff --git a/s_day12/src/com/inmind/test_06/Email.java b/s_day12/src/com/inmind/test_06/Email.java new file mode 100644 index 0000000..ffbae55 --- /dev/null +++ b/s_day12/src/com/inmind/test_06/Email.java @@ -0,0 +1,14 @@ +package com.inmind.test_06; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +// 注解:字段级注解,标记字段需要验证邮箱格式 +@Target(ElementType.FIELD) +@Retention(RetentionPolicy.RUNTIME) +@interface Email { + String message() default "邮箱格式不正确"; // 错误提示信息 + ValidatorType type() default ValidatorType.EMAIL; // 关联的验证器类型 +} diff --git a/s_day12/src/com/inmind/test_06/NotNull.java b/s_day12/src/com/inmind/test_06/NotNull.java new file mode 100644 index 0000000..cb5323d --- /dev/null +++ b/s_day12/src/com/inmind/test_06/NotNull.java @@ -0,0 +1,14 @@ +package com.inmind.test_06; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +// 注解:字段级注解,标记字段不允许为null +@Target(ElementType.FIELD) // 注解适用范围:成员变量 +@Retention(RetentionPolicy.RUNTIME) // 运行时可访问 +@interface NotNull { + String message() default "字段不能为null"; // 错误提示信息,有默认值 + ValidatorType type() default ValidatorType.NOT_NULL; // 关联的验证器类型 +} diff --git a/s_day12/src/com/inmind/test_06/Range.java b/s_day12/src/com/inmind/test_06/Range.java new file mode 100644 index 0000000..59f8f40 --- /dev/null +++ b/s_day12/src/com/inmind/test_06/Range.java @@ -0,0 +1,16 @@ +package com.inmind.test_06; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +// 注解:字段级注解,标记字段值需要在指定范围内(适用于数值类型) +@Target(ElementType.FIELD) +@Retention(RetentionPolicy.RUNTIME) +@interface Range { + int min() default 0; // 最小值,默认0 + int max() default Integer.MAX_VALUE; // 最大值,默认整数最大值 + String message() default "字段值超出范围"; // 错误提示信息 + ValidatorType type() default ValidatorType.RANGE; // 关联的验证器类型 +} diff --git a/s_day12/src/com/inmind/test_06/ReflectTest.java b/s_day12/src/com/inmind/test_06/ReflectTest.java new file mode 100644 index 0000000..e228af1 --- /dev/null +++ b/s_day12/src/com/inmind/test_06/ReflectTest.java @@ -0,0 +1,52 @@ +package com.inmind.test_06; + +/* +业务说明 +这个案例实现了一个通用对象验证框架,核心业务是对 Java 对象的字段进行自动化验证,适用于需要数据校验的场景(如表单提交、接口参数校验等)。 +业务流程 +定义验证规则:通过自定义注解(@NotNull、@Range、@Email)标记需要验证的字段,并设置验证条件(如非空、数值范围、邮箱格式)。 +标记待验证类:在需要验证的类上添加@Validatable注解,声明该类需要进行字段验证。 +执行验证:调用Validator.validate()方法,传入待验证对象,框架会通过反射自动检查所有字段的注解并执行验证逻辑。 +返回验证结果:验证结果包含 “是否通过” 和具体错误信息,方便后续处理(如提示用户修正数据)。 +错误类型:使用枚举定义错误类型 + */ +import java.util.List; + +// 主类:程序入口,演示验证功能 +public class ReflectTest { + public static void main(String[] args) { + // 创建两个测试用户对象 + User validUser = new User("张三", 25, "zhangsan@example.com"); // 符合所有验证规则 + User invalidUser = new User(null, 15, "invalid-email"); // 不符合验证规则 + + // 验证有效用户 + System.out.println("=== 验证有效用户 ==="); + ValidationResult validResult = Validator.validate(validUser); + printValidationResult(validResult); + + // 验证无效用户 + System.out.println("\n=== 验证无效用户 ==="); + ValidationResult invalidResult = Validator.validate(invalidUser); + printValidationResult(invalidResult); + + // 演示根据错误类型筛选错误 + System.out.println("\n=== 按错误类型筛选结果 ==="); + List notNullErrors = invalidResult.getErrorsByType(ValidationErrorType.NOT_NULL); + System.out.println("非空错误数量: " + notNullErrors.size()); + for (ValidationError error : notNullErrors) { + System.out.println(error); + } + } + + // 打印验证结果的工具方法 + private static void printValidationResult(ValidationResult result) { + if (result.isValid()) { + System.out.println("验证通过!"); + } else { + System.out.println("验证失败,错误信息:"); + for (ValidationError error : result.getErrors()) { + System.out.println("- " + error); + } + } + } +} \ No newline at end of file diff --git a/s_day12/src/com/inmind/test_06/User.java b/s_day12/src/com/inmind/test_06/User.java new file mode 100644 index 0000000..d90b112 --- /dev/null +++ b/s_day12/src/com/inmind/test_06/User.java @@ -0,0 +1,29 @@ +package com.inmind.test_06; + +// 示例实体类:用户信息类,标记了@Validatable表示需要验证 +@Validatable +class User { + @NotNull(message = "用户名不能为空") // 用户名不允许为null + private String username; + + @Range(min = 18, max = 60, message = "年龄必须在18到60之间") // 年龄范围限制 + private int age; + + @Email(message = "请输入有效的邮箱地址") // 邮箱格式验证 + private String email; + + // 构造方法:初始化用户信息 + public User(String username, int age, String email) { + this.username = username; + this.age = age; + this.email = email; + } + + // getter和setter方法 + public String getUsername() { return username; } + public void setUsername(String username) { this.username = username; } + public int getAge() { return age; } + public void setAge(int age) { this.age = age; } + public String getEmail() { return email; } + public void setEmail(String email) { this.email = email; } +} \ No newline at end of file diff --git a/s_day12/src/com/inmind/test_06/Validatable.java b/s_day12/src/com/inmind/test_06/Validatable.java new file mode 100644 index 0000000..7da105e --- /dev/null +++ b/s_day12/src/com/inmind/test_06/Validatable.java @@ -0,0 +1,12 @@ +package com.inmind.test_06; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +// 注解:类级注解,标记该类需要进行字段验证 +@Target(ElementType.TYPE) // 注解适用范围:类、接口等 +@Retention(RetentionPolicy.RUNTIME) // 注解保留策略:运行时可通过反射获取 +@interface Validatable { +} \ No newline at end of file diff --git a/s_day12/src/com/inmind/test_06/ValidationError.java b/s_day12/src/com/inmind/test_06/ValidationError.java new file mode 100644 index 0000000..8f659d2 --- /dev/null +++ b/s_day12/src/com/inmind/test_06/ValidationError.java @@ -0,0 +1,25 @@ +package com.inmind.test_06; + +// 验证错误信息类:包含错误类型和错误描述 +class ValidationError { + private ValidationErrorType errorType; // 错误类型 + private String message; // 错误描述 + + public ValidationError(ValidationErrorType errorType, String message) { + this.errorType = errorType; + this.message = message; + } + + public ValidationErrorType getErrorType() { + return errorType; + } + + public String getMessage() { + return message; + } + + @Override + public String toString() { + return "[" + errorType + "] " + message; + } +} diff --git a/s_day12/src/com/inmind/test_06/ValidationErrorType.java b/s_day12/src/com/inmind/test_06/ValidationErrorType.java new file mode 100644 index 0000000..7caf9db --- /dev/null +++ b/s_day12/src/com/inmind/test_06/ValidationErrorType.java @@ -0,0 +1,9 @@ +package com.inmind.test_06; + +// 枚举:定义验证错误的类型,用于分类错误信息 +enum ValidationErrorType { + NOT_NULL, // 非空错误:字段值为null时触发 + MIN_VALUE, // 最小值错误:数值小于允许的最小值时触发 + MAX_VALUE, // 最大值错误:数值大于允许的最大值时触发 + INVALID_EMAIL // 邮箱格式错误:邮箱地址格式不正确时触发 +} \ No newline at end of file diff --git a/s_day12/src/com/inmind/test_06/ValidationResult.java b/s_day12/src/com/inmind/test_06/ValidationResult.java new file mode 100644 index 0000000..a743b4b --- /dev/null +++ b/s_day12/src/com/inmind/test_06/ValidationResult.java @@ -0,0 +1,41 @@ +package com.inmind.test_06; + +import java.util.ArrayList; +import java.util.List; + +// 验证结果类:封装验证的结果信息 +class ValidationResult { + private boolean valid; // 验证是否通过 + private List errors = new ArrayList<>(); // 错误列表 + + // 获取验证是否通过的状态 + public boolean isValid() { + return valid; + } + + // 设置验证状态 + public void setValid(boolean valid) { + this.valid = valid; + } + + // 获取错误列表 + public List getErrors() { + return errors; + } + + // 添加错误信息 + public void addError(ValidationError error) { + errors.add(error); + } + + // 根据错误类型筛选错误 + public List getErrorsByType(ValidationErrorType type) { + List result = new ArrayList<>(); + for (ValidationError error : errors) { + if (error.getErrorType() == type) { + result.add(error); + } + } + return result; + } +} \ No newline at end of file diff --git a/s_day12/src/com/inmind/test_06/Validator.java b/s_day12/src/com/inmind/test_06/Validator.java new file mode 100644 index 0000000..0d3d1ae --- /dev/null +++ b/s_day12/src/com/inmind/test_06/Validator.java @@ -0,0 +1,110 @@ +package com.inmind.test_06; + +import java.lang.reflect.Field; + +// 验证器工具类:核心类,使用反射执行验证逻辑 +//针对我们定义的3个校验注解的反射验证框架代码 +class Validator { + // 验证对象的公共方法,返回验证结果 + public static ValidationResult validate(Object obj) { + ValidationResult result = new ValidationResult(); + result.setValid(true); // 默认验证通过 + + // 检查对象所属的类是否标记了@Validatable注解,未标记则直接返回 + if (!obj.getClass().isAnnotationPresent(Validatable.class)) { + return result; + } + + try { + // 通过反射获取类的所有字段(包括私有字段) + Field[] fields = obj.getClass().getDeclaredFields(); + + // 遍历每个字段进行验证 + for (Field field : fields) { + // 设置私有字段可访问(否则无法获取值) + field.setAccessible(true); + String fieldName = field.getName(); // 获取字段名 + Object value = field.get(obj); // 获取字段的值 + + // 验证@NotNull注解:如果字段标记了该注解且值为null,则添加错误 + if (field.isAnnotationPresent(NotNull.class)) { + // 演示ValidatorType的使用:获取注解关联的验证器类型 + ValidatorType validatorType = field.getAnnotation(NotNull.class).type(); + System.out.println("对字段[" + fieldName + "]使用" + validatorType + "进行验证"); + + if (value == null) { + NotNull annotation = field.getAnnotation(NotNull.class); + // 使用ValidationErrorType创建错误信息 + result.addError(new ValidationError( + ValidationErrorType.NOT_NULL, + fieldName + ": " + annotation.message() + )); + result.setValid(false); + } + } + + // 验证@Range注解:仅对数值类型且值不为null的字段生效 + if (field.isAnnotationPresent(Range.class) && value != null) { + // 演示ValidatorType的使用 + ValidatorType validatorType = field.getAnnotation(Range.class).type(); + System.out.println("对字段[" + fieldName + "]使用" + validatorType + "进行验证"); + + // 检查字段值是否为数字类型 + if (value instanceof Number) { + Range annotation = field.getAnnotation(Range.class); + Number number = (Number) value; + + // 检查是否小于最小值 + if (number.intValue() < annotation.min()) { + result.addError(new ValidationError( + ValidationErrorType.MIN_VALUE, + fieldName + ": " + annotation.message() + "(最小值: " + annotation.min() + ")" + )); + result.setValid(false); + } + + // 检查是否大于最大值 + if (number.intValue() > annotation.max()) { + result.addError(new ValidationError( + ValidationErrorType.MAX_VALUE, + fieldName + ": " + annotation.message() + "(最大值: " + annotation.max() + ")" + )); + result.setValid(false); + } + } + } + + // 验证@Email注解:仅对字符串类型且值不为null的字段生效 + if (field.isAnnotationPresent(Email.class) && value != null) { + // 演示ValidatorType的使用 + ValidatorType validatorType = field.getAnnotation(Email.class).type(); + System.out.println("对字段[" + fieldName + "]使用" + validatorType + "进行验证"); + + // 检查字段值是否为字符串类型 + if (value instanceof String) { + Email annotation = field.getAnnotation(Email.class); + String email = (String) value; + + // 简单验证邮箱格式(包含@符号) + if (!email.contains("@")) { + result.addError(new ValidationError( + ValidationErrorType.INVALID_EMAIL, + fieldName + ": " + annotation.message() + )); + result.setValid(false); + } + } + } + } + } catch (IllegalAccessException e) { + // 处理反射访问异常 + e.printStackTrace(); + result.setValid(false); + result.addError(new ValidationError( + null, "验证过程中发生错误: " + e.getMessage() + )); + } + + return result; + } +} \ No newline at end of file diff --git a/s_day12/src/com/inmind/test_06/ValidatorType.java b/s_day12/src/com/inmind/test_06/ValidatorType.java new file mode 100644 index 0000000..6d31d5d --- /dev/null +++ b/s_day12/src/com/inmind/test_06/ValidatorType.java @@ -0,0 +1,8 @@ +package com.inmind.test_06; + +// 枚举:定义验证器的类型,用于标识不同的验证规则 +enum ValidatorType { + NOT_NULL, // 非空验证器 + RANGE, // 范围验证器 + EMAIL // 邮箱验证器 +} diff --git a/s_day13.rar b/s_day13.rar new file mode 100644 index 0000000..6612c8f Binary files /dev/null and b/s_day13.rar differ diff --git a/s_day13/books-schema.xml b/s_day13/books-schema.xml new file mode 100644 index 0000000..58dacc7 --- /dev/null +++ b/s_day13/books-schema.xml @@ -0,0 +1,17 @@ + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/s_day13/books.dtd b/s_day13/books.dtd new file mode 100644 index 0000000..932ea66 --- /dev/null +++ b/s_day13/books.dtd @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/s_day13/books.xml b/s_day13/books.xml new file mode 100644 index 0000000..86ab221 --- /dev/null +++ b/s_day13/books.xml @@ -0,0 +1,34 @@ + + + + + + java + 99 + 小王 + + + mysql + 199 + 小李 + + + mysql + 199 + 小李 + + + mysql + 199 + 小李 + + \ No newline at end of file diff --git a/s_day13/books.xsd b/s_day13/books.xsd new file mode 100644 index 0000000..f314f9a --- /dev/null +++ b/s_day13/books.xsd @@ -0,0 +1,40 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/s_day13/note.txt b/s_day13/note.txt new file mode 100644 index 0000000..b5cf836 --- /dev/null +++ b/s_day13/note.txt @@ -0,0 +1,29 @@ + + + + + + +]> + + George + John + Reminder + Don't forget the meeting! + + + +以上 DTD 解释如下: +!DOCTYPE note (第二行)定义此文档是 note 类型的文档。 + +!ELEMENT note (第三行)定义 note 元素有四个元素:"to、from、heading,、body" + +!ELEMENT to (第四行)定义 to 元素为 "#PCDATA" 类型 + +!ELEMENT from (第五行)定义 frome 元素为 "#PCDATA" 类型 + +!ELEMENT heading (第六行)定义 heading 元素为 "#PCDATA" 类型 + +!ELEMENT body (第七行)定义 body 元素为 "#PCDATA" 类型 + diff --git a/s_day13/src/com/inmind/daynamic_proxy_01/CaiXuKun.java b/s_day13/src/com/inmind/daynamic_proxy_01/CaiXuKun.java new file mode 100644 index 0000000..ccfc736 --- /dev/null +++ b/s_day13/src/com/inmind/daynamic_proxy_01/CaiXuKun.java @@ -0,0 +1,18 @@ +package com.inmind.daynamic_proxy_01; + +public class CaiXuKun implements Singer{ + @Override + public void sing(int money) { + System.out.println("蔡徐坤收到了"+money+"钱,唱了鸡你太美"); + } + + @Override + public void dance(int money) { + System.out.println("蔡徐坤收到了"+money+"钱,跳了篮球舞"); + } + + @Override + public void eat() { + System.out.println("蔡徐坤吃了大盘鸡"); + } +} diff --git a/s_day13/src/com/inmind/daynamic_proxy_01/Demo01.java b/s_day13/src/com/inmind/daynamic_proxy_01/Demo01.java new file mode 100644 index 0000000..5eaed67 --- /dev/null +++ b/s_day13/src/com/inmind/daynamic_proxy_01/Demo01.java @@ -0,0 +1,16 @@ +package com.inmind.daynamic_proxy_01; +/* +1.类加载器:能够将字节码文件加载在JVM的方法区,就在堆中产生一个一一对应的Class对象 + 类加载器的作用:生成Class对象 + + 应用场景:在动态代理中,它要作为参数 + */ +public class Demo01 { + public static void main(String[] args) { + //反射的前提 + Class clazz = Demo01.class; + //获取类加载器 + ClassLoader classLoader = clazz.getClassLoader(); + System.out.println(classLoader); + } +} diff --git a/s_day13/src/com/inmind/daynamic_proxy_01/Demo02.java b/s_day13/src/com/inmind/daynamic_proxy_01/Demo02.java new file mode 100644 index 0000000..0a5f386 --- /dev/null +++ b/s_day13/src/com/inmind/daynamic_proxy_01/Demo02.java @@ -0,0 +1,26 @@ +package com.inmind.daynamic_proxy_01; +/* +装饰设计模式 + 装饰者 被装饰者 作用:装饰者增强被装饰者的功能 + 花瓶 花 花瓶增强了花的好看的程度 + 经纪人 蔡徐坤 经纪人增强了蔡徐坤的唱跳金额的判断功能 + 装饰设计模式的前提:装饰者需要与被装饰者拥有的功能要一致,继承同一个父类或者实现同一个接口 + BufferedReader FileReader 底层封装了缓冲区,提高字符输入流的读取效率 + + */ +public class Demo02 { + public static void main(String[] args) { + //在美食城唱歌 + CaiXuKun caiXuKun = new CaiXuKun(); + /* + caiXuKun.sing(10); + caiXuKun.dance(20);*/ + /* + 蔡徐坤火了 + 需求:蔡徐坤的类的功能不能改变(.java内容不能改变),但是要给它的唱歌跳舞功能增加一些金额判定 + */ + JingJiRen jingJiRen = new JingJiRen(caiXuKun); + jingJiRen.sing(120); + jingJiRen.dance(30); + } +} diff --git a/s_day13/src/com/inmind/daynamic_proxy_01/Demo03.java b/s_day13/src/com/inmind/daynamic_proxy_01/Demo03.java new file mode 100644 index 0000000..9baa6d5 --- /dev/null +++ b/s_day13/src/com/inmind/daynamic_proxy_01/Demo03.java @@ -0,0 +1,97 @@ +package com.inmind.daynamic_proxy_01; + +import java.lang.reflect.InvocationHandler; +import java.lang.reflect.Method; +import java.lang.reflect.Proxy; +import java.util.Arrays; + + +/* + 静态代理:直接定义一个固定的类,增强某个类的功能(JingJiRen) + 动态代理:不用定义一个固定的类,动态地增强某个类的功能 + + 需求:蔡徐坤的类不能改变,也不能定义新的经纪人类,但是还想对蔡徐坤的唱跳功能,进行增强金额判断,此时只能使用动态代理API + + 装饰设计模式 + 装饰者 被装饰者 作用:装饰者增强被装饰者的功能 + 花瓶 花 花瓶增强了花的好看的程度 + 经纪人 蔡徐坤 经纪人增强了蔡徐坤的唱跳金额的判断功能 + 装饰设计模式的前提:装饰者需要与被装饰者拥有的功能要一致,继承同一个父类或者实现同一个接口 + BufferedReader FileReader 底层封装了缓冲区,提高字符输入流的读取效率 +------------------------------------------------------------------------------------------------------------------------------ + 动态代理模式 + 代理者 被代理者 作用:代理者拦截了被代理者的指定的功能,进行操作 + singerProxy caiXuKun 拦截了caixukun的sing,dance功能进行金额判断 + + 动态代理的前提条件:代理者与被代理者必须要拥有相同的功能,实现同一个接口 + + 装饰设计模式与动态代理的区别: + 1.装饰设计模型:注重功能的增强,拥有更多的功能代码,,它必须实现所有的抽象方法 + 2.动态代理:注重功能方法的拦截,它只需要针对想拦截的方法即可 + */ +public class Demo03 { + public static void main(String[] args) { + CaiXuKun caiXuKun = new CaiXuKun(); + + //动态地创建出代理对象 + //动态代理的参数一:类加载器 + ClassLoader loader = caiXuKun.getClass().getClassLoader(); + + //动态代理的参数二:代理对象与被代理对象要拥有相同的功能,Singer接口 + Class[] interfaces = caiXuKun.getClass().getInterfaces(); + //动态代理的参数三:处理器对象,用来处理代理对象(蔡徐坤)中的业务逻辑 + InvocationHandler h = new InvocationHandler() { + //注意:动态代理对象(singerProxy),调用任意的方法,都会引起以下的invoke方法执行一次!!!! + + /* + invoke方法的三大参数的含义: + 参数一 :proxy,就是动态代理对象singerProxy(不要使用!!!,它会引起递归,导致栈内存溢出错误) + 参数二:method,反射中的Method类,就是当前动态代理对象调用的方法sing,dance,eat,toString等 + 参数三:args,当前动态代理对象调用方法时,传入的参数 + */ + @Override + public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { + /*System.out.println("invoke方法执行了"); + System.out.println(proxy);//打印时会调用proxy的toString方法 + System.out.println(method.getName()); + System.out.println(Arrays.toString(args));*/ + /* + 动态代理增强的代码实现 + 1.如果是sing方法,判断是不是超过100 + 2.如果是dance方法,判断是不是超过50 + */ + String methodName = method.getName(); + if ("sing".equals(methodName)) { + //获取sing的参数 + int money = (int) args[0]; + if (money > 100) { +// caiXuKun.sing(money); +// caiXuKun.sing(money); + method.invoke(caiXuKun, args); + }else{ + System.out.println("钱不够,一遍玩去"); + } + + return null;//如果是sing,单独处理,并提前结束,避免sing方法执行2次 + } + + if ("dance".equals(methodName)) { + int money = (int) args[0]; + if (money > 50) { +// caiXuKun.dance(money); + method.invoke(caiXuKun, args); + } else { + System.out.println("钱不够,玩泥巴去吧"); + } + return null; + } + //除了sing和dance以外的功能方法,都保证原有功能即可 + return method.invoke(caiXuKun, args); + } + }; + Singer singerProxy = (Singer) Proxy.newProxyInstance(loader,interfaces,h); + singerProxy.sing(80); + singerProxy.dance(55); + singerProxy.eat(); + } +} diff --git a/s_day13/src/com/inmind/daynamic_proxy_01/JingJiRen.java b/s_day13/src/com/inmind/daynamic_proxy_01/JingJiRen.java new file mode 100644 index 0000000..178302e --- /dev/null +++ b/s_day13/src/com/inmind/daynamic_proxy_01/JingJiRen.java @@ -0,0 +1,39 @@ +package com.inmind.daynamic_proxy_01; + +public class JingJiRen implements Singer{ + + CaiXuKun caiXuKun; + + public JingJiRen(CaiXuKun caiXuKun) { + this.caiXuKun = caiXuKun; + } + + @Override + public void sing(int money) { + //金额判断,超过100万才让蔡徐坤唱歌 + if (money > 100) { + caiXuKun.sing(money); + } else { + System.out.println("钱不够,一边玩去"); + } + } + + @Override + public void dance(int money) { + //金额判断,超过50万才让蔡徐坤跳舞 + if (money > 50) { + caiXuKun.dance(money); + } else { + System.out.println("钱不够,一边玩去"); + } + } + + @Override + public void eat() { + System.out.println("坤坤没空,你看我怎么样"); + } + + public void method(){ + + } +} diff --git a/s_day13/src/com/inmind/daynamic_proxy_01/Singer.java b/s_day13/src/com/inmind/daynamic_proxy_01/Singer.java new file mode 100644 index 0000000..e561475 --- /dev/null +++ b/s_day13/src/com/inmind/daynamic_proxy_01/Singer.java @@ -0,0 +1,13 @@ +package com.inmind.daynamic_proxy_01; +/* +定义出一个歌手的规范,只要实现该接口的方法,那么对应的类,就算是一个歌手类 + */ +public interface Singer { + + void sing(int money); + + void dance(int money); + + void eat(); + +} diff --git a/s_day13/src/com/inmind/logback_03/LogbackTest.java b/s_day13/src/com/inmind/logback_03/LogbackTest.java new file mode 100644 index 0000000..5a87c8c --- /dev/null +++ b/s_day13/src/com/inmind/logback_03/LogbackTest.java @@ -0,0 +1,32 @@ +package com.inmind.logback_03; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class LogbackTest { + //创建出一个logger对象 + public static final Logger LOGGER = LoggerFactory.getLogger("LogbackTest"); + + public static void main(String[] args) { + + try { + // System.out.println("test方法开始执行了"); + LOGGER.info("test方法开始执行了"); + test(1, 0); + // System.out.println("test方法执行结束了"); + LOGGER.info("test方法执行结束了"); + } catch (Exception e) { + // System.out.println("test方法执行失败,出现了异常"); + LOGGER.error("test方法执行失败,出现了异常"); + } + + } + + public static void test(int a ,int b) { + LOGGER.warn("注意算术除法异常"); + LOGGER.debug("参数a:"+a); + LOGGER.debug("参数b:"+b); + int c = a/b; + System.out.println("结果是:"+c); + } +} diff --git a/s_day13/src/com/inmind/xml_02/Demo01.java b/s_day13/src/com/inmind/xml_02/Demo01.java new file mode 100644 index 0000000..625aae1 --- /dev/null +++ b/s_day13/src/com/inmind/xml_02/Demo01.java @@ -0,0 +1,34 @@ +package com.inmind.xml_02; +/* +XML 被设计用来传输和存储数据,可扩展标记语言 +HTML 被设计用来显示数据。超文本标记语言,用来开发网页 + +可扩展:可以自定义 +标记:标签,<开始标签>标签体 + + +XML 与 HTML 的主要差异 +XML 不是 HTML 的替代。 +XML 和 HTML 为不同的目的而设计: +XML 被设计为传输和存储数据,其焦点是数据的内容。 +HTML 被设计用来显示数据,其焦点是数据的外观。 +HTML 旨在显示信息,而 XML 旨在传输信息。 + + +book{ + name + price + author +} + + + java + 99 + 小王 + + +为什么要了解学习XML?? +今后学习框架,使用xml文件作为配置文件 + */ +public class Demo01 { +} diff --git a/s_day13/src/logback.xml b/s_day13/src/logback.xml new file mode 100644 index 0000000..c0e0a44 --- /dev/null +++ b/s_day13/src/logback.xml @@ -0,0 +1,42 @@ + + + + + + System.out + + + %d{yyyy-MM-dd HH:mm:ss.SSS} [%-5level] %c [%thread] : %msg%n + + + + + + + %d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + utf-8 + + + D:/log/inmind-data.log + + + + D:/log/inmind-data-%i-%d{yyyy-MM-dd}-.log.gz + + 1MB + + + + + + + + + + \ No newline at end of file