JavaSE面向对象综合练习学习记录

键盘录入

第一套体系

包含有nextInt()nextDouble()next()

nextInt()

只能接收整数

import java.util.Scanner;

public class ScannerTest {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        System.out.println("请输入一个整数");
        int number = sc.nextInt();  // 10
        System.out.println(number);  // 10
    }
}

这个是我现在学习Java以来一直常用的,就没有必要解释了

但是如果输入其他类中,报错

Exception in thread "main" java.util.InputMismatchException
	at java.base/java.util.Scanner.throwFor(Scanner.java:939)
	at java.base/java.util.Scanner.next(Scanner.java:1594)
	at java.base/java.util.Scanner.nextInt(Scanner.java:2258)
	at java.base/java.util.Scanner.nextInt(Scanner.java:2212)
	at ScannerTest.main(ScannerTest.java:7)

nextDouble()

只能接收小数

import java.util.Scanner;

public class ScannerTest {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        System.out.println("请输入一个浮点数");
        double number = sc.nextDouble();  // 13.14
        System.out.println(number);  // 13.14
    }
}

这个接收整数不会报错

import java.util.Scanner;

public class ScannerTest {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        System.out.println("请输入一个浮点数");
        double number = sc.nextDouble();  // 10
        System.out.println(number);  // 10.0
    }
}

会在小数部分加个0

next()

只能接收字符串

import java.util.Scanner;

public class ScannerTest {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        System.out.println("请输入一个字符串");
        String str = sc.next();  // HelloWorld
        System.out.println(str);  // HelloWorld
    }
}

注意事项

遇到空格、制表符、回车就停止接受了,这些符号后面的数据就不会接受了。

import java.util.Scanner;

public class ScannerTest {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        System.out.println("请输入一个浮点数");
        double number = sc.nextDouble();  // 13.14	111111
        System.out.println(number);  // 13.14
    }
}

13.14 111111 后面是个制表符(tab键)然后输出13.14

import java.util.Scanner;

public class ScannerTest {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        System.out.println("请输入一个字符串");
        String str = sc.next();  // Hello World
        System.out.println(str);  // Hello
    }
}

输入字符串的中间有个空格。

还有一种情况

import java.util.Scanner;

public class ScannerTest {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        System.out.println("请输入第一个整数");
        int number1 = sc.nextInt();  
        System.out.println(number1); 

        System.out.println("请输入第二个整数");
        int number2 = sc.nextInt();  
        System.out.println(number2);  
    }
}

输入两个整数,看似没有问题,执行程序

请输入第一个整数
10 20
10
请输入第二个整数
20

在输入第一个整数的时候我输入了10 20注意,中间使用空格的。

这是第一套体系,凡是遇到空格、制表符后面的数据不会接受了,所以应该 20不会被接收。但是在输入第二个整数的时候,他不让我输入,直接输出了20

当我输入了10 20时,number1只是接受了空格前面的数据10,剩下的 20被暂时存放在了内存中,在下一次输入的时候,不会让你输入了,而是把20直接给number2

第二套体系

nextLine()

可以接收空格、制表符,遇到空格才停止接收数据

import java.util.Scanner;

public class ScannerTest {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        System.out.println("请输入一个字符串");
        String line = sc.nextLine();  // asdfg hj	kl
        System.out.println(line);  // asdfg hj	kl
    }
}

这段输入里面有空格和制表符,但是我一个回车,他就停止接收数据。然后字符串和字符串中的空格、制表符全部输出。

import java.util.Scanner;

public class ScannerTest {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        System.out.println("请输入第一个字符串");
        String line1 = sc.nextLine();
        System.out.println(line1);

        System.out.println("请输入第二个字符串");
        String line2 = sc.nextLine();
        System.out.println(line2);

    }
}

// 请输入第一个字符串
// hello world
// hello world
// 请输入第二个字符串
// hello	world
// hello	world

注意事项

两种体系不能混用。为什么,看代码

import java.util.Scanner;

public class ScannerTest {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        System.out.println("请输入一个整数");
        int num = sc.nextInt();
        System.out.println(num);

        System.out.println("请输入一个字符串");
        String line = sc.nextLine();
        System.out.println(line);

    }
}

第一次输入123

请输入一个整数
123
123
请输入一个字符串


进程已结束,退出代码为 0

输入123 456

请输入一个整数
123 345
123
请输入一个字符串
 345

进程已结束,退出代码为 0

这两次的输入内容不同,但是有一个共同点,那就是在输入字符串的时候没有让我输入,自动程序结束。

而且第一次输入123,字符串那里还空了一行。

其实并不难解释,要这么想输入的123其实是123(回车)(空格),当我们输完123后按下回车,那么123后面的这一行就都是空格了,因此空格放在了内存中,然后给了line

123 456这个更好理解,nextInt()直接收回车前面的数据。因此123 456还剩下(空格)456 被放在了内存中,给了line

