Java基础 (一)
基础概念及运算符、判断、循环
基础概念
关键字
数据类型 分为两种
基本数据类型
标识符
运算符
运算符
算术运算符
隐式转换 小 ------>>> 大
强制转换
字符串 拼接符号 +
字符+ 运算
自增自减运算符
i++++i
赋值运算符
赋值运算符 包括 强制转换
关系运算符
逻辑运算符
三元运算符
流程控制
流程控制
if else if else
-------->>>> 适用于范围
int score=100;
if(score>90){System.out.println("A");
}else if(score>80){System.out.println("B");
}else if(score>70){System.out.println("C");
}else if(score>60){System.out.println("D");
}else{System.out.println("E");
}
switch
-------->>>适用于有限个,一 一 列举,进行匹配
Scanner scanner = new Scanner (System.in);System.out.println ("请输入星期几:");int week = scanner.nextInt ();switch (week) {case 1:System.out.println ("星期一");break; // 没有break 会穿透case 2:System.out.println ("星期二");break;case 3:System.out.println ("星期三");break;case 4:System.out.println ("星期四");break;case 5:System.out.println ("星期五");break;case 6:System.out.println ("星期六");break;case 7:System.out.println ("星期日");break;default:System.out.println ("输入错误");break;}
case 穿透
Scanner scanner = new Scanner (System.in);
System.out.println ("请输入星期几:");
int week = scanner.nextInt ();
switch (week) {case 1:case 2:case 3:case 4:case 5:System.out.println ("工作日");break;case 6:case 7:System.out.println ("节假日");break;default:System.out.println ("输入错误");break;
}
循环
循环
for 循环
//求1-5的和
int sum=0;for (int i = 1; i <= 5; i++) {sum+=i;
}System.out.println (sum);
int sum=0;
// 无限循环
for (;;) {System.out.println (sum++);
}
while (true){}// 键盘录入两个数字,实现这两个数字之间的偶数和
Scanner scanner = new Scanner (System.in);System.out.println("请输入第一个数字:");
int start = scanner.nextInt();System.out.println("请输入第二个数字:");
int end = scanner.nextInt();int sum = 0;
for (int i = start; i <= end; i++) {if (i % 2 == 0) {sum += i;}
}System.out.println("这两个数字之间的偶数和为:" + sum);scanner.close();
while
// 编写一个程序,珠穆朗玛峰高度8843.8米,现有一张0.1毫米的厚度的纸,请问,折叠多少次后,可以达到珠穆朗玛峰的高度。
double paperThickness = 0.1; // 纸张厚度,单位:毫米
double everestHeight = 8843.8 * 1000; // 珠穆朗玛峰高度,单位:毫米int foldCount = 0; // 折叠次数
double foldedThickness = paperThickness; // 折叠后的厚度
// 不知道循环结束条件,用while循环
while (foldedThickness < everestHeight) {foldedThickness *= 2; // 每次折叠后厚度翻倍foldCount++;
}System.out.println("需要折叠 " + foldCount + " 次才能达到珠穆朗玛峰的高度。");
跳转语句
continue
与break
for (int i = 1; i <=5; i++) {if (i==3)continue;System.out.println ("小老虎在吃第"+i+"个包子");
}for (int i = 1; i <=5; i++) {if (i==4)break;System.out.println ("小老虎在吃第"+i+"个包子");}// 求平方根,只保留整数部分
int num = new Scanner (System.in).nextInt ();
for (int i = 1; i <=num; i++) {// 等于的话也进入下次循环if(i*i>num){System.out.println (i-1);break;}}
数组、方法、方法引用、Stream流
数组
数组
int[] nums=new int[]{1,2,3,4,5,6,7,8,9};
// 定义一个数组,长度为20,默认初始化元素为0
int[] nums2=new int[20];for (int num : nums) {System.out.println (num);
}
System.out.println (nums[5]);// 获取第六个元素,下标从0开始
System.out.println (nums);// 打印的是地址
求最值
// 求数组中的最大值
int [] arr=new int[]{33,5,22,44,55};
int max=arr[0]; // 不至于 得不到答案,如果是-1,可能没有答案for (int i = 0; i < arr.length; i++) {if(arr[i]>max){max=arr[i];}
}
System.out.println ( max);
创建数组
// 创建一个长度为10的数组,数组元素是随机生成的1-10的整数
int [] arr=new int[10];// 遍历数组,为每个元素赋值
for (int i = 0; i < 10; i++) {int num = new Random ().nextInt (10)+1;arr[i]=num;
}
// 计算数组元素的平均值
Double avg = Arrays.stream (Arrays.stream (arr).toArray ()).average ().getAsDouble ();
// 输出数组元素
for (int i : arr) {if(i<avg)System.out.println (i);
}// 交换数组中元素的位置
int left=0,right=arr.length-1;
while (left<right){int temp=arr[left];arr[left]=arr[right];arr[right]=temp;left++;right--;
}
方法与方法重载
写方法时,最好画出 代码流程图
代码流程图
方法
程序中 最小的执行单元
public class Test {public static void main(String[] args) {// 静态方法可以调用静态方法// 非 静态方法只能调用 非静态方法printNum ();}public static void printNum(){int num1=5;int num2=10;System.out.println (num1+num2);
}
}
带参数方法的调用
public static void main(String[] args) {int sum = add (10, 20);System.out.println (sum);}// 带参数,带返回值
public static int add( int num1, int num2 ) {int sum = num1 + num2;return sum;
}public static void main(String[] args) {int sum = add (10, 20,30);System.out.println (sum);}
// 参数构成数组
public static int add( int... ags ) {return ags[0] + ags[1];
}
计算面积
public static void main(String[] args) {double area = getArea (10,20);System.out.println ("面积是:"+area);}public static double getArea( double length, double width ) {return length * width; // 返回面积}
方法重载
同类,名同参不同
public static void main(String[] args) {double area1 = getArea (10,20);double area2 = getArea (5.0);System.out.println ("矩形面积是:"+area1);System.out.println ("圆的面积是:"+area2);}// 方法重载// 矩形面积
public static double getArea( double length, double width ) {return length * width; // 返回面积
}
// 圆的面积
public static double getArea( double radius ) {return 3.14*radius*radius; // 返回面积
}
public static void main(String[] args) {int [] arr = {1,2,3,4,5,6,7,8,9,10};boolean contains = contains (arr, 11);System.out.println (contains);}// 判断一个数组中是否包含某个元素
public static boolean contains( int[] arr, int target ) {for (int num : arr) {if(num == target){return true;}}return false;}
基本数据类型 与 引用类型
方法的值传递
基本数据类型
传递的是 真实的数据
引用数据类型
传递的是 地址
public static void main(String[] args) {int num = 10;System.out.println ("修改前的值:" + num);change (num);System.out.println ("修改后的值:" + num);}
// 值传递,基本数据类型 传的是副本
public static void change( int num) {num = 20;System.out.println ("change:" + num);
}
// 统计101-200 之间的质数个数
public static void main(String[] args) {int count=0;for (int i = 101; i <=200; i++) {boolean flag=true;for(int j=2;j<i;j++){if(i%j==0){flag=false;break; // 跳出单层循环,即 内层循环}}if(flag) count++;}System.out.println("质数个数:"+count);}
/*
* 定义一个方法,实现验证码的功能
* 5位
* 前四位为大写字母或者小写字母
* 最后一位为数字 0-9
* */public static void main(String[] args) {// 定义一个数组,存储大小写字母char[] dict=new char[52];for (int i = 0; i < 52; i++) {if(i<=25){dict[i]=(char)('a'+i);}else {dict[i]=(char)('A'+i-26);}}// 随机生成一个数字int num=new Random ().nextInt (10);String code="";// 随机生成4个字母for (int i = 0; i < 4; i++) {int idx = new Random ().nextInt (52);code+= dict[idx];}// 拼接数字code+=num;System.out.println (code);}
抽取奖金
/*
* 定义一个方法,实现抽奖的功能
* 奖金:{2,288,588,1000,10000}
* 代码模拟抽奖,打印出每个奖项,奖项的出现顺序要随机且不重复
* 概率:{90,4,3,2,1}
*
* */public static void main(String[] args) {// 定义一个数组,存储奖金int[] rewards={2,288,588,1000,10000};// 定义一个数组,存储奖金是否被抽中boolean[] isAwarded=new boolean[5];// 定义随机数模拟概率,概率为90的,随机数为0-89,概率为4的,随机数为90-93,以此类推// 模拟抽奖1000次for (int i = 0; i < 1000; i++) {int num=new Random ().nextInt (10000);if(num<9000){getReward (rewards, isAwarded, 0);} else if (num < 9400) {getReward (rewards, isAwarded, 1);} else if (num < 9700) {getReward (rewards, isAwarded, 2);} else if (num < 9990) {getReward (rewards, isAwarded, 3);}else getReward (rewards, isAwarded, 4);}}private static void getReward(int[] rewards, boolean[] isAwarded, int i) {if(!isAwarded[i]){int reward = rewards[i];System.out.println ("获得奖金"+reward);isAwarded[i]=true;}//else {// System.out.println (rewards[i]+"已被抽取");//}
}
二维数组
// 这样定义 结构更加清晰
int [] [ ] arr=new int[][]{{1,2,3},{4,5,6},{7,8,9}
};
// 动态赋值
int [][] arr1=new int[3][3];for (int i = 0; i < arr.length; i++) {for (int j = 0; j < arr[i].length; j++) {System.out.print (arr[i][j] +" ");}System.out.println ();
}
Lambda表达式
public class Test {public static void main(String[] args) {swim ( // 匿名内部类,创建的时 实现Swim接口的对象new Swim () {@Overridepublic void Swimming() {System.out.println ("正在游泳");}});} static void swim(Swim s){s.Swimming ();}}
interface Swim{void Swimming();}
public class Test {public static void main(String[] args) {swim ( // Lambda表达式改写匿名内部类// 无参 无返回值()-> System.out.println ("游泳"));}static void swim(Swim s){s.Swimming ();}}// 看作函数式接口
// 无参数 无返回值
@FunctionalInterface
interface Swim{void Swimming();}
String[] strings={"s12","s244","s57773","4","s123"};// 按照字符串的长度排序
Arrays.sort (strings,(o1,o2)->o1.length ()-o2.length ());
System.out.println (Arrays.toString (strings));
Stream流
Stream流
ArrayList<String> strs = new ArrayList<> ();
Collections.addAll (strs,"s12","s244","s57773","4","s123","s234");
strs.stream ().forEach ((s)->System.out.print(s+" "));
Stream 流的创建
//第 一种 实现或继承 Collection接口的集合
// 如list.set 直接调用 stream() 方法
List<Integer> ids = Arrays.asList(10, 20, 30, 40, 50);
ids.stream();
Set<String> sets = new HashSet<>();
sets.stream();
// 数组使用 Arrays.stream(array) 转未Stream流
Integer[] array = new Integer[]{1, 5, 5, 8, 6, 7, 9, 5};
Stream<Integer> stream = Arrays.stream(array);//Stream.of()
Integer min = Stream.of(1, 2, 3)//获取 最小值.min(Comparator.comparingInt(x -> x)).get();
System.out.println(min); //1Integer max = Stream.of(1, 2, 3)//获取 最大值.max(Comparator.comparingInt(x -> x)).get();
System.out.println(max); //3
案例
public static void main(String[] args) {ArrayList<String> strs = new ArrayList<> ();
Collections.addAll (strs,"张无忌","周琦若","赵敏","张强","张三丰","张良","谢广坤","王二麻子");
strs.stream ().filter (s->s.startsWith ("张")).limit (3)// 跳过哪一个.skip (1).forEach (System.out::println);}Collections.addAll (strs,"张无忌-15","周琦若-24","赵敏-34","张强-29","张三丰-22","张良-18","谢广坤-27","王二麻子-26");
// 只获取年龄,并打印
strs.stream ().map (s->s.split ("-")[1]).forEach (System.out::println);
collect 收集
public static void main(String[] args) {ArrayList<String> strs = new ArrayList<> ();Collections.addAll (strs,"张无忌-男-15","周琦若-女-24","赵敏-女-34","张强-男-29","张三丰-男-22","张良-男-18","谢广坤-男-27","王银-女-26");// 收集所有男性的名字List<String> stringList = strs.stream ().filter (s -> "男".equals (s.split ("-")[1])).map (s -> s.split ("-")[0]).collect (Collectors.toList ());stringList.forEach (System.out::println);}// 收集所有男性的名字
/* List<String> stringList = strs.stream ().filter (s -> "男".equals (s.split ("-")[1])).map (s -> s.split ("-")[0]).collect (Collectors.toList ());
stringList.forEach (System.out::println);
*/// 收集为Map集合
Map<String, Integer> mans = strs.stream ().filter (s -> s.split ("-")[1].equals ("男")).collect (Collectors.toMap (s -> s.split ("-")[0],s -> Integer.parseInt (s.split ("-")[2])));
mans.forEach ((k,v)->System.out.println (k+" "+v));
}
练习
/*
* 定义一个集合,添加一些整数 1,2,3,4,5,6,7,8,9,10
* 过滤掉所有奇数,只保留偶数
* 并将结果保存
* */
public static void main(String[] args) {//定义一个集合,数组形式int[] nums = {1,2,3,4,5,6,7,8,9,10};int[] ints = Arrays.stream (nums).filter (n -> n % 2 == 0).toArray ();System.out.println (Arrays.toString (ints));// 定义一个集合,list形式ArrayList<Integer> list = new ArrayList<> ();Collections.addAll (list,1,2,3,4,5,6,7,8,9,10);//过滤掉所有奇数,只保留偶数List<Integer> integers = list.stream ().filter (n -> n % 2 == 0).collect (Collectors.toList ());System.out.println (integers);
}
/** 定义一个ArrayList集合,添加以下字符串 前面是姓名,后面是年龄* zhangsan,23* lisi,24* wangwu,25* 保留年龄大于等于24岁的人,并将结果收集到Map集合中,姓名为键,年龄为值* */public static void main(String[] args) {ArrayList<String> list = new ArrayList<> ();Collections.addAll (list, "zhangsan,23", "lisi,24", "wangwu,25");Map<String, Integer> map = list.stream ().filter (s -> Integer.parseInt (s.split (",")[1]) >= 24).collect (Collectors.toMap (s -> s.split (",")[0],s -> Integer.parseInt (s.split (",")[1])));map.forEach ((k, v) -> System.out.println (k + " " + v));// System.out.println (map);}
public class Actor {@Overridepublic String toString() {return "Actor{" +"name='" + name + '\'' +", age=" + age +'}';}private String name;private int age;public Actor(String s) {String[] split = s.split (",");this.name = split[0];this.age = Integer.parseInt (split[1]);}public Actor(String name, int age) {this.name = name;this.age = age;}public String getName() {return name;}public void setName(String name) {this.name = name;}
}/*
* 两个 ArrayList集合,分别存储 6名男演员与 6名女演员姓名和年龄 ,格式为:
* 张三,23* 要求:
* 男演员只要名字为3个字的前两人
* 女演员只要姓杨的,并且不要第一个
* 最后将过滤后的男演员和女演员合并到一起
* 将上一步的演员对象封装成Actor 对象
* 将所有演员对象都保存到ArrayList集合中
* 演员类的成员变量:name, age
*
* 男演员: "蔡徐坤,24", "刘不甜,28", "古天,35", "吴签,30", "肖梁梁,37","张国荣,32"
* 女演员: "赵丽颖,19", "杨颖,20", "张天爱,35", "张敏,35", "高圆圆,40","刘诗诗,32"
* */
public static void main(String[] args) {ArrayList<String> man = new ArrayList<> ();ArrayList<String> woman = new ArrayList<> ();// 添加元素Collections.addAll (man, "蔡徐坤,24", "刘不甜,28", "古天,35", "吴签,30", "肖梁梁,37", "张国荣,32");Collections.addAll (woman, "赵丽颖,19", "杨颖,20", "张天爱,35", "杨幂,35", "高圆圆,40", "刘诗诗,32");// 男演员只要名字为3个字的前两人Stream<String> stream1 = man.stream ().filter (s -> s.split (",")[0].length () == 3).limit (2);// 女演员只要姓杨的,并且不要第一个Stream<String> stream2 = woman.stream ().filter (s -> s.split (",")[0].startsWith ("杨")).skip (1);// 最后将过滤后的男演员和女演员合并到一起// 将上一步的演员对象封装成Actor 对象// 将所有演员对象都保存到ArrayList集合中List<Actor> res = Stream.concat (stream1, stream2).map (Actor::new).collect (Collectors.toList ());// 打印System.out.println (res);for (Actor actor : res) {System.out.println (actor);}}
更多请查询
Stream流
方法引用
方法引用
引用静态方法
Integer [] arr={7,1,5,4,6,8,4,3};
// 匿名内部类
Arrays.sort (arr, new Comparator<Integer>(){@Overridepublic int compare(Integer o1, Integer o2) {return o1-o2;}
});
System.out.println (Arrays.toString (arr));// lambda表达式
Arrays.sort (arr, (o1,o2)-> o2-o1);
System.out.println (Arrays.toString (arr));
// 方法引用
Arrays.sort (arr, Test::sub);
System.out.println (Arrays.toString (arr));}// 必须是静态类,因为静态方法只能访问静态方法
private static int sub(int num1, int num2) {return num1-num2;
}
ArrayList<String> list = new ArrayList<> ();
Collections.addAll (list,"1","2","3","4","5");
list.stream ().map (Integer::parseInt).forEach (s-> System.out.println (s));
引用成员方法
/*方法引用(引用成员方法)格式三种:其他类: 其他类对象::方法名本类: this::方法名 (非 静态方法使用)父类: super::方法名 (非 静态方法使用)需求:集合中有一些名字,按照要求过滤数据:张无忌,周琦若,赵敏,张强,张三丰要求: 只要以张开头,且名字是三个字的* */public static void main(String[] args) {ArrayList<String> list = new ArrayList<> ();Collections.addAll (list,"张无忌","周琦若","赵敏","张强","张三丰");/* list.stream ().filter (s->s.startsWith ("张")).filter (s->s.length ()==3).forEach (System.out::println);*//* list.stream ().filter (new Predicate<String> () {@Overridepublic boolean test(String s) {return s.startsWith ("张")&&s.length ()==3;}}).forEach (System.out::println);*/// 其他类对象::方法名list.stream ().filter (new StringOperation()::stringJudge).forEach (System.out::println);// 静态方法中 没有 this和super/* list.stream ().filter (this::stringJudge).forEach (System.out::println);*/
}
引用 构造方法
public class Student {@Overridepublic String toString() {return "Student{" +"name='" + name + '\'' +", age=" + age +'}';}private String name;private int age;public Student(String name, int age) {this.name = name;this.age = age;}public int getAge() {return age;}public void setAge(int age) {this.age = age;}// 构造方法 没有返回值,生成的对象 与返回值类型一致即可public Student(String s) {String[] split = s.split (",");this.name = split[0];this.age = Integer.parseInt (split[1]);}public String getName() {return name;}public void setName(String name) {this.name = name;}
}
/*方法引用(引用构造方法)格式三种:类名::new需求:集合存储 姓名和年龄,要求封装成Student对象并收集到List集合中* */public static void main(String[] args) {ArrayList<String> list = new ArrayList<> ();Collections.addAll (list,"张无忌,15","周琦若,14","赵敏,13","张强,20","张三丰,40","张良,35");
/* list.stream ().map (s -> {String[] split = s.split (",");String name = split[0];int age = Integer.parseInt (split[1]);return new Student (name,age);}).forEach (s -> System.out.println (s.toString ()));*/list.stream ().map (Student::new).forEach (s -> System.out.println (s.toString ()));}
使用 类名引用成员方法
/*方法引用(类名引 用成员方法)格式三种:类名::成员方法需求:集合存储 一些字符串,要求变成大写后,打印输出* */public static void main(String[] args) {ArrayList<String> list = new ArrayList<> ();Collections.addAll (list,"aaaa","bbb","cccd","dddd");// 变成大写list.stream ().map (String::toUpperCase).forEach (s -> System.out.println (s));}// 引用数组的构造方法
public static void main(String[] args) {ArrayList<Integer> list = new ArrayList<> ();Collections.addAll (list,1,2,3,5,47,9,45,6,4,8,7);// 集合转数组,数组的类型要与 流中的类型一致Integer[] integers = list.stream ().toArray (Integer[]::new);System.out.println (Arrays.toString (integers));}
面向对象
概念
概念
注意
面向对象
编程,
遍历集合 就是 操作集合中的 每一个对象!
调用方法,就是 对传入的值进行修改
// 得到随机对象,用于获取随机数Random random = new Random ();int num = random.nextInt (10) + 1;System.out.println (num);// 创建一个Scanner 对象,用于接受用户获取的数据Scanner scanner=new Scanner (System.in);System.out.println ("请输入一个整数:");int anInt = scanner.nextInt ();System.out.println ("你输入的数字是:"+anInt);
public class Phone {// 属性:成员变量private String brand;private double price;public Phone() {}public String getBrand() {return brand;}public void setBrand(String brand) {this.brand = brand;}public double getPrice() {return price;}public void setPrice(double price) {this.price = price;}public Phone(String brand, double price) {this.brand = brand;this.price = price;}// 行为:方法public void call() {System.out.println ("我在使用"+this.brand+"打电话");}public void sendMessage() {System.out.println ("我在使用"+this.brand+"发短信");}
}public static void main(String[] args) throws Exception {Phone p = new Phone();p.setBrand ("华为");p.setPrice (1000);System.out.println (p.getBrand ());System.out.println (p.getPrice ());p.call ();}
封装
理解为: XXX 操作 XXX类
谁 `被动``,谁就 提供方法,即 数据对应的行为~~~~
修饰符:
1、private:当前 类,只能 在本类中才能 被访问
2、缺省:本类和 同包下的类
3、public :任何 位置
4、protected:子类 和 同包下的类 和 本类
public class GirlFriend {private String name;private int age;private String gender;public GirlFriend(String name, int age, String gender) {this.name = name;this.age = age;this.gender = gender;}public GirlFriend() {}public String getName() {return name;}public void setName(String name) {this.name = name;}public int getAge() {return age;}// age在该类中,该行为 由该类提供public void setAge(int age) {if (age < 0 || age > 60) {throw new IllegalArgumentException ("年龄必须在0到60之间");}this.age = age;}public String getGender() {return gender;}public void setGender(String gender) {this.gender = gender;}
}public static void main(String[] args) throws Exception {GirlFriend girlFriend = new GirlFriend ();girlFriend.setAge (70);}
构造方法
public GirlFriend(String name, int age, String gender) {this (name, gender); // this调用 该对象另一个构造方法this.age = age;}public GirlFriend(String name, String gender) {this.name = name;this.gender = gender;}public GirlFriend() {}
标准的Java Bean
public class GirlFriend {private String name;private String gender;private int age = 20;// 空参构造public GirlFriend() {}// 全参构造public GirlFriend(String name, String gender, int age) {this.name = name;this.gender = gender;this.age = age;}/*** 获取** @return name*/public String getName() {return name;}/*** 设置** @param name*/public void setName(String name) {this.name = name;}/*** 获取** @return gender*/public String getGender() {return gender;}/*** 设置** @param gender*/public void setGender(String gender) {this.gender = gender;}/*** 获取** @return age*/public int getAge() {return age;}/*** 设置** @param age*/public void setAge(int age) {this.age = age;}public String toString() {return "GirlFriend{name = " + name + ", gender = " + gender + ", age = " + age + "}";}
}
安装PTG 插件
成员变量与局部变量
内存图分析
面向对象综合联系
格斗游戏
public class Role {private String name;// 满值 100private int blood;public Role() {}public Role(String name, int blood) {this.name = name;this.blood = blood;}/*** 获取** @return name*/public String getName() {return name;}/*** 设置** @param name*/public void setName(String name) {this.name = name;}/*** 获取** @return blood*/public int getBlood() {return blood;}/*** 设置** @param blood*/public void setBlood(int blood) {this.blood = blood;}public String toString() {return "Role{name = " + name + ", blood = " + blood + "}";}// 定义一个方法攻击别人// 谁攻击谁? 攻击的目标是谁? 攻击的次数? 每次攻击的伤害值?//调用者攻击别人public void attack(Role role) {// 随机生成血量 0-100Random random = new Random ();int num = random.nextInt (100) + 1;// 攻击前检查 血量,若血量<=0,目标已经死亡,不能再攻击if (role.getBlood () <= 0) {System.out.println ("角色已经阵亡,不能再攻击");return;}// 攻击,更新角色的血量,若攻击后血量<=0,目标已阵亡int remainBlood = role.getBlood () - num;role.setBlood (remainBlood);// 防止血量为负数if (remainBlood < 0) remainBlood = 0;System.out.println (this.getName () + "攻击了:" + role.getName ()+ ",造成了:" + num + "点伤害,"+role.getName ()+"剩余血量:" + remainBlood);if (remainBlood <= 0) System.out.println (role.getName () + "已经阵亡");}}
public static void main(String[] args) throws Exception {Role role = new Role ("张三", 100);Role role2 = new Role ("李四", 100);/* // 张三攻击李四role.attack (role2);role2.attack (role);*/while (true){// 格斗,即相互攻击// 张三攻击李四role.attack (role2);// 打完之后检查血量,防止死亡后继续攻击if (role2.getBlood () <= 0){// %s 表示占位符,%s 表示字符串类型的占位符System.out.printf ( "%s赢了", role.getName ());System.out.println ();break;}// 李四攻击张三role2.attack (role);if (role.getBlood () <= 0){System.out.println (role2.getName () + "赢了");break;}}}
对象数组
// 商品数组// Goods[] goods = new Goods[3];// 创建三个商品对象,存到数组中ArrayList<Goods> list = new ArrayList<> ();// 创建三个商品对象,存到数组中,也可以键盘录入,获取 从前端获取信息Goods cmp = new Goods ("001", "电脑", 3000, 10);Goods cup = new Goods ("002", "保温杯", 50, 30);Goods phone = new Goods ("003", "收集", 1000, 20);Collections.addAll (list, cmp, cup, phone);System.out.println (list);
public static void main(String[] args) throws Exception {/*** 定义一个长度为3的数组,存储1~3名学生对象作为初始数据,学生对象的学号,姓名各不相同* 学生属性:学号,姓名,年龄* 要求1:再次添加一个学生对象,并在添加的时候进行学号的唯一性判断* 要求2:添加完毕之后,遍历所有学生信息* 要求3:通过id删除学生信息* 如果存在,删除,如果不存在,提示删除失败* 要求4:删除完毕之后,遍历所有学生信息* 要求5:查询数组id为“heima002”的学生,如果存在,则将他的年龄+1**/// 1.定义一个长度为3的数组,存储 1~3名学生对象作为初始数据,学生对象的学号,姓名各不相同Student[] students = new Student[3];students[0] = new Student ("heima001", "张三", 18);students[1] = new Student ("heima002", "李四", 19);students[2] = new Student ("heima003", "王五", 20);// 2.要求 1:再次添加一个学生对象,并在添加的时候进行学号的唯一性判断Student student = new Student ("heima004", "赵六", 21);// 定义一个变量,用于记录学号 是否存在boolean flag = false;flag = isExist (students, student.getId (), flag);if (flag) {System.out.println ("学号已存在,添加失败");} else {// 学号 不存在,创建新数组,移动元素,添加新的学生对象// 2.1 创建一个新的数组,长度为 原数组长度+1Student[] newStudents = new Student[students.length + 1];// 2.2 遍历原数组,将原数组中的元素复制到新数组中for (int i = 0; i < students.length; i++) {newStudents[i] = students[i];}// 2.3 将新的学生对象添加到新数组的最后一个位置newStudents[newStudents.length - 1] = student;// 2.4 将新数组赋值给原数组students = newStudents;System.out.println ("添加成功");}// 3.要求2:添加完毕之后,遍历所有学生信息for (int i = 0; i < students.length; i++) {if (students[i] != null) {System.out.println (students[i].getId () + "," + students[i].getName () + "," + students[i].getAge ());}}// 4.要求3:通过id删除学生信息// 如果存在,删除,如果不存在,提示删除失败String id = "heima002";boolean flag2 = false;boolean exist = isExist (students, id, flag2);if (exist) {// 存在,删除// 4.1 创建一个新的数组,长度为 原数组长度-1Student[] newStudents = new Student[students.length - 1];// 4.2 遍历原数组,将原数组中的元素复制到新数组中int index = 0;for (int i = 0; i < students.length; i++) {if (students[i] != null && !students[i].getId ().equals (id)) {newStudents[index] = students[i];index++;}}} else {System.out.println ("删除失败");}// 5.要求4:删除完毕之后,遍历所有学生信息Arrays.stream (students).forEach (System.out::println);// 6.要求5:查询数组id为“heima002”的学生,如果存在,则将他的年龄+1boolean flag3 = false;flag3 = isExist (students, id, flag3);// 7.如果存在,将他的年龄+1if (flag3) {for (int i = 0; i < students.length; i++) {if (students[i] != null && students[i].getId ().equals (id)) {students[i].setAge (students[i].getAge () + 1);}}} else {System.out.println ("查询失败");}}private static boolean isExist(Student[] students, String id, boolean flag) {for (int i = 0; i < students.length; i++) {if (students[i] != null && students[i].getId ().equals (id)) {flag = true;break;}}return flag;}
继承
问题: 很多 内容重复
解决:抽取 共同部分
概念
什么时候使用 继承
下面 这种情况 没 必要使用继承
, 子类 不是 父类的一种 !!!
继承的特点 和继承体系
// 默认继承object类
public class Student extends Object
设计继承结构
TaiDi taiDi = new TaiDi ();taiDi.eat ();taiDi.water ();taiDi.touch ();taiDi.lookDoor ();
将父类的方法改为 private
public class Dog extends Animal{private void lookDoor() {System.out.println("看门");}
}
子类 能继承父类的哪些内容 ?
继承中 成员变量和成员方法的 访问特点
public class Person {public void eat() {System.out.println ("吃饭");}public void drink() {System.out.println ("喝水");}
}class OverSeasStudent extends Person {// 重写方法@Overridepublic void eat() {System.out.println ("吃意大利面");}@Overridepublic void drink() {System.out.println ("喝可口可乐");}void lunch() {// 调用该对象的 方法this.eat ();this.drink ();// 调用父类的方法super.eat ();super.drink ();}}
测试:
public static void main(String[] args) throws Exception {OverSeasStudent seasStudent = new OverSeasStudent ();seasStudent.lunch ();}
继承中的 构造方法和 this、super关键字
public class Person {private String name;private int 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;}public Person() {System.out.println ("父类的无参构造");}public Person(String name, int age) {this.name = name;this.age = age;System.out.println ("父类的有参构造");}}/*** 子类继承父类的 成员变量* 但是 不能直接访问,需要调用get/set 方法*/
class OverSeasStudent extends Person {public OverSeasStudent() {super (); // 调用父类的无参构造System.out.println ("子类的无参构造");}public OverSeasStudent(String name, int age) {super (name, age); // 调用父类的有参构造System.out.println ("子类的有参构造");}public void lunch() {System.out.println ("吃大餐");}}
OverSeasStudent seasStudent = new OverSeasStudent ("张三",26);System.out.println (seasStudent.getAge ());
多态
认识 多态
多态的 应用场景
Person类中 添加 show() 方法
子类 继承
父类,重写 show() 方法
public class Student extends Person {private String gender;public Student() {}public Student(String name, int age, String gender) {super (name, age);this.gender = gender;}@Overridepublic void show() {System.out.println (this.getName () + "show");// 子类继承父类的属性,两者一样System.out.println ("子类继承父类的属性 和父类属性一样"+(this.getName () == super.getName ())); // trueSystem.out.println (toString ());}@Overridepublic String toString() {return "Student{" + "name=" + this.getName () + ",age=" + this.getAge () + ",gender=" + this.gender + "}";}
}
public static void main(String[] args) throws Exception {register (new Student ("张三", 23, "男"));}/*** 这个方法既能接受老师,又能接受学生*/public static void register(Person person) {// instanceof 判断为 哪种类型System.out.println ("Person为 Student类:" + (person instanceof Student));person.show ();}
多态调用成员的 特点
方法调用,运行 看右边,实际是: 子类 有没有 重写父类的方法
变量调用, 运行 看左边,实际是: 子类 无法
重写父类的 属性
public class Person {String chacter = "人";
}public class Student extends Person {String chacter = "学生";
}
public static void main(String[] args) throws Exception {Student student = new Student ();String chacter = student.chacter;System.out.println (chacter); // 输出结果为:学生Person person=student;String chacter1 = person.chacter;System.out.println (chacter1); // 输出结果为:人}
向下转型
Person person = new Student ();// 向下转型// 先判断是不是这个类型,再转System.out.println (person instanceof Student);if (person instanceof Student) {Student student = (Student) person;String chacter = student.chacter;System.out.println (chacter); // 输出结果为:学生}
System.out.println (person instanceof Student);if (person instanceof Student) {// 向下转型Student student = (Student) person;// 调用子类的独有方法student.study ();String chacter = student.chacter;System.out.println (chacter); // 输出结果为:学生}
抽象类、抽象方法
作用
抽象方法 所在的类必须是 抽象类
定义格式
注意事项
父类
public abstract class Person {private String name;private int age;/*** 抽象类 可以有构造方法* 但是 不能实例化** @param name* @param age*/public Person(String name, int age) {this.name = name;this.age = age;}public Person() {}//public abstract void work();/*** 抽象类 可以有普通方法* 抽象类的普通方法 可以有方法体*/public void show() {System.out.println ("来吧...展示");}// 模板,每个子类的实现不同 !!!// 强制子类 必须按照这种 格式重写~public abstract void eat();}
子类
/*** 子类继承抽象类* 必须 实现抽象类中的 抽象方法* 如果子类也是抽象类 可以 不实现抽象方法*/
public class Student extends Person {@Overridepublic void eat() {System.out.println ("学生吃饭");}
}public class Teacher extends Person {@Overridepublic void eat() {System.out.println ("老师吃米饭");}
}
接口
定义和使用
练习
父类
public abstract class Animal {private String name;private int age;public Animal() {}public Animal(String name, int age) {this.name = name;this.age = age;}/*** 获取** @return name*/public String getName() {return name;}/*** 设置** @param name*/public void setName(String name) {this.name = name;}/*** 获取** @return age*/public int getAge() {return age;}/*** 设置** @param age*/public void setAge(int age) {this.age = age;}public String toString() {return "Animal{name = " + name + ", age = " + age + "}";}/*** 抽象方法* 不同子类 重写该方法*/public abstract void eat();
}
接口:各种各样的 行为规则
public interface Swim {public abstract void swim();
}public interface Say {public abstract void sayEn();
}
兔子:
public class Rabbit extends Animal {public Rabbit() {}public Rabbit(String name, int age) {super (name, age);}@Overridepublic void eat() {System.out.println ("兔子吃胡萝卜");}
}
狗:
public class Dog extends Animal implements Swim {public Dog() {}public Dog(String name, int age) {super (name, age);}@Overridepublic void eat() {System.out.println ("狗吃骨头");}@Overridepublic void swim() {System.out.println ("狗会游泳");}
}
青蛙:
public class Frog extends Animal implements Swim{public Frog() {}public Frog(String name, int age) {super (name, age);}@Overridepublic void eat() {System.out.println ("青蛙吃虫子");}@Overridepublic void swim() {System.out.println ("青蛙会游泳");}
}
测试:
public static void main(String[] args) throws Exception {Frog f1 = new Frog ("小青1", 2);Frog f2 = new Frog ("小青2", 3);System.out.println (f1.getName () + " " + f1.getAge ());System.out.println (f2.getName () + " " + f2.getAge ());f1.eat ();f1.swim ();}
接口中 成员的特点
接口和抽象类 综合案例
public abstract class Player {private String name;private int age;public Player() {}public Player(String name, int age) {this.name = name;this.age = age;}/*** 不同的运动员 打不同的球*/public abstract void studyBall();/*** 获取* @return name*/public String getName() {return name;}/*** 设置* @param name*/public void setName(String name) {this.name = name;}/*** 获取* @return age*/public int getAge() {return age;}/*** 设置* @param age*/public void setAge(int age) {this.age = age;}public String toString() {return "Player{name = " + name + ", age = " + age + "}";}
}
public abstract class Coach {private String name;private int age;public Coach() {}public Coach(String name, int age) {this.name = name;this.age = age;}/*** 不同的教练 教不同的球*/public abstract void teachBall();/*** 获取* @return name*/public String getName() {return name;}/*** 设置* @param name*/public void setName(String name) {this.name = name;}/*** 获取* @return age*/public int getAge() {return age;}/*** 设置* @param age*/public void setAge(int age) {this.age = age;}public String toString() {return "Coach{name = " + name + ", age = " + age + "}";}
}
接口应用
public interface Say {/*** 接口中的 变量默认是 常量*/public static final String NAME = "张三";void sayEn();/*** 接口中的 静态方法*/public static void show() {System.out.println ("来吧...展示" + ":接口中的 静态方法");}public default void show2() {System.out.println ("来吧...展示" + ":接口中的 默认方法");}/*** JDK 1.9 开始 接口中可以定义 私有方法*//*private static void show3() {System.out.println ("来吧...展示" + ":接口中的 私有静态方法");}*/
}
内部类
定义
车 依赖发动机
/*** 汽车类*/public class Car {private String carName;private int carAge;private String carColor;public Car() {}public Car(String carName, int carAge, String carColor) {this.carName = carName;this.carAge = carAge;this.carColor = carColor;}public void show() {System.out.println ("汽车的名字是:" + this.carName);System.out.println ("汽车的年龄是:" + this.carAge);// 外部类访问内部类的成员,需要通过内部类的对象访问Engine engine = new Engine ();System.out.println (engine.getEngineName ());System.out.println (engine.getEngineAge ());}/*** 获取** @return carName*/public String getCarName() {return carName;}/*** 设置** @param carName*/public void setCarName(String carName) {this.carName = carName;}/*** 获取** @return carAge*/public int getCarAge() {return carAge;}/*** 设置** @param carAge*/public void setCarAge(int carAge) {this.carAge = carAge;}/*** 获取** @return carColor*/public String getCarColor() {return carColor;}/*** 设置** @param carColor*/public void setCarColor(String carColor) {this.carColor = carColor;}public String toString() {return "Car{carName = " + carName + ", carAge = " + carAge + ", carColor = " + carColor + "}";}/*** 内部类,代表汽车的发动机* 外部类 访问内部类,需要通过外部类的对象访问* private 只能在 外部类中访问,其他的不允许创建对象*/private class Engine {private String engineName;private int engineAge;public Engine(String engineName, int engineAge) {this.engineName = engineName;this.engineAge = engineAge;}public Engine() {}/*** 获取** @return engineName*/public String getEngineName() {return engineName;}/*** 设置** @param engineName*/public void setEngineName(String engineName) {this.engineName = engineName;}/*** 获取** @return engineAge*/public int getEngineAge() {return engineAge;}/*** 设置** @param engineAge*/public void setEngineAge(int engineAge) {this.engineAge = engineAge;}public String toString() {return "Engine{engineName = " + engineName + ", engineAge = " + engineAge + "}";}}}
public static void main(String[] args) throws Exception {Car car = new Car ("宾利", 10, "黑色");car.show ();}
成员内部类
// 外部类
public class Outer {private int a = 10;// 成员内部类class Inner {private int a = 20;// Outer.this --->外部类对象的 地址值public void show() {int a = 30;System.out.println (a); // 30 就近原则System.out.println (this.a); // 20 内部类的成员System.out.println (Outer.this.a); // 10 外部类的成员}}
}
静态内部类
public class Outer {private int a = 10;static int b = 20;/*** 静态内部类 只能访问外部类的静态成员方法和 静态成员变量* 如果 需要访问外部类的 非静态成员,需要 创建外部类的对象*/static class Inner {public void show1() {Outer outer = new Outer ();System.out.println (outer.a); // 10System.out.println (b); // 20System.out.println ("非静态方法被调用");}public static void show2() {System.out.println ("静态方法被调用");}}
}
public class Test {public static void main(String[] args) throws Exception {Outer.Inner inner = new Outer.Inner ();inner.show1 ();// 静态方法被调用Outer.Inner.show2 ();}}
匿名内部类
(可用 Lambda 简化)
@FunctionalInterface // 函数式接口,可以不加
public interface Swim {void swim();
}
测试
public class Test {public static void main(String[] args) throws Exception {/*** Lambda表达式 */swim (() -> {System.out.println ("我在游泳");});/*** 匿名内部类*/swim (new Swim () {@Overridepublic void swim() {System.out.println ("哥们在游泳");}});}/*** Swim是接口* 需要传递 Swim接口的 实现类** @param s*/static void swim(Swim s) {s.swim ();}}
泛型、通配符
泛型的好处与细节
泛型类
/*** 类型 不确定,就使用泛型** @param <E>*/
public class MyList<E> {private Object[] data = new Object[10];private int size;public boolean add(E e) {data[size++] = e;return true;}}
泛型方法
/*** 类型 不确定,就使用泛型*/
public class MyList {private Object[] data = new Object[10];private int size;// 在修饰词后面添加泛型public <E> boolean add(E... e) {if (size == data.length) return false;data[size++] = e;return true;}public <E> E get(int index) {if (index < 0 || index >= size) return null;return (E) data[index];}}
测试
public class Test {public static void main(String[] args) throws Exception {MyList myList = new MyList ();myList.add ("1");myList.add (2);String s = myList.get (0);Integer o = myList.get (1);System.out.println (s);System.out.println (o);}}
泛型接口
实现类 给出具体类型:
实现类 延续泛型:
/*** 类型 不确定,就使用泛型*/
public class MyList<E> extends List<E> {}
public static void main(String[] args) throws Exception {MyList myList = new MyList ();myList.add ("你好");}
泛型的继承与通配符
public class Ye {
}class Fu extends Ye {
}class Zi extends Fu {
}
public static void main(String[] args) throws Exception {ArrayList<Ye> list1 = new ArrayList<> ();list1.add (new Ye ());ArrayList<Fu> list2 = new ArrayList<> ();list2.add (new Fu ());ArrayList<Zi> list3 = new ArrayList<> ();list3.add (new Zi ());method (list1); // 报错,只能传递Fu和Fu的 子类method (list2);method (list3);}public static <E> void method(ArrayList<? extends Fu> list) throws Exception {}
public static void main(String[] args) throws Exception {ArrayList<Ye> list1 = new ArrayList<> ();list1.add (new Ye ());ArrayList<Fu> list2 = new ArrayList<> ();list2.add (new Fu ());ArrayList<Zi> list3 = new ArrayList<> ();list3.add (new Zi ());method (list1);method (list2);method (list3);// 报错,只能传递Fu和Fu的 父类}public static <E> void method(ArrayList<? super Fu> list) throws Exception {}
权限修饰符、代码块
权限修饰符
代码块
静态代码块 不能 定义在 方法中!!!
public class Test {private static int num = 20;static {// 静态只能 用静态 !!!num = 10;System.out.println ("static代码块执行");}public static void main(String[] args) throws Exception {System.out.println (num);System.out.println ("main方法执行");}}
this、super、static、包、final 关键字、常量
this
private int age = 20;void method() {int age = 10;// 就近原则//System.out.println (age); //10// this 关键字,代表该对象System.out.println (this.age); // 20System.out.println (super.toString ()); // 父类的 toString方法 }
static
定义 数组工具类 ArrayUtils
public class ArrayUtils {// 私有化 构造方法// 目的:为了防止外部实例化对象private ArrayUtils() {}// 定义为静态的,方便调用/*** 打印数组** @param arr* @return*/public static String printArr(int[] arr) {StringBuilder sb = new StringBuilder ("[");for (int i = 0; i < arr.length; i++) {sb.append (arr[i]);if (i != arr.length - 1) {sb.append (",");}}return sb.append ("]").toString ();}/*** 返回平均分** @param arr* @return*/public static double getAvg(int[] arr) {double avg = 0;int sum = 0;// 求和for (int num : arr) {sum += num;}avg = sum * 1.0 / arr.length;return avg;}
}
public static void main(String[] args) throws Exception {int[] arr = new int[]{1, 2, 3, 4, 5, 6, 7, 8, 9, 10};// 打印数组System.out.println(ArrayUtils.printArr(arr));// 求平均分System.out.println("平均为:"+ArrayUtils.getAvg(arr));}
包
final
常量
核心:常量记录的数据是 不能 发生改变的
public static void main(String[] args) throws Exception {final double PI = 3.14;System.out.println (PI);//PI=5; // 编译错误final Student student = new Student ();/*** 记录的地址值不能改变,但是对象的属性值可以改变*///student = null;// 编译错误student.setName ("张三");student.setAge (18);System.out.println (student);}
public static void main(String[] args) throws Exception {final int[] ARR = {1, 2, 3, 4, 5};//ARR=null;// 数组的地址不能改变// 属性值可以改变ARR[0] = 5;ARR[1] = 6;for (int num : ARR) {System.out.print (num + " ");}}
异常
异常简介
// 编译时异常,try catch 捕获起来
try {FileInputStream fis = new FileInputStream ("a.txt");
} catch (FileNotFoundException e) {throw new RuntimeException (e);
}// 运行时异常,索引越界
int[] arr = {1, 2, 3};
System.out.println (arr[3]);
// 构造方法 没有返回值,生成的对象 与返回值类型一致即可
public Student(String s) {// 传递过来的字符串为 张三-13,不能按照, 分割String[] split = s.split (",");this.name = split[0];this.age = Integer.parseInt (split[1]);
}public static void main(String[] args) {Student student = new Student ("张三-13");System.out.println (student);}
try {System.out.println ("代码执行前");int i = 10 / 0; // 可能出现的异常代码System.out.println ("代码执行后");
}catch (Exception e){// 异常处理代码System.out.println ("出现了异常了");//throw new RuntimeException ("不能除0");
}// 可以让程序继续往下执行,不会停止System.out.println ("异常处理完,接着执行");
捕获异常 4个问题
/* 如果 try 中没有问题,代码怎么执行?会将 try中所有代码全部执行完毕,不会执行 catch里面的代码注意: 只有当try中出现了异常,才会执行catch中的代码*/int [] arr = {1,2,3,4,5,6};try {System.out.println (arr[0]);}catch (Exception e){// 异常处理代码System.out.println ("出现了异常了");//throw new RuntimeException ("不能除0");}// 可以让程序继续往下执行,不会停止System.out.println ("看看我执行了嘛");}/* 如果 try 中遇到 多个问题,代码怎么执行?会写多个catch 与之对应注意: 如果我们要捕获多个异常,这些异常中如果存在 子父类关系,那么子类异常写在上面,父类异常写在下面!!!*/int [] arr = {1,2,3,4,5,6};try {System.out. println (arr[10]); // ArrayIndexOutOfBoundsException 数组索引越界异常System.out.println (5/0); // ArithmeticException 数学异常String s = null; // NullPointerException 空指针异常System.out.println (s.equals ("abc"));// 可以让程序继续往下执行,不会停止}catch (ArrayIndexOutOfBoundsException e){System.out.println ("数组索引越界异常");}catch (ArithmeticException e){System.out.println ("数学异常");}catch (NullPointerException e){System.out.println ("空指针异常");}catch (Exception e){System.out.println ("其他异常");}System.out.println ("看看我执行了嘛");/* 如果 try中遇到的问题 没有被捕获,代码怎么执行?相当于try...catch 代码块白写最终还是交给 虚拟机进行处理,打印红色堆栈信息*/int[] arr = {1, 2, 3, 4, 5, 6};try {System.out.println (arr[10]); // ArrayIndexOutOfBoundsException 数组索引越界异常} catch (NullPointerException e) {System.out.println ("空指针异常");}System.out.println ("看看我执行了嘛");/* 如果 try中遇到问题,出现问题的代码 的下面一行代码还会不会执行?--不会执行,会直接跳转到对应的catch块,执行catch中的代码块如果没有对应的catch块。最终还是交给虚拟机处理*/int[] arr = {1, 2, 3, 4, 5, 6};try {System.out.println (arr[10]); // ArrayIndexOutOfBoundsException 数组索引越界异常System.out.println ("异常代码的下一行代码");} catch (ArrayIndexOutOfBoundsException e) {System.out.println ("数组越界异常");}System.out.println ("看看我执行了嘛");
/* 如果try中遇到问题,出现问题的代码 的下面一行代码还会不会执行?--不会执行,会直接跳转到对应的catch块,执行catch中的代码块--->如果catch中也遇到问题,根据有没有try进行处理如果没有对应的catch块。最终还是交给虚拟机处理*/int[] arr = {1, 2, 3, 4, 5, 6};try {System.out.println (arr[10]); // ArrayIndexOutOfBoundsException 数组索引越界异常System.out.println ("异常代码的下一行代码");} catch (ArrayIndexOutOfBoundsException e) {try {int i = 5 / 0; // catch块出现问题,若有try,会继续跳转到对应的catch块执行代码;若没有try,会交给虚拟机处理}catch (ArithmeticException e1){System.out.println ("算术异常");}System.out.println ("数组越界异常");}System.out.println ("看看我执行了嘛");
抛出异常
抛出异常
public static void main(String[] args) {// 定义一个方法,创建数组并求最大值 返回值类型 intint[] arr = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};int max = 0;try {max = getMax (arr);} catch (Exception e) {e.printStackTrace ();}System.out.println ("最大值为:" + max);}public static int getMax(int[] arr) {// 判空if (arr == null) {// 手动创建异常,将异常交给方法的调用者throw new NullPointerException ();}int max = arr[0];for (int i = 1; i < arr.length; i++) {if (arr[i] > max) {max = arr[i];}}return max;}
public String getName() {return name;
}public void setName(String name) {int len=name.length ()if(len>3 || len>10) throw new RuntimeException ("名字长度有误");this.name = name;
}
自定义异常
自定义异常
public class NameFormatException extends RuntimeException{/*** 技巧:* NameFormat :当前 异常的名字,表示姓名格式化问题* Exception : 表示当前类是一个异常类* 运行时异常: RuntimeException 核心 表示由于参数错误而导致的问题* 编译时异常: Exception 核心 提醒程序员检查本地信息**/public NameFormatException() {}public NameFormatException(String message) {super (message);}
}
// 构造方法 没有返回值,生成的对象 与返回值类型一致即可public Student(String s) {String[] split = s.split (",");setName (split[0]);this.age = Integer.parseInt (split[1]);}public String getName() {return name;}public void setName(String name) {int len=name.length ();if(len<3 || len>10)throw new NameFormatException (name+"格式有误,长度为"+len+",不符合要求");this.name = name;}
Student student = new Student ("张三,12");
反射
获取Class对象
获取Class对象
// 全类名 : 包名 + 类名 --->最常用
Class<?> clazz1 = Class.forName ("com.example.demo.Student");// 第二种方式 --->当参数进行传递
Class<Student> clazz2 = Student.class;// 第三种方式 --->已经有了这个类的对象时,才可以使用
Student student = new Student ();
Class<? extends Student> clazz3 = student.getClass ();System.out.println (clazz1==clazz2); // true
System.out.println (clazz2==clazz3); // true
获取构造方法
获取构造方法
// 全类名 : 包名 + 类名 --->最常用
Class<?> clazz1 = Class.forName ("com.example.demo.Student");
Constructor<?>[] constructors = clazz1.getConstructors ();
// 打印所有构造方法
for (Constructor<?> constructor : constructors) {System.out.println (constructor);
}// 全类名 : 包名 + 类名 --->最常用
Class<?> clazz1 = Class.forName ("com.example.demo.Student");
Constructor<?> constructor = clazz1.getConstructor (String.class, int.class);
Student student = (Student) constructor.newInstance ("张三", 25);
System.out.println (student);// 全类名 : 包名 + 类名 --->最常用
Class<?> clazz1 = Class.forName ("com.example.demo.Student");
Constructor<?> constructor = clazz1.getConstructor (String.class);Student student = (Student) constructor.newInstance ("张三,12");
System.out.println (student);// 构造方法私有
private Student() {}
// 全类名 : 包名 + 类名 --->最常用
Class<?> clazz1 = Class.forName ("com.example.demo.Student");
Constructor<?> constructor = clazz1.getDeclaredConstructor ();
// 设置为可以访问
constructor.setAccessible (true);
Student s = (Student) constructor.newInstance ();
s.setName ("张三");
s.setAge (20);
System.out.println (s);
获取成员变量
获取成员变量
Class<?> clazz1 = Class.forName ("com.example.demo.Student");
Field[] fields = clazz1.getDeclaredFields ();for (Field field : fields) {System.out.println (field);
}// 全类名 : 包名 + 类名 --->最常用
Class<?> clazz1 = Class.forName ("com.example.demo.Student");
// 获取 单个成员变量
Field name = clazz1.getDeclaredField ("name");
Field age = clazz1.getDeclaredField ("age");
// 获取 变量的修饰权限
System.out.println (name.getModifiers ());Student student = new Student ();
// 给 变量赋值
name.setAccessible (true);
age.setAccessible (true);
name.set (student,"张三");
age.set (student,27);
System.out.println (student);
获取成员方法
获取成员方法
// 全类名 : 包名 + 类名 --->最常用Class<?> clazz1 = Class.forName ("com.example.demo.Student");// 获得所有方法,包括父类的方法/* Method[] methods = clazz1.getMethods ();for (Method method : methods) {System.out.println (method);}*/// 获得所有方法,只有本类的方法/* Method[] declaredMethods = clazz1.getDeclaredMethods ();for (Method declaredMethod : declaredMethods) {// 获得方法System.out.println (declaredMethod);// 获得修饰符System.out.println (declaredMethod.getModifiers ());}*/// 获得指定方法Method setName = clazz1.getDeclaredMethod ("setName", String.class);// 获得方法名String name = setName.getName ();System.out.println (name);// 获取方法的参数Parameter[] parameters = setName.getParameters ();for (Parameter parameter : parameters) {System.out.println (parameter);}// 获取方法抛出的异常Class<?>[] exceptionTypes = setName.getExceptionTypes ();for (Class<?> exceptionType : exceptionTypes) {System.out.println (exceptionType);}// 方法运行 invoke: 方法名.invoke(调用该方法的对象,参数)Student student = new Student ();setName.invoke (student, "张三"); // 调用者,传递的实际参数Method setAge = clazz1.getDeclaredMethod ("setAge", int.class);setAge.invoke (student,29);System.out.println (student);
练习
public static void main(String[] args) throws Exception {// 创建一个学生对象,将所有字段名和值保存到文件中Student student = new Student ("杨紫", 18, '女', 170, "演戏");saveObj(student);}private static void saveObj(Student student) throws IOException {// 获取所有的字段名和值Field[] declaredFields = student.getClass ().getDeclaredFields ();// 创建IO流BufferedWriter bw = new BufferedWriter (new FileWriter ("E:\\ProjectDirectory\\demo\\src\\main\\java\\com\\example\\demo\\a.txt"));for (Field field : declaredFields) {field.setAccessible (true);// 获取字段名和值String name = field.getName ();Object val = null;try {val = field.get (student);} catch (IllegalAccessException e) {e.printStackTrace ();}// 写入文件bw.write (name + "=" + val);// 换行bw.newLine ();System.out.println (name + "=" + val);}bw.close ();
}
// 配置文件
classname=com.example.demo.Student
method=eat
public static void main(String[] args) throws Exception {// 创建一个学生对象,将所有字段名和值保存到文件中Student student = new Student ("杨紫", 18, '女', 170, "演戏");Properties properties = new Properties ();FileInputStream fis = new FileInputStream (new File ("prop.properties"));// 加载文件properties.load (fis);fis.close ();// 获取类名和方法名String className = (String) properties.get ("classname");String method = (String) properties.get ("method");// 通过反射创建对象并调用方法Class aClass = Class.forName (className);// 获取无参构造方法Constructor constructor = aClass.getDeclaredConstructor ();// 调用无参构造方法创建对象Object o = constructor.newInstance ();// 修改字段值Field name = aClass.getDeclaredField ("name");name.setAccessible (true);name.set (o, "李沁");// 调用方法aClass.getDeclaredMethod (method).invoke (o);}
动态代理
概念
不 修改代码且 增加功能
实现
接口
public interface Star {void sing();void dance();
}
实现类
public class BigStar implements Star {private String name;public BigStar() {}public BigStar(String name) {this.name = name;}// 唱歌@Overridepublic void sing() {System.out.println (this.name + " 在唱歌");}// 跳舞@Overridepublic void dance() {System.out.println (this.name + " 在跳舞");}
}
代理工具类
public class ProxyUtils {public static Star createProxy(BigStar star) throws Exception {return (Star) Proxy.newProxyInstance (star.getClass ().getClassLoader (), // 指定 用哪个类加载器去加载new Class[]{Star.class}, // 指定接口,指定代理对象要实现哪些接口// 用来 指定生成的代理对象要干什么事情new InvocationHandler () {@Overridepublic Object invoke(Object proxy, Method method, Object[] args) throws Throwable {// 执行主体方法前if ("sing".equals (method.getName ())) {System.out.println ("准备话筒,收钱");} else if ("dance".equals (method.getName ())) {System.out.println ("准备场地,收钱");}// 执行主体方法return method.invoke (star, args);}});}}
调用方法
public static void main(String[] args) throws Exception {BigStar bigStar = new BigStar ("蔡徐坤");Star proxy = ProxyUtils.createProxy (bigStar);proxy.sing ();System.out.println ("---------");proxy.dance ();}
注解
概念
区别注解与注释
注解:给程序 看的
注释:给人 看的
自定义注解
自定义注解
@Target 注解
@Retention 注解
然后 使用反射
,对标注注解的,执行相应操作
@Target (ElementType.METHOD) // 作用在方法上
@Retention(RetentionPolicy.RUNTIME) // 运行时注解
public @interface InitMethod {
}
public class InitDemo {@InitMethodpublic void init() {System.out.println ("init...");}public void test() {System.out.println ("Test方法执行了");}
}
将 带有 @InitMethod
的方法全部执行
public class Test {public static void main(String[] args) throws Exception {Class<?> aClass = Class.forName ("com.example.demo.InitDemo");// 获取所有方法,不包括父类的方法Method[] methods = aClass.getDeclaredMethods ();if (methods != null) {for (Method method : methods) {boolean isInitMethod = method.isAnnotationPresent (InitMethod.class);if (isInitMethod) {// 执行方法, 无参构造的实例化对象method.invoke (aClass.getConstructor ().newInstance (),null);}}}}}
执行后
将 Test方法,打上 @InitMethod
注解,再次执行
@InitMethodpublic void init() {System.out.println ("init...");}@InitMethodpublic void test() {System.out.println ("Test方法执行了");}
字符串
介绍
字符串操作
字符串比较、遍历
比较字符串的内容
String s1="abc"; // 字符串池// 字符串对象String s2=new String ("aBc");System.out.println (s1==s2); // 比较地址值 falseSystem.out.println (s1.equals (s2)); // 比较字符串内容 falseSystem.out.println (s1.equalsIgnoreCase (s2)); // 比较字符串内容,忽略大小写 true
用户登录
// 已知正确的用户名和密码,用程序实现用户登录功能,给三次机会// 登录成功, 给出提示// 登录失败, 给出提示// 三次机会用完, 给出提示String username = "admin";String password = "123456";boolean flag = false;Scanner scanner = new Scanner (System.in);for (int i = 0; i < 3; i++) {System.out.println ("请输入用户名");String s1 = scanner.nextLine ();System.out.println ("请输入密码");String s2 = scanner.nextLine ();if (username.equals (s1) && password.equals (s2)) {System.out.println ("登录成功");flag = true;break;} else {if(i!=2) System.out.println ("登录失败,还剩:" + (2- i) + "次机会");}}if(!flag) System.out.println ("登录失败,请30分钟后重试");
遍历字符串
Scanner scanner = new Scanner (System.in);System.out.println ("请输入字符串:");String s = scanner.nextLine ();/*for (int i = 0; i < s.length (); i++) {System.out.print (s.charAt (i) + " ");}*/char[] chars = s.toCharArray ();for (char aChar : chars) {System.out.print (aChar+" ");}
统计字符个数
public static void main(String[] args) throws Exception {Scanner scanner = new Scanner (System.in);System.out.println ("请输入字符串:");String s = scanner.nextLine ();/*** 分别统计大小写字母 和 数字出现的个数*/int sum1 = 0, sum2 = 0, sum3 = 0;// char 变量在计算时自动提升为int , 查Ascii码表for (int i = 0; i < s.length (); i++) {if (s.charAt (i) >= 'a' && s.charAt (i) <= 'z') {// 小写字母sum1++;} else if (s.charAt (i) >= 'A' && s.charAt (i) <= 'Z') {// 大写字母sum2++;} else if (s.charAt (i) >= '0' && s.charAt (i) <= '9') {// 数字sum3++;}}System.out.printf ("小写字母:%d个, 大写字母:%d个, 数字:%d个", sum1, sum2, sum3);}
字符串拼接 +
拼接字符串
public static void main(String[] args) throws Exception {Scanner scanner = new Scanner (System.in);//System.out.println ("请输入字符串:");//String s = scanner.nextLine ();int [] arr=new int[]{1,2,3,4};String res=arrayToString(arr);System.out.println (res);}private static String arrayToString(int[] arr) {if(arr==null||arr.length==0) return "[]";StringBuffer sb=new StringBuffer ();sb.append ("[");for(int i=0;i<arr.length;i++){sb.append (arr[i]);// 最后一个元素不需要 加,if(i!=arr.length-1){sb.append (",");}}return sb.append ("]").toString ();}
字符串反转
Scanner scanner = new Scanner (System.in);System.out.println ("请输入字符串:");String s = scanner.nextLine ();char[] chars = s.toCharArray ();int left=0,right=chars.length-1;while (left<=right){char tmp=chars[left];chars[left]=chars[right];chars[right]=tmp;left++;right--;}System.out.println (String.valueOf (chars));
char[] dict={'零','壹','贰','叁','肆','伍','陆','柒','捌','玖'};Scanner sc=new Scanner (System.in);// 请输入一个数字System.out.println ("请输入一个数字");String num = sc.nextLine ();for (int i = 0; i < num.length (); i++) {char c = num.charAt (i);System.out.print (dict[c-'0']);}
字符串替代 replace、截取subString
手机号屏蔽
String s = "abcdefg";String substring = s.substring (1, 4); // len = 4 -1 = 3,返回值才是截取后的结果System.out.println (substring); // bcd
// 手机号中间四位屏蔽String s = "15155644987";// 截取前三位String s1 = s.substring (0, 3);// 截取后四位String s2 = s.substring (7, 11);// String s2 = s.substring (7);String res = s1 + "****" + s2;System.out.println (res);
敏感词替换
// 手机号中间四位屏蔽String talk = "你玩的真好,他妈不要再玩了,TMD,SB,给我去死,傻逼东西";// 定义敏感词库String[] dicts = {"TMD", "SB", "MLGB", "你妈", "傻逼", "去死", "他妈"};for (String dict : dicts) {// 替换后 赋给原字符串talk = talk.replace (dict, "***");}System.out.println (talk);
字符串拼接 StringBuilder
StringBuilder 的使用场景
字符串 拼接
字符串 反转
StringBuilder sb = new StringBuilder ("abc");sb.append (1);sb.append (2.3);sb.append (true);System.out.println (sb.toString ());StringBuilder reverse = sb.reverse ();int length = sb.length ();System.out.println (length); // 字符串长度// 字符串反转System.out.println (reverse.toString ());
Scanner scanner = new Scanner (System.in);// 输入一个字符串System.out.println ("请输入一个字符串");String str = scanner.nextLine ();StringBuilder stringBuilder = new StringBuilder (str);// 字符串反转String reverse = stringBuilder.reverse ().toString ();// 字符串比较System.out.println (str.equals (reverse));
public static void main(String[] args) throws Exception {// CharSequence delimiter,// CharSequence prefix,// CharSequence suffixStringJoiner sj = new StringJoiner (",", "[", "]");int[] arr = {1, 2, 3, 4, 5, 6, 7, 8, 9};for (int i : arr) {sj.add (i + "");}System.out.println (sj.toString ());}
综合练习
调整 字符串
public static void main(String[] args) throws Exception {boolean falg = adjustString ("abcde", "cdeab");System.out.println (falg);}private static boolean adjustString(String s1, String s2) {if (s1.length () != s2.length ()) return false;char[] sc1 = s1.toCharArray ();for (int i = 0; i < sc1.length; i++) {char[] chars = new char[sc1.length];int index = 0;// 元素左移for (int j = 1; j < sc1.length; j++) {chars[index++] = sc1[j];}// 原数组的最后一个位置 放置刚刚被左移的元素chars[index] = sc1[0];sc1 = chars;String adj = String.valueOf (sc1);if (adj.equals (s2)) return true;}return false;}
打乱 字符串的内容
// 定义一个字符串,将其打乱String str = "abcdefg";char[] chars = str.toCharArray ();for (int i = 0; i < str.length (); i++) {// 随机交换索引int idx = new Random ().nextInt (chars.length);// 交换char c = str.charAt (i);char tmp = chars[idx];chars[idx] = c;chars[i] = tmp;}System.out.println (String.valueOf (chars));
ArrayList
支持 动态修改、增加删除元素
ArrayList<String> list = new ArrayList<> ();// 添加元素list.add ("aaa");list.add ("bbb");list.add ("ccc");list.add ("ddd");// 修改指定位置出的元素list.set (1, "cbd");// 查询元素String s = list.get (2);System.out.println (s);// 删除元素list.remove ("ccc");//list.remove (1);System.out.println (list);// 集合的大小int size = list.size ();System.out.println (size);// 判断集合是否为空boolean empty = list.isEmpty ();System.out.println (empty);// 集合是否包含某个元素boolean contains = list.contains ("cbd");System.out.println (contains);// 遍历集合list.forEach (System.out::println);// 清空集合list.clear ();
// 创建集合ArrayList<Student> stus = new ArrayList<> ();stus.add (new Student ("张三", 18));stus.add (new Student ("李四", 20));stus.add (new Student ("王五", 24));stus.add (new Student ("赵六", 30));// 遍历集合stus.forEach (System.out::println);
public static void main(String[] args) throws Exception {// 创建集合ArrayList<Student> stus = new ArrayList<> ();Student student1 = new Student ("heima001", "张三", 18);Student student2 = new Student ("heima002", "李四", 20);Student student3 = new Student ("heima003", "王五", 24);Student student4 = new Student ("heima004", "赵六", 30);Collections.addAll (stus, student1, student2, student3, student4);// 判断Id 在集合中是否存在boolean flag;flag = containsId (stus, "heima004");System.out.println (flag);}private static boolean containsId(ArrayList<Student> stus, String id) {boolean flag = false;// 增强 for循环for (Student student : stus) {if (id.equals (student.getId ())) {flag = true;}}return flag;}
练习
public class Student {private String id;private String name;private int age;private String address;public Student() {}public Student(String id, String name, int age, String address) {this.id = id;this.name = name;this.age = age;this.address = address;}/*** 获取** @return id*/public String getId() {return id;}/*** 设置** @param id*/public void setId(String id) {this.id = id;}/*** 获取** @return name*/public String getName() {return name;}/*** 设置** @param name*/public void setName(String name) {this.name = name;}/*** 获取** @return age*/public int getAge() {return age;}/*** 设置** @param age*/public void setAge(int age) {this.age = age;}/*** 获取** @return address*/public String getAddress() {return address;}/*** 设置** @param address*/public void setAddress(String address) {this.address = address;}public String toString() {return "Student{id = " + id + ", name = " + name + ", age = " + age + ", address = " + address + "}";}
}
import java.util.ArrayList;
import java.util.Scanner;public class Test {public static void main(String[] args) throws Exception {ArrayList<Student> list = new ArrayList<> ();// 添加标签choose: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 ("请输入您的选择:");Scanner sc = new Scanner (System.in);String choose = sc.next ();switch (choose) {case "1":int i1 = addStudent (list);res (i1, "添加");break;case "2":int i = deleteStudent (list);// 1 成功 0 失败 -1 不存在res (i, "删除");break;case "3":int i2 = alterStudent (list);// 1 成功 0 失败 -1 不存在res (i2, "修改");break;case "4":queryStudent (list);break;case "5":System.out.println ("退出系统");// break; 只能跳出单层循环 ;跳出多重循环 用标签// System.exit (0); // 退出虚拟机break choose;default:System.out.println ("没有该选项");}}}private static void res(int i1, String msg) {if (i1 == -1) {System.out.println (msg + "失败");} else if (i1 == 0) {System.out.println ("当前无学生信息");} else {System.out.println (msg + "成功");}}/*** 查询** @param list*/private static void queryStudent(ArrayList<Student> list) {if (list.size () == 0) {System.out.println ("当前无学生信息");return;}// 打印表头信息System.out.println ("id\t\t姓名\t\t年龄\t\t居住地");// 遍历集合for (int i = 0; i < list.size (); i++) {Student student = list.get (i);System.out.println (student.getId () + "\t\t" +student.getName () + "\t\t" +student.getAge () + "\t\t" +student.getAddress ());}}/*** 修改** @param list*/private static int alterStudent(ArrayList<Student> list) {if (list.size () < 1) return 0;// 键盘录入Scanner sc = new Scanner (System.in);System.out.println ("请输入id");String id = sc.nextLine ();// 判断id是否存在int idx = containsId (list, id);if (idx == -1) {System.out.println ("id不存在");return -1;}Student student = getStudent (sc, id);list.set (idx, student);return 1;}/*** 删除** @param list*/private static int deleteStudent(ArrayList<Student> list) {if (list.size () < 1) return 0;Scanner sc = new Scanner (System.in);String id;int idx;while (true) {System.out.println ("请输入要删除的学生id");id = sc.nextLine ();// 判断id是否存在idx = containsId (list, id);if (idx == -1) {System.out.println ("id不存在");continue;} else break;}list.remove (idx);return 1;}/*** 添加** @param list*/private static int addStudent(ArrayList<Student> list) {// 键盘录入Scanner sc = new Scanner (System.in);String id;while (true) {System.out.println ("请输入id");id = sc.nextLine ();// 判断id是否存在int flag = containsId (list, id);if (flag != -1) {System.out.println ("id已存在");continue;} else break;}Student student = getStudent (sc, id);list.add (student);return 1;}private static Student getStudent(Scanner sc, String id) {Student student;while (true) {System.out.println ("请输入姓名:长度1~4");String name = sc.nextLine ();// 姓名长度 1~4, 否则 重新输入if (name.length () < 1 || name.length () >= 4) continue;String age;loop:while (true) {System.out.println ("请输入年龄:1~99");age = sc.nextLine ();// 年龄1~99, 否则 重新输入if (age.length () < 1 || age.length () >= 3) continue;// 年龄只能是数字for (char c : age.toCharArray ()) {if (c < '0' || c > '9') {System.out.println ("你输入的不是数字!");continue loop;}}break;}System.out.println ("请输入居住地");String address = sc.nextLine ();student = new Student (id, name, Integer.parseInt (age), address);break;}return student;}private static int containsId(ArrayList<Student> stus, String id) {int flag = -1;for (int i = 0; i < stus.size (); i++) {if (id.equals (stus.get (i).getId ())) {// 存在,返回索引flag = i;break;}}return flag;}}
相关文章:

Java基础 (一)
基础概念及运算符、判断、循环 基础概念 关键字 数据类型 分为两种 基本数据类型 标识符 运算符 运算符 算术运算符 隐式转换 小 ------>>> 大 强制转换 字符串 拼接符号 字符 运算 自增自减运算符 ii赋值运算符 赋值运算符 包括 强制转换 关系运算符 逻辑运算符 …...

数据结构——实验六·散列表
嗨~~欢迎来到Tubishu的博客🌸如果你也是一名在校大学生,正在寻找各种编程资源,那么你就来对地方啦🌟 Tubishu是一名计算机本科生,会不定期整理和分享学习中的优质资源,希望能为你的编程之路添砖加瓦⭐&…...

springboot网上书城
摘 要 在Internet高速发展的今天,我们生活的各个领域都涉及到计算机的应用,其中包括网上书城管理系统的网络应用,在国外网上书城管理系统已经是很普遍的方式,不过国内的书城管理系统可能还处于起步阶段。网上书城管理系统具有网上…...
如何在 Pytest 中使用命令行界面和标记运行测试
关注开源优测不迷路 大数据测试过程、策略及挑战 测试框架原理,构建成功的基石 在自动化测试工作之前,你应该知道的10条建议 在自动化测试中,重要的不是工具 在前文你已经初步尝试编写了代码和单元测试,并且想要确保它能正常运行。…...

不建模,无代码,如何构建一个3D虚拟展厅?
在数字化浪潮的推动下,众多企业正积极探索线上3D虚拟展厅这一新型展示平台,旨在以更加生动、直观的方式呈现其产品、环境与综合实力。然而,构建一个既专业又吸引人的3D虚拟展厅并非易事,它不仅需要深厚的技术支持,还需…...

github汉化
本文主要讲述了github如何汉化的方法。 目录 问题描述汉化步骤1.打开github,搜索github-chinese2.打开项目,打开README.md3.下载安装脚本管理器3.1 在README.md中往下滑动,找到浏览器与脚本管理器3.2 选择浏览器对应的脚本管理器3.2.1 点击去…...

Unity Line Renderer Component入门
Overview Line Renderer 组件是 Unity 中用于绘制连续线段的工具。它通过在三维空间中的两个或两个以上的点的数组,并在每个点之间绘制一条直线。可以绘制从简单的直线到复杂的螺旋线等各种图形。 1. 连续性和独立线条 连续性:Line Renderer 绘制的线条…...
数据库的三级模式结构与两级映像
三级模式结构与两级映像 什么是数据库的三级模式结构?1. 模式(Conceptual Schema,概念模式)定义特点作用示例 2. 外模式(External Schema,外部模式)定义特点作用举例 3. 内模式(Inte…...
TCP断开通信前的四次挥手(为啥不是三次?)
1.四次握手的过程 客户端A发送 FIN(终止连接请求) A:我要断开连接了(FIN)。A进入FIN_WAIT_1状态,表示请求断开,等待对方确认。 服务器B回复 ACK(确认断开请求,但还未准备…...

win32汇编环境,按字节、双字等复制字符的操作
;运行效果 ;win32汇编环境,按字节、双字等复制字符的操作 ;这是汇编的优点之一。我们可以按字节、双字、四字、八字节等复制或挨个检查字符。 ;有时候,在接收到的一串信息中,比如访问网站时,返回的字串里,有很多0值存在࿰…...
.net 项目引用与 .NET Framework 项目引用之间的区别和相同
在 .NET 和 .NET Framework 项目中,引用其他库或项目的方式有一些区别和相同之处。以下是详细的对比: 相同点 引用目的: 目的:无论是 .NET 还是 .NET Framework 项目,引用其他库或项目的主要目的是为了使用这些库或项…...

RabbitMQ--延迟队列
(一)延迟队列 1.概念 延迟队列是一种特殊的队列,消息被发送后,消费者并不会立刻拿到消息,而是等待一段时间后,消费者才可以从这个队列中拿到消息进行消费 2.应用场景 延迟队列的应用场景很多,…...
使用pyboard、micropython和tja1050进行can通信
单片机和can收发器之间tx、rx不需要交叉接线!!! tja1050的rx接Y3、tx接Y4 from pyb import CANcan CAN(1) can.init(modecan.NORMAL, prescaler6, sjw1, bs14, bs22, auto_restartTrue) # 1Mbps的配置,本文使用的micropython1.…...
JS学习之JavaScript模块化规范进化论
前言 JavaScript 语言诞生至今,模块规范化之路曲曲折折。 前言 JavaScript 语言诞生至今,模块规范化之路曲曲折折。社区先后出现了各种解决方案,包括 AMD、CMD、CommonJS 等,而后 ECMA 组织在 JavaScript 语言标准层面࿰…...

亚博microros小车-原生ubuntu支持系列:7-脸部检测
背景知识 官网介绍: Face Mesh - mediapipe mpFaceMesh.FaceMesh() 类的参数有:self.staticMode, self.maxFaces, self.minDetectionCon, self.minTrackCon staticMode:是否将每帧图像作为静态图像处理。如果为 True,每帧都会进行人脸检测…...

第二届国赛铁三wp
第二届国赛 缺东西去我blog找👇 第二届长城杯/铁三 | DDLS BLOG web Safe_Proxy 源码题目 from flask import Flask, request, render_template_stringimport socketimport threadingimport htmlapp Flask(__name__)app.route(/, methods"GET"])de…...

缓存商品、购物车(day07)
缓存菜品 问题说明 问题说明:用户端小程序展示的菜品数据都是通过查询数据库获得,如果用户端访问量比较大,数据库访问压力随之增大。 结果: 系统响应慢、用户体验差 实现思路 通过Redis来缓存菜品数据,减少数据库查询…...
4【编程语言的鄙视链原因解析】
在编程行业中,是存在鄙视链的,技术越好的圈子越不明显,技术越差的圈子越明显,很多时候为新人营造了错误的观点,我们来针对此类现象为新人们讲解原因 ①心里落差:比如你是学厨师的 你经过过年努力练…...
美团一面面经
第一个问题:介绍一下最近做的项目 第二个问题:我对你项目有个地方比较感兴趣啊。就是你用的那个二级缓存,你的吞吐量有多大啊,为什么需要使用二级缓存? 答: 在二级缓存策略下,笔记详情接口的吞…...
什么是报文的大端和小端,有没有什么记忆口诀?
在计算机科学中,**大端(Big-Endian)和小端(Little-Endian)**是两种不同的字节序(即多字节数据在内存中的存储顺序)。理解这两种字节序对于网络通信、文件格式解析以及跨平台编程等非常重要。 1…...
conda相比python好处
Conda 作为 Python 的环境和包管理工具,相比原生 Python 生态(如 pip 虚拟环境)有许多独特优势,尤其在多项目管理、依赖处理和跨平台兼容性等方面表现更优。以下是 Conda 的核心好处: 一、一站式环境管理:…...

iPhone密码忘记了办?iPhoneUnlocker,iPhone解锁工具Aiseesoft iPhone Unlocker 高级注册版分享
平时用 iPhone 的时候,难免会碰到解锁的麻烦事。比如密码忘了、人脸识别 / 指纹识别突然不灵,或者买了二手 iPhone 却被原来的 iCloud 账号锁住,这时候就需要靠谱的解锁工具来帮忙了。Aiseesoft iPhone Unlocker 就是专门解决这些问题的软件&…...

抖音增长新引擎:品融电商,一站式全案代运营领跑者
抖音增长新引擎:品融电商,一站式全案代运营领跑者 在抖音这个日活超7亿的流量汪洋中,品牌如何破浪前行?自建团队成本高、效果难控;碎片化运营又难成合力——这正是许多企业面临的增长困局。品融电商以「抖音全案代运营…...
五年级数学知识边界总结思考-下册
目录 一、背景二、过程1.观察物体小学五年级下册“观察物体”知识点详解:由来、作用与意义**一、知识点核心内容****二、知识点的由来:从生活实践到数学抽象****三、知识的作用:解决实际问题的工具****四、学习的意义:培养核心素养…...

P3 QT项目----记事本(3.8)
3.8 记事本项目总结 项目源码 1.main.cpp #include "widget.h" #include <QApplication> int main(int argc, char *argv[]) {QApplication a(argc, argv);Widget w;w.show();return a.exec(); } 2.widget.cpp #include "widget.h" #include &q…...
【git】把本地更改提交远程新分支feature_g
创建并切换新分支 git checkout -b feature_g 添加并提交更改 git add . git commit -m “实现图片上传功能” 推送到远程 git push -u origin feature_g...
三体问题详解
从物理学角度,三体问题之所以不稳定,是因为三个天体在万有引力作用下相互作用,形成一个非线性耦合系统。我们可以从牛顿经典力学出发,列出具体的运动方程,并说明为何这个系统本质上是混沌的,无法得到一般解…...
全面解析各类VPN技术:GRE、IPsec、L2TP、SSL与MPLS VPN对比
目录 引言 VPN技术概述 GRE VPN 3.1 GRE封装结构 3.2 GRE的应用场景 GRE over IPsec 4.1 GRE over IPsec封装结构 4.2 为什么使用GRE over IPsec? IPsec VPN 5.1 IPsec传输模式(Transport Mode) 5.2 IPsec隧道模式(Tunne…...
IP如何挑?2025年海外专线IP如何购买?
你花了时间和预算买了IP,结果IP质量不佳,项目效率低下不说,还可能带来莫名的网络问题,是不是太闹心了?尤其是在面对海外专线IP时,到底怎么才能买到适合自己的呢?所以,挑IP绝对是个技…...
C++.OpenGL (20/64)混合(Blending)
混合(Blending) 透明效果核心原理 #mermaid-svg-SWG0UzVfJms7Sm3e {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-SWG0UzVfJms7Sm3e .error-icon{fill:#552222;}#mermaid-svg-SWG0UzVfJms7Sm3e .error-text{fill…...