基础概念及运算符、判断、循环
基础概念
关键字
数据类型 分为两种
基本数据类型
标识符
运算符
运算符
算术运算符
隐式转换 小 ------>>> 大
强制转换
字符串 拼接符号 +
字符+ 运算
自增自减运算符
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;}}