练习一:文字版格斗游戏

简单

  • 需求:

    格斗游戏,每个游戏角色的姓名,血量,都不相同,在选定人物的时候(new对象的时候),这些信息就应该被确定下来

  • 举例:

    程序运行之后结果为:

    姓名为:乔峰 血量为:100

    姓名为:鸠摩智 血量为:100

    乔峰举起拳头打了鸠摩智一下,造成了XX点伤害,鸠摩智还剩下XXX点血。

    鸠摩智举起拳头打了鸠摩智一下,造成了XX点伤害,乔峰还剩下XXX点血。

    乔峰举起拳头打了鸠摩智一下,造成了XX点伤害,鸠摩智还剩下XXX点血。

    鸠摩智举起拳头打了鸠摩智一下,造成了XX点伤害,乔峰还剩下XXX点血。

    乔峰K.O.了鸠摩智

代码示例:

package Test;

import java.util.Random;

public class Role {
    private String name;  // 人物名
    private int hp;  // 生命值

    // 无参构造方法
    public Role() {

    }

    // 带全参构造方法
    public Role(String name, int hp) {
        this.name = name;
        this.hp = hp;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getHp() {
        return hp;
    }

    public void setHp(int hp) {
        this.hp = hp;
    }

    // 方法调用者攻击形参,pi.attack(p2):p1攻击p2
    public void attack(Role role) {
        // 随机造成伤害
        Random r = new Random();
        int hurt = r.nextInt(15);  // 随机伤害
        int res = role.getHp() - hurt;  // 剩余血量
        res = res < 0 ? 0: res;  // 血量不能为负数
        role.setHp(res);  // 更改角色血量
        System.out.println(this.getName() + "举起拳头打了" + role.getName() + "一下," + "造成" + hurt + "点伤害," +
                role.getName() + "还剩下" + role.getHp() + "点血");
    }
}
package Test;

public class PlayGameTreat {
    public static void main(String[] args) {
        Role role1 = new Role("乔峰", 100);
        Role role2 = new Role("鸠摩智", 100);
        while (true) {
            role1.attack(role2);
            role2.attack(role1);
            if (role1.getHp() <= 0) {
                System.out.println(role2.getName() + "K.O了" + role1.getName());
                break;
            }else if (role2.getHp() <= 0) {
                System.out.println(role1.getName() + "K.O了" + role2.getName());
                break;
            }
        }
    }
}

格斗游戏,因为题目中提到了角色,那我就想,应该要创建一个角色类,角色都有什么属性,姓名和血量,那就写进去。

JavaBean类编写规范中提到过,应该提供无参构造方法和全参构造方法,那就编写,还要写getXxx()setXxx()方法。到此这个类算是基本完成,行为,我们还没有写行为,因为现在不知道都有哪些行为,那我们就需要的时候在完成吧。

先创建两个对象role1role2。 看似一切都准备好了。

那这个对象都有哪些行为呢?格斗游戏那就是有个攻击的行为。那我就写一个攻击的方法

public void attack(Role role) {
	// 随机造成伤害
    Random r = new Random();
    int hurt = r.nextInt(15);  // 随机伤害
    int res = role.getHp() - hurt;  // 剩余血量
    res = res < 0 ? 0: res;  // 血量不能为负数
    role.setHp(res);  // 更改角色血量
    System.out.println(this.getName() + "举起拳头打了" + role.getName() + "一下," + "造成" + hurt + "点伤害," +
                role.getName() + "还剩下" + role.getHp() + "点血");
}

一开始我想着这些事情应该是在主方法完成,但是做不出来,然后在类里面定义了一个方法,但还是不明白,最后看着老师的代码

第一个疑问点就是这个方法的参数(形参)

public void attack(Role role) {
    
}

方法形参的数据类型怎么是Role在我的印象里面Java好像并没有这种类型,而Role正好是我刚刚定义好的一个类。

这个我一开始没有百度,我也不知道怎么百度,然后自己想通了,我是这么想着

String,就是一个类,那我的Role也是可以看作一个类,数据类型。

int[] StringRole这些都可看作是一个引用数据类,所以这样是行得通的。

我们继续分析攻击的这个行为,在里面,都干了啥。

首先,要搞明白谁打了谁。调用者打了参数。role1.attack(role2)表示:role1攻击role2。

Random r = new Random();
int hurt = r.nextInt(15);  // 随机伤害
int res = role.getHp() - hurt;  // 剩余血量
res = res < 0 ? 0: res;  // 血量不能为负数
role.setHp(res);  // 更改角色血量
System.out.println(this.getName() + "举起拳头打了" + role.getName() + "一下," + "造成" + hurt + "点伤害," +
                role.getName() + "还剩下" + role.getHp() + "点血");

这里还有一个逻辑this指谁?是方法的调用者,攻击者。

用随机数写一个伤害,这个伤害我控制在了15。

剩余血量是谁的剩余血量,是被攻击者的,那就应该是role.getHp(),之后再减去这次伤害hurt

你还有多少血,我还有-5滴血,没有这么一说,所以,就是做个判断,如果是负数,那就为0

更改一下角色的血量,setHp()

输出,谁打了谁,调用者打的,那就用this.

其实role就是一个地址,把这个对象的地址传给这个方法,在主方法里面也是这么用的relo1.setHp()中的role1就是一个地址。一开始我还没想明白。现在明白了。

while (true) {
	role1.attack(role2);
    role2.attack(role1);
    if (role1.getHp() <= 0) {
    	System.out.println(role2.getName() + "K.O了" + role1.getName());
        break;
    }else if (role2.getHp() <= 0) {
        System.out.println(role1.getName() + "K.O了" + role2.getName());
        break;
	}
}

这是一个回合制游戏,你打我一下,我打你一下,看谁先没血了,游戏结束。

进阶

