基础概念及运算符、判断、循环
基础概念
关键字
数据类型 分为两种
基本数据类型
标识符
运算符
运算符
算术运算符
隐式转换 小 ------>>> 大
强制转换
字符串 拼接符号 +
字符+ 运算
自增自减运算符
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 () {
@Override
public 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); //1
Integer 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 {
@Override
public 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>(){
@Override
public 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> () {
@Override
public 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 {
@Override
public 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;
// 满值 100
private 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-100
Random 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 创建一个新的数组,长度为 原数组长度+1
Student[] 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 创建一个新的数组,长度为 原数组长度-1
Student[] 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”的学生,如果存在,则将他的年龄+1
boolean flag3 = false;
flag3 = isExist (students, id, flag3);
// 7.如果存在,将他的年龄+1
if (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 {
// 重写方法
@Override
public void eat() {
System.out.println ("吃意大利面");
}
@Override
public 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;
}
@Override
public void show() {
System.out.println (this.getName () + "show");
// 子类继承父类的属性,两者一样
System.out.println ("子类继承父类的属性 和父类属性一样"+(this.getName () == super.getName ())); // true
System.out.println (toString ());
}
@Override
public 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 {
@Override
public void eat() {
System.out.println ("学生吃饭");
}
}
public class Teacher extends Person {
@Override
public 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);
}
@Override
public void eat() {
System.out.println ("兔子吃胡萝卜");
}
}
狗:
public class Dog extends Animal implements Swim {
public Dog() {
}
public Dog(String name, int age) {
super (name, age);
}
@Override
public void eat() {
System.out.println ("狗吃骨头");
}
@Override
public void swim() {
System.out.println ("狗会游泳");
}
}
青蛙:
public class Frog extends Animal implements Swim{
public Frog() {
}
public Frog(String name, int age) {
super (name, age);
}
@Override
public void eat() {
System.out.println ("青蛙吃虫子");
}
@Override
public 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); // 10
System.out.println (b); // 20
System.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 () {
@Override
public 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); // 20
System.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) {
// 定义一个方法,创建数组并求最大值 返回值类型 int
int[] 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;
}
// 唱歌
@Override
public void sing() {
System.out.println (this.name + " 在唱歌");
}
// 跳舞
@Override
public 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 () {
@Override
public 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 {
@InitMethod
public 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
注解,再次执行
@InitMethod
public void init() {
System.out.println ("init...");
}
@InitMethod
public void test() {
System.out.println ("Test方法执行了");
}
字符串
介绍
字符串操作
字符串比较、遍历
比较字符串的内容
String s1="abc"; // 字符串池
// 字符串对象
String s2=new String ("aBc");
System.out.println (s1==s2); // 比较地址值 false
System.out.println (s1.equals (s2)); // 比较字符串内容 false
System.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 suffix
StringJoiner 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;
}
}