  • 需求

    在上一个的基础上,我想看到人物的性别和长相,打斗的时候我想看到武功招式。

  • 举例

    程序运行之后结果为:

    姓名为:乔峰 血量为:100 性别为:男 长相为:气宇轩昂

    姓名为:鸠摩智 血量为:100 性别为:男 长相为:气宇轩昂

    乔峰使出了一招【背心钉】,转到对方的身后,一掌向鸠摩智背心的灵台穴拍去。给鸠摩智造成一处瘀伤。

    鸠摩智使出了一招【游空探爪】,飞起身形自半空中变掌为抓锁向乔峰。结果乔峰退了半步,毫发无损。

    。。。。

    乔峰K.O.了鸠摩智

代码示例:

package Test2;

import java.util.Random;

public class Role {
    private String name;  // 人物名
    private int hp;  // 生命值
    private char gender;  // 性别
    private String face;  // 长相

    // 容颜
    String[] boyfaces= {"风流俊雅","气宇轩昂","相貌英俊","五官端正","相貌平平","一塌糊涂","面目狰狞"};
    String[] girlfaces ={"美奂绝伦","沉鱼落雁","婷婷玉立","身材娇好","相貌平平","相貌简陋","惨不忍睹"};

    //attack 攻击描述:
    String[] attacks_desc = {
            "%s使出了一招【背心钉】,转到对方的身后,一掌向%s背心的灵台穴拍去。",
            "%s使出了一招【游空探爪】,飞起身形自半空中变掌为抓锁向%s。",
            "%s大喝一声,身形下伏,一招【劈雷坠地】,捶向%s双腿。",
            "%s运气于掌,一瞬间掌心变得血红,一式【掌心雷】,推向%s。",
            "%s阴手翻起阳手跟进,一招【没遮拦】,结结实实的捶向%s。",
            "%s上步抢身,招中套招,一招【劈挂连环】,连环攻向%s。"
    };

    //injured 受伤描述:
    String[] injureds_desc = {
            "结果%s退了半步,毫发无损",
            "结果给%s造成一处瘀伤",
            "结果一击命中,%s痛得弯下腰",
            "结果%s痛苦地闷哼了一声,显然受了点内伤",
            "结果%s摇摇晃晃,一跤摔倒在地",
            "结果%s脸色一下变得惨白,连退了好几步",
            "结果『轰』的一声,%s口中鲜血狂喷而出",
            "结果%s一声惨叫,像滩软泥般塌了下去"
    };

    // 无参构造方法
    public Role() {

    }

    public Role(String name, int hp, char gender) {
        this.name = name;
        this.hp = hp;
        this.gender = gender;
        setFace(gender);  // 随机长袖
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getHp() {
        return hp;
    }

    public void setHp(int hp) {
        this.hp = hp;
    }

    public char getGender() {
        return gender;
    }

    public void setGender(char gender) {
        this.gender = gender;
    }

    public String getFace() {
        return face;
    }

    public void setFace(char gender) {
        Random r = new Random();
        if (gender == '男') {
            int index = r.nextInt(boyfaces.length);
            this.face = boyfaces[index];
        }else if (gender == '女') {
            int index = r.nextInt(girlfaces.length);
            this.face = girlfaces[index];
        }
    }

    // 方法调用者攻击形参,pi.attack(p2):p1攻击p2
    public void attack(Role role) {
        Random r = new Random();
        // 随机获取一个攻击描述
        int indexAttacks  = r.nextInt(attacks_desc.length);
        String KungFu = attacks_desc[indexAttacks];
        System.out.printf(KungFu, this.getName(), role.getName());

        // 随机造成伤害
        int hurt = r.nextInt(15);  // 随机伤害
        int res = role.getHp() - hurt;  // 剩余血量
        res = res <= 0 ? 0: res;  // 血量不能为负数
        role.setHp(res);  // 更改角色血量

        // 随机获取一个受伤描述
        if (res > 90) {
            System.out.printf(injureds_desc[0], role.getName());
        }else if (res>80 && res<=90) {
            System.out.printf(injureds_desc[1], role.getName());
        }else if (res>70 && res<=80) {
            System.out.printf(injureds_desc[2], role.getName());
        }else if (res>60 && res<=70) {
            System.out.printf(injureds_desc[3], role.getName());
        }else if (res>40 && res<=60) {
            System.out.printf(injureds_desc[4], role.getName());
        }else if (res>20 && res<=40) {
            System.out.printf(injureds_desc[5], role.getName());
        }else if (res>10 && res<=20) {
            System.out.printf(injureds_desc[6], role.getName());
        }else  {
            System.out.printf(injureds_desc[7], role.getName());
        }
        System.out.println();


    }

    public void shoeRole() {
        System.out.print("姓名:" + this.getName() + ";");
        System.out.print("血量:" + this.getHp() + ";");
        System.out.print("性别:" + this.getGender() + ";");
        System.out.print("长相:" + this.getFace() + ";");
        System.out.println();
    }
}
package Test2;

public class PlayGame {
    public static void main(String[] args) {
        // 第一个角色
        Role role1 = new Role("鸠摩智", 100, '男');

        // 第二个角色
        Role role2 = new Role("乔峰", 100, '女');

        role1.shoeRole();
        role2.shoeRole();

        while (true) {
            role1.attack(role2);
            role2.attack(role1);
            if (role1.getHp() <= 0) {
                System.out.println(role2.getName() + "K.O了" + role1.getName());
                break;
            }else if (role2.getHp() <= 0) {
                System.out.println(role1.getName() + "K.O了" + role2.getName());
                break;
            }
        }
    }
}

多了两个属性,性别和长相,行为不变。

从构造方法讲起,因为是我自己写的,所以无参构造用不上,可以不用,但不能没有

public Role(String name, int hp, char gender) {
	this.name = name;
    this.hp = hp;
    this.gender = gender;
    setFace(gender);  // 随机长袖
}

姓名、血量、性别都是我们写的,长相是系统生成的,所以在这里需要调用ssetFace(),方法。

public void setFace(char gender) {
    Random r = new Random();
	if (gender == '男') {
        int index = r.nextInt(boyfaces.length);
    	this.face = boyfaces[index];
	}else if (gender == '女') {
        int index = r.nextInt(girlfaces.length);
    	this.face = girlfaces[index];
	}
}

上面有一个容颜数组,是从那个里面随机抽取元素的,男角色和女角色各不同,然后用this给成员变量赋值。

public void attack(Role role) {
	Random r = new Random();
    // 随机获取一个攻击描述
    int indexAttacks  = r.nextInt(attacks_desc.length);
    String KungFu = attacks_desc[indexAttacks];
    System.out.printf(KungFu, this.getName(), role.getName());

    // 随机造成伤害
    int hurt = r.nextInt(15);  // 随机伤害
    
    int res = role.getHp() - hurt;  // 剩余血量
	res = res <= 0 ? 0: res;  // 血量不能为负数
    role.setHp(res);  // 更改角色血量

    // 随机获取一个受伤描述
    if (res > 90) {
    	System.out.printf(injureds_desc[0], role.getName());
	}else if (res>80 && res<=90) {
    	System.out.printf(injureds_desc[1], role.getName());
	}else if (res>70 && res<=80) {
    	System.out.printf(injureds_desc[2], role.getName());
	}else if (res>60 && res<=70) {
    	System.out.printf(injureds_desc[3], role.getName());
	}else if (res>40 && res<=60) {
    	System.out.printf(injureds_desc[4], role.getName());
	}else if (res>20 && res<=40) {
    	System.out.printf(injureds_desc[5], role.getName());
	}else if (res>10 && res<=20) {
    	System.out.printf(injureds_desc[6], role.getName());
	}else  {
    	System.out.printf(injureds_desc[7], role.getName());
	}
    System.out.println();


    }

其实就是之前学习过的知识,这次招式有了名称,都放在了数组里面,随机招式。那就是随机索引。

判断剩余的血量进行受伤描述。

printf()的使用

这里注意一下输出函数

System.out.println();  // 换行输出	
System.out.print();  // 不换行输出

我们说一下这个

System.out.print()

举个例子

System.out.printf("我叫%s:今年%d岁", "小明", 18);  // 我叫小明:今年18岁

其实如果接触过python、C语言都知道%s%d%c等等都是占位符。

注意数据类型应保持一致

练习二:对象数组练习

对象数组(商品)

  • 需求:

    定义数组存储3个商品对象。

    商品的属性:商品的id,名字,价格,库存。

    创建三个商品对象,并把商品对象存入到数组当中。

代码示例:

package Test3;

public class Goods {
    private int id;  // 商品id
    private String name;  //姓名
    private double price;  // 价格
    private int inventory;  // 库存

    public Goods() {
    }

    public Goods(int id, String name, double price, int inventory) {
        this.id = id;
        this.name = name;
        this.price = price;
        this.inventory = inventory;
    }

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public double getPrice() {
        return price;
    }

    public void setPrice(double price) {
        this.price = price;
    }

    public int getInventory() {
        return inventory;
    }

    public void setInventory(int inventory) {
        this.inventory = inventory;
    }
}

package Test3;

public class GoodsTest {
    public static void main(String[] args) {
        // 存放商品的数组
        Goods[] arr = new Goods[3];

        // 三个商品对象
        Goods goods1 = new Goods(1, "手机", 2999, 100);
        Goods goods2 = new Goods(2, "电脑", 5999, 150);
        Goods goods3 = new Goods(3, "耳机", 299, 50);

        arr[0] = goods1;
        arr[1] = goods2;
        arr[2] = goods3;

        for (int i = 0; i < arr.length; i++) {
            Goods temp = arr[i];
            System.out.println(temp.getId()+ ", " + temp.getName() + ", " + temp.getPrice() + ", " + temp.getInventory());
        }
    }
}

可以看出来,我们定义的类可以当作一个数据类型来用

Goods[] arr = new Goods[3];

然后就是用到了之前学习的内容。

但我很好奇,数组里的元素存放的是什么,对象地址?如果是的对象的地址,那是个十六进制数字,为什么要说Goods[]`类型。

对象数组(汽车)

  • 需求:

    定义数组存储3部汽车对象。

    汽车的属性:品牌,价格,颜色。

    创建三个汽车对象,数据通过键盘录入而来,并把数据存入到数组当中。

代码示例:

package Test4;

public class Car {
    private String brand;  // 品牌
    private double price;  // 价格
    private String color;  // 颜色

    public Car() {

    }

    public Car(String brand, double price, String color) {
        this.brand = brand;
        this.price = price;
        this.color = color;
    }

    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 String getColor() {
        return color;
    }

    public void setColor(String color) {
        this.color = color;
    }
}

package Test4;

import java.util.Scanner;

public class CarTest {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);

        // 存放汽车的数组
        Car[] cars = new Car[3];

        // 录入汽车的属性
        for (int i = 0; i < cars.length; i++) {
            // 抽奖汽车对象
            Car car = new Car();

            // 录入汽车品牌、价格、颜色
            System.out.println("===请输入第" + (i+1) + "辆汽车信息===");
            System.out.println("请输入品牌:");
            car.setBrand(sc.next());
            System.out.println("请输入价格:");
            car.setPrice(sc.nextDouble());
            System.out.println("请输入颜色:");
            car.setColor(sc.next());

            // 放进数组里面
            cars[i] = car;
        }

        // 打印小汽车的信息
        System.out.println("=====小汽车信息预览=====");
        for (int i = 0; i < cars.length; i++) {
            Car car = cars[i];
            System.out.println(car.getBrand() + ", " + car.getPrice() + ", " + car.getColor());
        }
    }
}

这部分有点难,我一开始没有想到

// 录入汽车的属性
for (int i = 0; i < cars.length; i++) {
	// 抽奖汽车对象
    Car car = new Car();

   // 录入汽车品牌、价格、颜色
   System.out.println("===请输入第" + (i+1) + "辆汽车信息===");
   System.out.println("请输入品牌:");
   car.setBrand(sc.next());
   System.out.println("请输入价格:");
   car.setPrice(sc.nextDouble());
   System.out.println("请输入颜色:");
   car.setColor(sc.next());

   // 放进数组里面
   cars[i] = car;
}	

在循环里面创建一个汽车对象,因为汽车的属性是要输入的,所以只能使用无参构造方法,但是一个完整的JavaBean类应该质数提供两个构造方法,所以我也把带全参的构造方法写上去了,其实也就是快捷键的工作Alt + Insert

创建了一个汽车对象,然后通过录入获取参数,其实也可以这样写

String brand = sc.next();
car.setBrand(brand);

我直接一句话解决:car.setBrand(sc.next());

汽车录入完了存放进数组里面cars[i] = car;

下一次循环,又会创建一个新的汽车对象。

一开始没有想到这里,而是受上道题的影响,上了创建了三个对象,然后赋值,也是成功了,但这样不好,把代码写死了。达咩。

对象数组(手机)

  • 需求

    定义数组存储3部手机对象。

    手机的属性:品牌,价格,颜色

  • 要求

    计算出三部手机的平均价格

package Test5;

public class Phone {
    private String brand;  // 品牌
    private double price;  // 价格
    private String color;  // 颜色

    public Phone() {

    }

    public Phone(String brand, double price, String color) {
        this.brand = brand;
        this.price = price;
        this.color = color;
    }

    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 String getColor() {
        return color;
    }

    public void setColor(String color) {
        this.color = color;
    }
}

package Test5;


import java.util.Scanner;

public class PhoneTest {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        double priceAvg = 0;  // 手机平均价格

        // 存放汽车的数组
        Phone[] phones = new Phone[3];

        // 录入汽车的属性
        for (int i = 0; i < phones.length; i++) {
            // 抽奖汽车对象
            Phone car = new Phone();

            // 录入汽车品牌、价格、颜色
            System.out.println("===请输入第" + (i+1) + "部手机信息===");
            System.out.println("请输入品牌:");
            car.setBrand(sc.next());
            System.out.println("请输入价格:");
            car.setPrice(sc.nextDouble());
            System.out.println("请输入颜色:");
            car.setColor(sc.next());

            // 放进数组里面
            phones[i] = car;
        }

        // 打印小汽车的信息
        System.out.println("=====手机信息预览=====");
        for (int i = 0; i < phones.length; i++) {
            Phone car = phones[i];
            priceAvg += car.getPrice();
            System.out.println(car.getBrand() + ", " + car.getPrice() + ", " + car.getColor());
        }

        priceAvg /= phones.length;
        System.out.printf("手机的平均价格是:%f", priceAvg);
    }
}

数据可以不用输入,直接使用全参构造方法,这里就回到了第二题

我是直接把上面题的代码复制了过来,稍微改动了一下,

我们看重点部分

// 打印小汽车的信息
System.out.println("=====手机信息预览=====");
for (int i = 0; i < phones.length; i++) {
	Phone car = phones[i];
    priceAvg += car.getPrice();
    System.out.println(car.getBrand() + ", " + car.getPrice() + ", " + car.getColor());
}

priceAvg /= phones.length;
System.out.printf("手机的平均价格是:%f", priceAvg);

getPrice()方法获取每个手机的价格

priceAvg += car.getPrice();

然后求平均

priceAvg /= phones.length;

数组练习4

  • 需求

    定义数组存储4个女朋友的对象 女朋友的属性:姓名、年龄、性别、爱好

  • 要求

    计算出四女朋友的平均年龄

    2- 统计年龄比平均值低的女朋友有几个?并把她们的所有信息打印出来。

package Test6;

public class GirlFriend {
    private String name;
    private int age;
    private String job;
    private String hobby;

    public GirlFriend() {
    }

    public GirlFriend(String name, int age, String job, String hobby) {
        this.name = name;
        this.age = age;
        this.job = job;
        this.hobby = hobby;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public String getJob() {
        return job;
    }

    public void setJob(String job) {
        this.job = job;
    }

    public String getHobby() {
        return hobby;
    }

    public void setHobby(String hobby) {
        this.hobby = hobby;
    }
}


package Test6;


public class GirlFriendTest {
    public static void main(String[] args) {
        GirlFriend[] girlFriends = new GirlFriend[4];
        int ageAvg = 0;  // 平均

        GirlFriend girlFriend1 = new GirlFriend("小莉莉", 18, "视频剪辑", "玩游戏");
        GirlFriend girlFriend2 = new GirlFriend("小诗诗", 19, "java开发", "睡觉");
        GirlFriend girlFriend4 = new GirlFriend("小惠惠", 20, "银行", "吃零食");
        GirlFriend girlFriend3 = new GirlFriend("小丹丹", 21, "前端工程师", "学习");

        girlFriends[0] = girlFriend1;
        girlFriends[1] = girlFriend2;
        girlFriends[2] = girlFriend3;
        girlFriends[3] = girlFriend4;

        for (int i = 0; i < girlFriends.length; i++) {
            GirlFriend girlFriend = girlFriends[i];
            ageAvg += girlFriend.getAge();
        }

        ageAvg /= girlFriends.length;
        System.out.println("女朋友们的平均年龄是:" + ageAvg);

        // 统计女朋友们年龄情况
        for (int i = 0; i < girlFriends.length; i++) {
            GirlFriend girlFriend = girlFriends[i];
            if (girlFriend.getAge() < ageAvg) {
                System.out.printf(girlFriend.getName() + ", " + girlFriend.getAge() + ", " + girlFriend.getJob() + ", " + girlFriend.getHobby());
            }
        }
    }
}

把对象存进数组里面,就是对数组元素进行操作了,这个在之前也是学习过。

for (int i = 0; i < girlFriends.length; i++) {
	GirlFriend girlFriend = girlFriends[i];
    if (girlFriend.getAge() < ageAvg) {
    	System.out.printf(girlFriend.getName() + ", " + girlFriend.getAge() + ", " + girlFriend.getJob() + ", " + girlFriend.getHobby());
    }
}

对象数组5

  • 需求

    定义一个长度为3的数组,数组存储1~3名学生对象作为初始数据,学生对象的学号,姓名各不相同。

    学生的属性:学号,姓名,年龄。

  • 要求

    再次添加一个学生对象,并在添加的时候进行学号的唯一性判断。

    添加完毕之后,遍历所有学生信息。

    通过id删除学生信息 如果存在,则删除,如果不存在,则提示删除失败。

    删除完毕之后,遍历所有学生信息。

    查询数组id为“2”的学生,如果存在,则将他的年龄+1岁

package Test7;

import java.util.Scanner;

public class Student {
    private int id;
    private String name;
    private int age;

    public Student() {
    }

    public Student(int id, String name, int age) {
        this.id = id;
        this.name = name;
        this.age = age;
    }

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    //id唯一性,判断方法调用者的id是否与其他对象重复
    public boolean primaryId(Student[] students) {
        for (int i = 0; i < students.length; i++) {
            Student student = students[i];
            // 解决NullPointerException报错
            if (student != null) {
                if (students[i].getId() == this.getId()) {
                    return true;  // 有重复
                }
            }
        }
        return false;  // 无重复
    }

}

package Test7;

import java.util.Scanner;

public class StudentTest {
    public static void main(String[] args) {
        // 学生数组
        Student[] students = new Student[5];

        // 三个学生对象作为初始化数据
        Student stu1 = new Student(1, "小明", 17);
        Student stu2 = new Student(2, "小红", 19);
        Student stu3 = new Student(3, "小刚", 18);
        students[0] = stu1;
        students[1] = stu2;
        students[2] = stu3;

        // 要求1,再次添加一个学生对象,并在添加的时候进行学号的唯一性判断。
        addStudent(students);

        //要求2,添加完毕之后,遍历所有学生信息。
        printStudent(students);

        // 要求3,通过id删除学生信息 如果存在,则删除,如果不存在,则提示删除失败。
        deleteStudent(students);

        // 要求4,删除完毕之后,遍历所有学生信息。
        printStudent(students);

        // 要求5,查询数组id为“2”的学生,如果存在,则将他的年龄+1岁
        findStudent(students);
        printStudent(students);
    }

    // 添加学生方法
    public static void addStudent(Student[] students) {
        Scanner sc = new Scanner(System.in);
        // 添加学生
        for (int i = 3; i < 4; i++) {
            Student stu = new Student();
            System.out.println("=====请输入学生信息=====");
            System.out.println("请输入学生ID:");
            int id = sc.nextInt();
            stu.setId(id);
            boolean primary = stu.primaryId(students);
            // true:id重复,重新输入
            while (primary) {
                System.out.println("学生id有重复,重新输入");
                id = sc.nextInt();
                stu.setId(id);
                primary = stu.primaryId(students);
            }

            System.out.println("请输入学生姓名:");
            String name = sc.next();
            stu.setName(name);

            System.out.println("请输入学生年纪:");
            int age = sc.nextInt();
            stu.setAge(age);
            students[i] = stu;  // 把学生对象放进数组
        }
    }

    // 删除学生方法
    public static void deleteStudent(Student[] students) {
        Scanner sc = new Scanner(System.in);
        System.out.println("请输入学生学号,删除学生信息:");
        int id = sc.nextInt();
        boolean exist = existId(id, students);

        // 对学号进行判断,是否存在
        while (!exist) {
            System.out.println("学号不存在,重新输入");
            id = sc.nextInt();
            exist = existId(id, students);
        }
        // 判断学号是否存在,存在,删除;不存在,提示
        for (int i = 0; i < students.length; i++) {
            Student student = students[i];
            if (student != null) {
                if (id == student.getId()) {
                    students[i] = null;  // 删除学生,指定为空
                    System.out.println("删除成功");
                }
            }
        }
    }

    // 通过id查找学生并修改信息
    public static void findStudent(Student[] students) {
        Scanner sc = new Scanner(System.in);
        System.out.println("请输入学生学号,修改学生信息(年纪+1):");
        int id = sc.nextInt();
        boolean exist = existId(id, students);

        // 对学号进行判断,是否存在
        while (!exist) {
            System.out.println("学号不存在,重新输入");
            id = sc.nextInt();
            exist = existId(id, students);
        }

        // 找这个id的学生信息
        for (int i = 0; i < students.length; i++) {
            Student student = students[i];
            if (student != null) {
                if (id == student.getId()) {
                    int age = student.getAge();
                    student.setAge(age + 1);  // 年龄+1
                    System.out.println("学生信息修改成功");
                }
            }
        }

    }

    // 打印所有学生信息
    public static void printStudent(Student[] students) {
        for (int i = 0; i < students.length; i++) {
            Student stu = students[i];
            // 如果有元素,就输出,解决NullPointerException报错
            if (stu != null){
                System.out.println(stu.getId() + ", " + stu.getName() + ", " + stu.getAge());
            }
        }
    }

    // 判断id是否存在
    public static boolean existId(int id, Student[] students) {
        for (int i = 0; i < students.length; i++) {
            Student student = students[i];
            if (student != null) {
                if (id == student.getId()) {
                    return true;  // 存在
                }
            }
        }
        return false;  // 不存在
    }
}

这道题复杂,但又不复杂。

看到三个学生对象,那么面向对象编程的思想就创建一个学生类,学生类的属性都标明了,那就是定义,然后生成一个标准的JavaBean类,行为,题目中没有给出,那就不管。这些已经是常规操作。

把已经创建好的三个学生对象存放到数组里面,数组里面存放的是学生对象,那么就要是Student[]类型,在通过索引把已经创建好的三个学生对象存入数组

要求1和要求2,添加学生信息,并且判断学号唯一性。在这里我想到了封装思想,所以想把这个方法当成对象的一个行为,定义在JavaBean里面

//id唯一性,判断方法调用者的id是否与其他对象重复
public boolean primaryId(Student[] students) {
	for (int i = 0; i < students.length; i++) {
    	Student student = students[i];
        // 解决NullPointerException报错
        if (student != null) {
        	if (students[i].getId() == this.getId()) {
            	return true;  // 有重复
			}
    	}
	}
	return false;  // 无重复
}

让方法调用者的id去跟数组里面每个学生对象的id去比较,

public static void addStudent(Student[] students) {
	Scanner sc = new Scanner(System.in);
    // 添加学生
    for (int i = 3; i < 4; i++) {
    	Student stu = new Student();
        System.out.println("=====请输入学生信息=====");
        System.out.println("请输入学生ID:");
        int id = sc.nextInt();
        stu.setId(id);
        boolean primary = stu.primaryId(students);
        // true:id重复,重新输入
        while (primary) {
        	System.out.println("学生id有重复,重新输入");
            id = sc.nextInt();
            stu.setId(id);
            primary = stu.primaryId(students);
		}
      ...

先用键盘录入一个id,然后用setId()这个方法给这个对象的成员变量id 进行赋值。

然后再定义一个变量primary 来确定在这个id是否重复。

如果重复,方法返回true,不重复,返回false

如果重复,返回的是true下面的while()循环就会一直循环,学号重复,重新输入,然后赋值调用方法。

就这样,一个学生对象的信息就会输入进数组,遍历这个数组。

注意两点

在遍历数组里面元素的时候,元素的对象的时候,推荐使用这个方法

for (int i = 0; i < students.length; i++) {
	Student student = students[i];
}

定义一个临时变量,把数组里的对象临时接收一下,这样比较清晰

还有一个问题,也是出现在这个里面

// 解决NullPointerException报错
if (student != null) {

}

因为我定义数组的时候,把数组开大了。

// 学生数组
Student[] students = new Student[5];

这道题最多出现了四个元素。

然后在我-遍历每个数组的时候,有或一个两个元素里面是空的,这时就会引发空指针问题,

在对数组里的对象操作之前,先判断一个是否是空对象,然后再操作

要求3,要求4删除学生,修改学生,就是还是通过学号去找,

比如我要删除学号为1的学生信息, 那就通过id找到这个学生的信息

if (id == student.getId()) {
	students[i] = null;  // 删除学生,指定为空
    System.out.println("删除成功");
}

把这个学生找到了然后直接让这个元素为null,注意是students[i] = null;,我一开始写成了Student = null;没有报错,也没有删除学生信息,我找了半天,看了上一章的学习笔记是students[i] = null;

年龄+1

那就是把这段students[i] = null;替换成 student.setAge(age + 1); // 年龄+1

这题结束

总结

面向对象的练习,看着都很难,等做出来,然后我又记录了一遍做题过程,不难。

再数组对象中,我觉得最最最重要的是明白

// 存放商品的数组
Goods[] arr = new Goods[3];

// 存放汽车的数组
Car[] cars = new Car[3];

// 存放汽车的数组
Phone[] phones = new Phone[3];
...

在我的印象中定义数组是这样的int[] arr,也可以是String[]double[]

但是Goods[]Car[]Phone[]是什么?

虽然我还是解释不通,但是可以这么想想,对象存放在堆里面,存放在堆里面的数据都被称为引用数据类型。那么这个对象就是引用数据类型。是个数据类型,那就是可以用了,但是这样又感觉说不通,先不管了,知道有这么一种用法就可以。

然后是封装思想,格斗游戏那个我可以理解,攻击是人物的一个行为,

验证学生对象我想着也是学生的一个行为,可是老师定义在了Java测试类里面

好了,我的学习笔记到此结束。

里面肯定有许许多多的bug,欢迎大家指出!毕竟这样成长更快。

也感谢大家可以看到这样,如果帮到了你,是我的荣幸。

谢谢大家!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值