Java-基础篇【面向对象基础、String、集合】

1:设计类

2:定义类的注意事项

 

package com.itheima.createobject;

public class Car {
    // 属性(成员变量)
    String name; // 名称
    double price; // 价格
    // 行为(方法)
    public void start(){
        System.out.println(name + " 价格是:" + price +", 启动成功!");
    }
    public void run(){
        System.out.println(name + " 价格是:" + price +", 跑的很快!");
    }
}
package com.itheima.createobject;

/**
目标:学习定义类的一些注意事项。
 成员变量修饰符暂时不写
 实际开发中一个代码文件不建议定义多个类:分开定义
 */
public class Student {
    // 修饰符 数据类型 变量名称 = 初始化值;
    String name;        //  修饰符暂时不写,初始值暂时不给
    double height;
}
class Animal{   // 不能public修饰
}
class Cat{
}
package com.itheima.createobject;
/**
目标:掌握自己设计类,并获得对象
 类名 对象名 = new 类名()
 */
public class Test {
    public static void main(String[] args) {
        // 如何去获取汽车的对象。
        Car c1 = new Car();
        System.out.println(c1);
        c1.name = "宝马X3";
        c1.price = 37.89;
        System.out.println(c1.name);
        System.out.println(c1.price);
        c1.start();
        c1.run();

        System.out.println("-------------------");
        Car c2 = new Car();
        c2.name = "奔驰GLC";
        c2.price = 39.89;
        System.out.println(c2.name);
        System.out.println(c2.price);
        c2.start();
        c2.run();
    }
}
package com.itheima.createobject;
public class Test2 {
    public static void main(String[] args) {
        Student s1 = new Student();     // 创建学生对象
        System.out.println(s1.name);        //  整数默认值:0     double类型默认值:0.0     引用数据类型默认值:null
        System.out.println(s1.height);

        Student s2 = new Student();
        System.out.println(s2.name);
        System.out.println(s2.height);
    }
}
package com.itheima.createobject;

public class test_ywt {
    public static void main(String[] args) {
        System.out.printf("hello");
    }
    public static void printArray(int[] arr){
        for (int i = 0; i < arr.length; i++) {
            System.out.print(arr[i] + " ");
        }
        System.out.println();
    }
}

3:成员变量默认值

4:多个对象的内存图

1:对象到底是放在哪个位置的?
  堆内存中
2: Car c = new Car();  c变量名中存储的是什么?
  存储的是对象在堆内存中的地址。
3: 成员变量(name、price)的数据放在哪里,存在于哪个位置?
  对象中,存在于堆内存中。
package com.itheima.memory;

public class Student {
    String name;
    char sex;
    String hobby;
    public void study(){
        System.out.println("姓名:" + name +",性别是:" + sex
                + ",爱好是:" + hobby + "的学生在好好学习,天天向上!");
    }
}
package com.itheima.memory;

/**
 对象内存图
    方法都是加载到栈里运行的,运行完了再退出去
    1:Test.class 和 Car.class 文件的 代码方法和类加载到 方法区域
    2:main函数加载到栈内存 运行
    3:栈内存生成 s1这个 引用类型变量【对象变量】
    4:new Student()在堆内存分配一块区域,对象区域,对象分配对象的属性空间name和price【成员变量空间】
    一开始默认数据NULL和0
    存储对象的行为方法
    方法不会之间加载到堆内存区域,因为浪费空间,方法直接放在 class文件加载的方法区就行,堆内存中存在一份
        对象能够找到方法,说明堆内存里还是存储一个  成员方法引用地址 ,指向方法区的地址以便能够调用
        对象也有一个在堆内存地址,赋值给栈内存里 s1这个变量指向,s1指向这个对象
    5:s1变量存储的对象地址找到对象,去操作对象里的属性和方法【赋值  打印】
    6:s1.study() s1找到 对象,然后根据 对象里 方法引用地址 找到方法区域的 study这个方法
    study方法加载到栈里运行,s1调用的study方法,方法再访问s1相应的内部的成员变量执行 study方法

    对象是存储在堆内存里的,成员变量也是存储在对象里的
    s1 和 s2这些对象变量 存储的是对象在堆内存中的地址
两个变量指向同一个对象内存图:
垃圾回收:
    注意:当堆内存中的对象【类对象,数组对象】,没有被任何变量引用(指向)时,就会被判定为内存中的“垃圾”
    下面的代码:有一个学生对象 由 s1 和s2指向,
    s1=null取消指向  s2=null也取消指向,指向学生对象的两条线都掐断,这样内存中的学生对象变成垃圾对象,会被java垃圾回收机制定期清除【自动清除】
 */
public class Test {
    public static void main(String[] args) {
        // 目标:掌握2个变量指向同一个对象的形式
        Student s1 = new Student();
        s1.name = "小明";
        s1.sex = '男';
        s1.hobby = "睡觉、游戏、听课";
        s1.study();

        // 关键:把s1赋值给学生类型的变量s2
        Student s2 =  s1;   // s1 和 s2指向同一个变量
        System.out.println(s1);
        System.out.println(s2);

        s2.hobby = "爱提问";

        System.out.println(s2.name);
        System.out.println(s2.sex);
        System.out.println(s1.hobby);
        s2.study();

//        s1 = null;
//        s2 = null;
//        System.out.println(s1.name);
    }
}

5:两个变量指向同一个对象内存解析

6:垃圾回收机制

垃圾回收:
    注意:当堆内存中的对象,没有被任何变量引用(指向)时,就会被判定为内存中的“垃圾”。

7:面向对象之——构造器

package com.itheima.constructor;

public class Car {
    String name;
    double price;
    public Car(){        // 无参数构造器(默认存在的)
        System.out.println("无参数构造器被触发执行~~~");
    }
    public Car(String n, double p){      // 有参数构造器
        System.out.println("有参数构造器被触发执行~~~");
        name = n;       // 当前成员变量的name 赋值成 外面类实例化传参过来的参数 n
        price = p;
    }
}
package com.itheima.constructor;
/**
目标:明白构造器的作用和分类。(开发的人,理解能力好)
 */
public class ConstructorDemo {
    public static void main(String[] args) {
        Car c = new Car();      // 调用无参数构造器(默认存在的)
//        c.name = "";
//        c.price
        System.out.println(c.name);     // 访问属性使用的默认值
        System.out.println(c.price);        // 访问属性使用的默认值
        Car c2 = new Car("奔驰GLC", 39.78);   // 调用有参数构造器
        System.out.println(c2.name);
        System.out.println(c2.price);
    }
}

8:this关键字

package com.itheima.thisdemo;

public class Car {
    String name;
    double price;

    public void goWith(String name){
        System.out.println(this.name +"正在和:" + name +"比赛!");
    }

    public Car(){       // 无参数构造器(默认存在的)
        System.out.println("无参数构造器被触发执行~~~");
    }

//    public Car(String name, double price){
//        name = name;
//        price = price;
//        // 这样写不可以,name=name,等号前面的name访问传参name,等号后面的name还是访问的传参name,
//不会修改对象变量String name【自己值给自己赋值】【没有给当前成员变量赋值,采用 this】
// } // public Car(String a, double b){ // name = a; // price = b; // // 这样写才可以赋值,采用不同的变量名字,标准还是使用this // } public Car(String name, double price){ // 有参数构造器 System.out.println("有参数构造器被触发执行~~~"); System.out.println(this); this.name = name; // name赋值给当前对象成员变量的name this.price = price; // price赋值给当前对象成员变量的price } }
package com.itheima.thisdemo;

/**
    目标:说出this关键字的作用,并学会其使用。
 */
public class ThisDemo {
    public static void main(String[] args) {
        Car c = new Car("宝马X3", 37.89);
        System.out.println(c);
        System.out.println(c.name);
        System.out.println(c.price);

        c.goWith("奔驰GLC");
    }
}

9:封装

10:封装的常见手段  private关键字的使用

package com.itheima.encapsulation;

public class Student {
    // private私有的成员变量,只能在本类访问。
   private int age;

   public int getAge(){
       return age;
   }
   public void setAge(int age){
        if(age >= 0 && age <= 200){
            this.age = age;
        }else {
            System.out.println("年龄数据有问题,应该不是人的年龄!");
        }
   }
}
package com.itheima.encapsulation;
/**
    目标:学会面向对象的三大特征:封装的形式、作用。
 */
public class Test {
    public static void main(String[] args) {
        Student s = new Student();
        // s.age = -23;
        s.setAge(-23);
        System.out.println(s.getAge());
    }
}

11:JavaBean标准编程

package com.itheima.javabean;

public class User {
    private double height;      // 1:成员变量私有化,使用 private修饰
    private String name;
    private double salary;
    private String address;
    private String phone;

    public User() {     // 3:无参数构造器,默认自带的
        //  鼠标右键——>Generate——>Construct——>select None一个都不选——>点击ok自动生成无参数构造器
    }

    public User(double height, String name, double salary, String address, String phone) {  // 有参数构造器
        //  鼠标右键——>Generate——>Construct——>shift全选所有的private私有成员变量——>点击ok自动生成有参数构造器
        this.height = height;
        this.name = name;
        this.salary = salary;
        this.address = address;
        this.phone = phone;
    }

    // 2:提供成员变量的 set get方法
    //  鼠标右键——>Generate——>Getter and Setter——>shift全选所有的private私有成员变量——>点击ok自动生成Getter and Setter方法
    // 自动生成的 方法没有安全校验的,比如身高需要 1-2米,这里面没有校验
    public double getHeight() {
        return height;
    }

    public void setHeight(double height) {
        this.height = height;
    }

    public String getName() {
        return name;
    }

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

    public double getSalary() {
        return salary;
    }

    public void setSalary(double salary) {
        this.salary = salary;
    }

    public String getAddress() {
        return address;
    }

    public void setAddress(String address) {
        this.address = address;
    }

    public String getPhone() {
        return phone;
    }

    public void setPhone(String phone) {
        this.phone = phone;
    }
}
package com.itheima.javabean;
/**
JavaBean
    也可以称为实体类【现实生活中有个体的】,其对象可以用于在程序中封装数据
    学生类,汽车类,用户类:实体类
    测试类不是:非实体类
    new 一个学生对象就可以封装学生的数据
标准JavaBean【实体类】须满足如下书写要求
    成员变量使用 private 修饰。
    提供成员变量对应的 setXxx() / getXxx()方法。
    必须提供一个无参构造器;有参数构造器是可写可不写的
    满足这 3 个要求就可以认为是一个标准的 JavaBean【java实体类】
 */
public class Test {
    public static void main(String[] args) {
        User user = new User();     // 无参数构造器
        user.setName("二狗");
        user.setHeight(163);
        user.setSalary(50000);
        user.setAddress("中国");
        user.setPhone("13141314520");
//        String name = user.getName();
//        System.out.println(name);
        System.out.println(user.getName());
        System.out.println(user.getHeight());
        System.out.println(user.getSalary());
        System.out.println(user.getAddress());
        System.out.println(user.getPhone());

        System.out.println("--------------------");
        User user1 = new User(176, "黑马吴彦祖", 30000, "黑马", "110");     //// 参数构造器
        System.out.println(user1.getName());
        System.out.println(user1.getHeight());
        System.out.println(user1.getSalary());
        System.out.println(user1.getAddress());
        System.out.println(user1.getPhone());
    }
}
package com.itheima.javabean2;
/**
 private String name;       私有成员变量,外部无法通过对象 a.name 访问了。只能通过 getName 方法访问
 */
public class Article {      // 商品对象
    private String name;    // 名称
    private double price;   // 价格
    private int buyNumber; // 购买数量

    public Article() {
    }

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

    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 getBuyNumber() {
        return buyNumber;
    }

    public void setBuyNumber(int buyNumber) {
        this.buyNumber = buyNumber;
    }
}
package com.itheima.javabean2;

import java.util.Scanner;

public class Test {
    public static void main(String[] args) {
        Article[] shopCar = new Article[10];    // a、定义一个数组存储商品对象的,代表购物车对象。
        // Article:引用类型,商品类型的数组,里面存储商品对象。长度10,这里存储的还是商品的地址,默认值为null
        // b、让用户选择功能
        while (true) {
            Scanner sc = new Scanner(System.in);
            System.out.println("添加商品:add");
            System.out.println("查看商品:query");
            System.out.println("修改数量:update");
            System.out.println("结算价格:pay");
            System.out.println("请您选择要操作的功能:");
            String command = sc.next();
            switch (command) {
                case "add":
                    addArticle(shopCar);        // 把商品加入到购物车中去,参数是 shopCar 购物车去添加商品  alt + 回车 :快捷生成方法
                    break;
                case "query":
                    queryArticle(shopCar);      // 查看购物车中的商品信息
                    break;
                case "update":
                    updateArticle(shopCar);     // 修改商品的购买数量
                    break;
                case "pay":
                    calcPayMoney(shopCar);      // 查结算金额
                    break;
                default:        // 输入命令有问题走这个
                    System.out.println("当前命令输入有误!");
            }
            String q = "QQ";
            System.out.println(command == q );
//            if(command == "Q"){
//                System.out.println("等于啊");
//            }
            if(command.equals("Q")){
                break;
            }
        }
    }

    private static void calcPayMoney(Article[] shopCar) {
        queryArticle(shopCar);
        double money = 0;       // 准备一个double类型的变量统计总金额
        for (int i = 0; i < shopCar.length; i++) {
            Article a = shopCar[i];
            if(a != null){
                money += (a.getPrice() * a.getBuyNumber());
            }else {
                break;
            }
        }
        System.out.println("本次商品购买的总价为:" + money);
    }

    public static void updateArticle(Article[] shopCar) {
        Scanner sc = new Scanner(System.in);
        while (true) {
            System.out.println("请您输入要修改数量的商品名称:");
            String name = sc.next();
            Article a = getArticleByName(name , shopCar );  // 返回根据商品名称找到的商品对象,也可能返回null
            if(a != null){      // 找到了商品对象
                System.out.println("请您输入修改后购买的数量:");
                int buyNumber = sc.nextInt();
                a.setBuyNumber(buyNumber);        // 更新修改数量
                System.out.println("该商品的购买数量修改了!");
                break;      //  商品修改完成break
            }else {     // 没有找到商品对象,继续输入,找到为止
                System.out.println("购物车中没有该商品信息");
            }
        }
    }

    public static Article getArticleByName(String name , Article[] shopCar){
        // 查根据名字返回商品对象:Article
        for (int i = 0; i < shopCar.length; i++) {
            Article a = shopCar[i];     // 商品不为null
            if(a != null && a.getName().equals(name) ){
                return a;
            }
        }
        return null;
    }

    public static void queryArticle(Article[] shopCar) {
        System.out.println("============查询购物车信息==========================");
        System.out.println("商品名称\t商品价格\t商品的购买数量");
        // 展示购物车的商品信息
        for (int i = 0; i < shopCar.length; i++) {
            Article a = shopCar[i]; // 接受商品变量,a指向商品变量的地址
            if(a != null){  //  不为null 说明有数据可以展示商品对象
                System.out.println(a.getName() +"\t" + a.getPrice() + "\t" + a.getBuyNumber());
            }else {     // 为null说明循环遍历结束了
                return; // break; 也可以
            }
        }
    }

    public static void addArticle(Article[] shopCar) {  // 参数接受一个商品数组购物车
        Scanner sc = new Scanner(System.in);        // 1:录入用户输入的商品信息
        System.out.println("请您输入商品的名称:");
        String name = sc.next();
        System.out.println("请您输入商品的价格:");
        double price = sc.nextDouble();
        System.out.println("请您输入购买商品的数量:");
        int buyNumber = sc.nextInt();

        Article a = new Article();
        a.setName(name);
        a.setPrice(price);
        a.setBuyNumber(buyNumber);

        for (int i = 0; i < shopCar.length; i++) {
            if(shopCar[i] == null){
                shopCar[i] = a;
                break;
            }
        }
        System.out.println("添加成功!");
    }
}
//package com.itheima.javabean2;
//
//import java.util.Scanner;
//
//public class TestArticle {
//    public static void main(String[] args) {
//        Article[] shopCar = new Article[10];    // a、定义一个数组存储商品对象的,代表购物车对象。
//        // Article:引用类型,商品类型的数组,里面存储商品对象。长度10,这里存储的还是商品的地址,默认值为null
//        // b、让用户选择功能
//        while (true) {
//            Scanner sc = new Scanner(System.in);
//            System.out.println("添加商品:add");
//            System.out.println("查看商品:query");
//            System.out.println("修改数量:update");
//            System.out.println("结算价格:pay");
//            System.out.println("请您选择要操作的功能:");
//            String command = sc.next();
//            switch (command) {
//                case "add":
//                    addArticle(shopCar);        // 把商品加入到购物车中去,参数是 shopCar 购物车去添加商品  alt + 回车 :快捷生成方法
//                    break;
//                case "query":
//                    queryArticle(shopCar);      // 查看购物车中的商品信息
//                    break;
//                case "update":
//                    updateArticle(shopCar);     // 修改商品的购买数量
//                    break;
//                case "pay":
//                    calcPayMoney(shopCar);      // 查结算金额
//                    break;
//                case "Q":
//                    break;
//                default:        // 输入命令有问题走这个
//                    System.out.println("当前命令输入有误!");
//            }
//            break;
//        }
//    }
//
//    private static void calcPayMoney(com.itheima.demo.Article[] shopCar) {
//        queryArticle(shopCar);
//        double money = 0;       // 准备一个double类型的变量统计总金额
//        for (int i = 0; i < shopCar.length; i++) {
//            com.itheima.demo.Article a = shopCar[i];
//            if(a != null){
//                money += (a.price * a.buyNumber);
//            }else {
//                break;
//            }
//        }
//        System.out.println("本次商品购买的总价为:" + money);
//    }
//
//    public static void updateArticle(com.itheima.demo.Article[] shopCar) {
//        Scanner sc = new Scanner(System.in);
//        while (true) {
//            System.out.println("请您输入要修改数量的商品名称:");
//            String name = sc.next();
//            com.itheima.demo.Article a = getArticleByName(name , shopCar );  // 返回根据商品名称找到的商品对象,也可能返回null
//            if(a != null){      // 找到了商品对象
//                System.out.println("请您输入修改后购买的数量:");
//                int buyNumber = sc.nextInt();
//                a.buyNumber = buyNumber;        // 更新修改数量
//                System.out.println("该商品的购买数量修改了!");
//                break;      //  商品修改完成break
//            }else {     // 没有找到商品对象,继续输入,找到为止
//                System.out.println("购物车中没有该商品信息");
//            }
//        }
//    }
//
//    public static com.itheima.demo.Article getArticleByName(String name , com.itheima.demo.Article[] shopCar){
//        // 查根据名字返回商品对象:Article
//        for (int i = 0; i < shopCar.length; i++) {
//            com.itheima.demo.Article a = shopCar[i];     // 商品不为null
//            if(a != null && a.name.equals(name) ){
//                return a;       // a.name.equals(name)      判断 a这个商品的name字段等于我们预期传递来的参数name,是不是我们要找的
//            }
//        }
//        return null;    // 循环了 100 个了,还没有找到,就返回 null
//    }
//
//    public static void queryArticle(com.itheima.demo.Article[] shopCar) {
//        System.out.println("============查询购物车信息==========================");
//        System.out.println("商品名称\t商品价格\t商品的购买数量");
//        // 展示购物车的商品信息
//        for (int i = 0; i < shopCar.length; i++) {
//            com.itheima.demo.Article a = shopCar[i]; // 接受商品变量,a指向商品变量的地址
//            if(a != null){  //  不为null 说明有数据可以展示商品对象
//                System.out.println(a.name +"\t" + a.price + "\t" + a.buyNumber);
//            }else {     // 为null说明循环遍历结束了
//                return; // break; 也可以
//            }
//        }
//    }
//
//    public static void addArticle(com.itheima.demo.Article[] shopCar) {  // 参数接受一个商品数组购物车
//        Scanner sc = new Scanner(System.in);        // 1:录入用户输入的商品信息
//        System.out.println("请您输入商品的名称:");
//        String name = sc.next();
//        System.out.println("请您输入商品的价格:");
//        double price = sc.nextDouble();
//        System.out.println("请您输入购买商品的数量:");
//        int buyNumber = sc.nextInt();
//
//        // 2:创建一个商品对象,封装这些商品信息
//        Article a = new Article();
//        a.setName(name);
//        a.setPrice(price);
//        a.setBuyNumber(buyNumber);
//
//        // 3:添加商品:遍历这个购物车数组对象,看哪个位置是null,如果是null ,把商品对象添加进去
//        for (int i = 0; i < shopCar.length; i++) {
//            if(shopCar[i] == null){     // == null 说明 这个位置没有元素,就把商品对象添加到购物车里这个位置,存储的商品对象的地址
//                shopCar[i] = a; // 把商品对象添加到这个位置了,商品对象添加到购物车数组中去
//                break;
//            }
//        }
//        System.out.println("添加成功!");
//    }
//}

12:成员变量和局部变量的区别

13:面向对象综合案例

 14:面向对象之综合案例——购物车

package com.itheima.demo;

public class Article {      // 商品对象
    int id;     // 商品编号
    String name;    // 名称
    double price;   // 价格
    int buyNumber; // 购买数量
}
package com.itheima.demo;

import java.util.Scanner;
/**
需求:模拟购物车的功能。
    1、定义一个商品类:Article(属性:名称、价格)
    2、定义一个数组容器存储商品对象的,代表购物车对象。数组对象,容器,存储商品
    3:界面架构,用户选择操作功能
 */
public class Test {
    public static void main(String[] args) {
        Article[] shopCar = new Article[10];    // a、定义一个数组存储商品对象的,代表购物车对象。
        // Article:引用类型,商品类型的数组,里面存储商品对象。长度10,这里存储的还是商品的地址,默认值为null
        // b、让用户选择功能
        while (true) {
            Scanner sc = new Scanner(System.in);
            System.out.println("添加商品:add");
            System.out.println("查看商品:query");
            System.out.println("修改数量:update");
            System.out.println("结算价格:pay");
            System.out.println("请您选择要操作的功能:");
            String command = sc.next();
            switch (command) {
                case "add":
                    addArticle(shopCar);        // 把商品加入到购物车中去,参数是 shopCar 购物车去添加商品  alt + 回车 :快捷生成方法
                    break;
                case "query":
                    queryArticle(shopCar);      // 查看购物车中的商品信息
                    break;
                case "update":
                    updateArticle(shopCar);     // 修改商品的购买数量
                    break;
                case "pay":
                    calcPayMoney(shopCar);      // 查结算金额
                    break;
                case "Q":
                    break;
                default:        // 输入命令有问题走这个
                    System.out.println("当前命令输入有误!");
            }
            break;
        }
    }

    private static void calcPayMoney(Article[] shopCar) {
        queryArticle(shopCar);
        double money = 0;       // 准备一个double类型的变量统计总金额
        for (int i = 0; i < shopCar.length; i++) {
            Article a = shopCar[i];
            if(a != null){
                money += (a.price * a.buyNumber);
            }else {
                break;
            }
        }
        System.out.println("本次商品购买的总价为:" + money);
    }

    public static void updateArticle(Article[] shopCar) {
        Scanner sc = new Scanner(System.in);
        while (true) {
            System.out.println("请您输入要修改数量的商品名称:");
            String name = sc.next();
            Article a = getArticleByName(name , shopCar );  // 返回根据商品名称找到的商品对象,也可能返回null
            if(a != null){      // 找到了商品对象
                System.out.println("请您输入修改后购买的数量:");
                int buyNumber = sc.nextInt();
                a.buyNumber = buyNumber;        // 更新修改数量
                System.out.println("该商品的购买数量修改了!");
                break;      //  商品修改完成break
            }else {     // 没有找到商品对象,继续输入,找到为止
                System.out.println("购物车中没有该商品信息");
            }
        }
    }

    public static Article getArticleByName(String name , Article[] shopCar){
        // 查根据名字返回商品对象:Article
        for (int i = 0; i < shopCar.length; i++) {
            Article a = shopCar[i];     // 商品不为null
            if(a != null && a.name.equals(name) ){
                return a;       // a.name.equals(name)      判断 a这个商品的name字段等于我们预期传递来的参数name,是不是我们要找的
            }
        }
        return null;    // 循环了 100 个了,还没有找到,就返回 null
    }

    public static void queryArticle(Article[] shopCar) {
        System.out.println("============查询购物车信息==========================");
        System.out.println("商品名称\t商品价格\t商品的购买数量");
        // 展示购物车的商品信息
        for (int i = 0; i < shopCar.length; i++) {
            Article a = shopCar[i]; // 接受商品变量,a指向商品变量的地址
            if(a != null){  //  不为null 说明有数据可以展示商品对象
                System.out.println(a.name +"\t" + a.price + "\t" + a.buyNumber);
            }else {     // 为null说明循环遍历结束了
                return; // break; 也可以
            }
        }
    }

    public static void addArticle(Article[] shopCar) {  // 参数接受一个商品数组购物车
        Scanner sc = new Scanner(System.in);        // 1:录入用户输入的商品信息
        System.out.println("请您输入商品的名称:");
        String name = sc.next();
        System.out.println("请您输入商品的价格:");
        double price = sc.nextDouble();
        System.out.println("请您输入购买商品的数量:");
        int buyNumber = sc.nextInt();

        // 2:创建一个商品对象,封装这些商品信息
        Article a = new Article();
        a.name = name;      // 对象里面的成员变量赋值
        a.price = price;
        a.buyNumber = buyNumber;

        // 3:添加商品:遍历这个购物车数组对象,看哪个位置是null,如果是null ,把商品对象添加进去
        for (int i = 0; i < shopCar.length; i++) {
            if(shopCar[i] == null){     // == null 说明 这个位置没有元素,就把商品对象添加到购物车里这个位置,存储的商品对象的地址
                shopCar[i] = a; // 把商品对象添加到这个位置了,商品对象添加到购物车数组中去
                break;
            }
        }
        System.out.println("添加成功!");
    }
}

 15:String类概述

16:String对象的内存概述——之  字符串常量池

String是不可变字符串的原因?
  String变量每次的修改其实都是产生并指向了新的字符串对象。
  原来的字符串对象都是没有改变的,所以称不可变字符串

17:String字符串——之内容比较   equals  和 equalsIgnoreCase

String引用数据类型字符串的内容比较不适合用“==”比较
基本数据类型比较时使用 == 比较
package com.itheima.string;

import java.util.Scanner;
/**
 ==  判断的还是 值相等,基本数据类型变量存储的就是本身的值,可以使用 == 来进行比较
 引用数据类型【string 这些类】,存储的放的是地址,可能内容一样,地址不一样,不适合使用 == 来进行比较,使用String提供的equals方法
  */
public class StringAPIEqualsDemo4 {
    public static void main(String[] args) {
        // 1、正确登录名和密码
        String okName = "itheima";
        String okPassword = "123456";

        // 2、请您输入登录名称和密码
        Scanner sc = new Scanner(System.in);
        System.out.println("登录名称:");
        String name = sc.next();
        System.out.println("登录密码:");
        String password = sc.next();

        if(name == okName && okPassword==password){      // 使用 == 判断是否相等
            System.out.println("==判断 name和 okName是相等的");
        }      // 当前无法使用 == 判断,因为 == 在这里比较的是地址  okName指向的地址是常量池  name接受用户输入信息创建的,放在堆内存里的   指向的地址不一致
        else {
            System.out.println("==判断 name和 okName是不相等的");
        }

        // 3、判断用户输入的登录名称和密码与正确的内容是否相等。
        if(okName.equals(name ) && okPassword.equals(password)){
            System.out.println("登录成功!");
        }else {
            System.out.println("用户名或者密码错误了!");
        }

        // 4、忽略大小写比较内容的Api: 一般用于比较验证码这样的业务逻辑
        String sysCode = "23AdFh";
        String code1 = "23aDfH";
        System.out.println(sysCode.equals(code1)); // false
        System.out.println(sysCode.equalsIgnoreCase(code1)); // true        equalsIgnoreCase忽略大小写比较内容
    }
}

18:String字符串——之 遍历,替换,截取,分割操作

package com.itheima.string;
/**
目标:了解String类的特点:String类不可变的原理
 java.lang.String 类代表字符串,String类定义的变量可以用于指向字符串对象,然后操作该字符串
 Java 程序中的所有字符串文字(例如“abc”)都为此类的对象
双引号标起来的都可以说是字符串对象 String类的特点详解 String其实常被称为不可变字符串类型,它的对象在创建后不能被更改 以“”方式给出的字符串对象,在字符串常量池中存储【堆内存】 "传智"字符串存储在堆内存字符串常量池,name这个变量指向字符串地址空间 name存储的是地址:那么System.out.println(name);为什么打印的是字符串内容 这个 String 类的特殊改发,通过地址把内容输出了【继承里体现】存储的本质还是地址 字符串常量池中存储: "传智" "教育" "中心" name一开始指向 "传智" 然后 "传智" + "教育" 连接成一个新的字符串对象 运算出来的对象存储在 堆内存中 然后name指向最新的 "传智" + "教育" 本质上创建的字符串对象 "传智" "教育" "中心" 没有改变,一直存储在 字符串常量池中 string类型变量name从 指向 "传智" 变成了指向 "传智教育" ,【原来的对象 "传智" 没有改变】 【所以 string 对象是不可变的对象】【下面的中心运算和上面的类似】
*/ public class StringDemo1 { public static void main(String[] args) { String name = "传智"; name += "教育"; // name = name + "教育" name这个对象被覆盖重写指向一个新的 String了,name指向的变量变化了 name += "中心"; System.out.println(name); } }
package com.itheima.string;
/**
目标:掌握String常用的其他API。
 */
public class StringAPIOtherDemo5 {
    public static void main(String[] args) {
        // 1、public int length(): 获取字符串的长度
        String name = "我爱你中国love";
        System.out.println(name.length());

        // 2、public char charAt(int index): 获取某个索引位置处的字符
        char c = name.charAt(1);    // 返回一个字符
        System.out.println(c);

        System.out.println("------------遍历字符串中的每个字符--------------");
        for (int i = 0; i < name.length(); i++) {
            char ch = name.charAt(i);       // ctrl + alt+ v
            System.out.println(ch);
        }
        // 3、public char[] toCharArray():: 把字符串转换成字符数组
        char[] chars = name.toCharArray();  // 字符串转化成一个字符数组
        for (int i = 0; i < chars.length; i++) {
            char ch = chars[i];
            System.out.println(ch);
        }

        // 4、public String substring(int beginIndex, int endIndex) :截取内容,(包前不包后的)
        String name2 = "Java是最厉害的编程语言!";
        //              01234567   89
        String rs = name2.substring(0, 9);      // 包前不包后
        System.out.println(rs);
        String rs1 = name2.substring(4, 9);
        System.out.println(rs1);

        // 5、public String substring(int beginIndex):从当前索引一直截取到末尾
        String rs2 = name2.substring(4);        // 从4位置截取到尾
        System.out.println(rs2);

        // 6、public String replace(CharSequence target, CharSequence replacement)       敏感词替换:replace
        String name3 = "金三胖是最厉害的80后,金三胖棒棒的!我好爱金三胖";
        String rs3 = name3.replace("金三胖", "***");   // 返回的是一个新的内容,原来的name3内容不替换的
        System.out.println(rs3);

        // 7、public boolean contains(CharSequence s)        包含
        System.out.println(name3.contains("金三胖")); // true
        System.out.println(name3.contains("金二胖")); // false

        // 8、public boolean startsWith(String prefix)       以什么开始
        System.out.println(name3.startsWith("金三胖"));
        System.out.println(name3.startsWith("金三胖是最厉害的"));
        System.out.println(name3.startsWith("金三胖是最厉害的2"));

        // 9、public String[] split(String s):   按照某个内容把字符串分割成字符串数组返回。
        String name4 = "王宝强,贾乃亮,陈羽凡";
        String[] names = name4.split(",");
        for (int i = 0; i < names.length; i++) {
            System.out.println("选择了:" + names[i]);
        }
    }
}

18:String简单案例

package com.itheima.string;

import java.util.Random;

/**
练习题:使用String完成随机生成5位的验证码*/
public class StringExec6 {
    public static void main(String[] args) {
        // 1、定义可能出现的字符信息
        String datas = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
        
        // 2、循环5次,每次生成一个随机的索引,提取对应的字符连接起来即可
        String code = "";
        Random r = new Random();        // 随机数对象
        for (int i = 0; i < 5; i++) {
            // 随机一个索引
            int index = r.nextInt(datas.length());
            char c = datas.charAt(index);
            code += c;
        }

        // 3、输出字符串变量即可
        System.out.println(code);
    }
}
package com.itheima.string;

import java.util.Random;
import java.util.Scanner;

/**
练习题:模拟用户登录,3次登录机会、
 */
public class StringExec7 {
    public static void main(String[] args) {
        // 1、定义正确的登录名称和密码
        String okLoginName = "admin";
        String okPassword = "itheima";

        // 2、定义一个循环,循环3次,让用户登录
        Scanner sc = new Scanner(System.in);
        for (int i = 1; i <= 3; i++) {
            System.out.println("请您输入登录名称:");
            String loginName = sc.next();
            System.out.println("请您输入登录密码:");
            String password = sc.next();

            if(okLoginName.equals(loginName)){      // 3、先判断登录是否成功!
                if(okPassword.equals(password)){        // 4、再判断密码是否正确
                    System.out.println("登录成功!欢迎进入系统随意浏览~~~~");
                    break;
                }else {
                    // 密码错误了
                    System.out.println("您的密码不正确!您还剩余" + (3 - i) +"次机会登录!");
                }
            }else {
                System.out.println("您的登录名称不正确!您还剩余" + (3 - i) +"次机会登录!");
            }
        }
    }
}
package com.itheima.string;

import java.util.Scanner;

/**
练习题:手机号码屏蔽
    键盘录入一个手机号,将中间四位号码屏蔽,最终效果为:

分析
    键盘录入一个字符串。
    调用字符串对象的截取API,截取字符串前三位、后四位。
    将前三位 连接“****”然后继续连接后四位,输出最终结果即可
 */
public class StringExec8 {
    public static void main(String[] args) {
        // 1、键盘录入一个手机号码
        Scanner sc = new Scanner(System.in);
        System.out.println("请您输入您的手机号码:");
        String tel = sc.next();

        // 2、截取号码的前三位,后四位    18665666520
        String before = tel.substring(0, 3); // 0  1  2
        String after = tel.substring(7);  // 从索引7开始截取到手机号码的末尾

        String s = before + "****" + after;
        System.out.println(s);
    }
}

19:String创建字符串对象的 2 种方式

package com.itheima.string;

/**
目标:String类创建字符串对象的2种方式
    方式一:直接使用“”定义。(推荐方式)
    方式二:通过String类的构造器创建对象

以“”方式给出的字符串对象,在字符串常量池中存储,而且相同内容只会在其中存储一份。【节省内存资源】
    比如  a = "中国"  在一个项目中可能出现几百上千次,"中国"这个对象内容一致不可变,所以 出现几千次存储一份就行了
通过构造器new对象,每new一次都会产生一个新对象,放在堆内存中
 */
public class StringDemo2 {
    public static void main(String[] args) {
        // 方式一:直接使用双引号得到字符串对象
        String name = "我爱你中国";
        System.out.println(name);   // 特殊优化,本身 name存储的是地址,但是这里打印还是根据地址打印了地址存储的内容

        // 方式二:
        // 1、public String(): 创建一个空白字符串对象,不含有任何内容 (几乎不用)
        String s1 = new String(); // s1 = ""
        System.out.println(s1);

        // 2、public String(String): 根据传入的字符串内容,来创建字符串对象(几乎不用)
        String s2 = new String("我是中国人");
        System.out.println(s2);

        // 3、public String(char[] c): 根据字符数组的内容,来创建字符串对象
        char[] chars = {'a' , 'b' , '中', '国'};          // 【字符数组】
        String s3 = new String(chars);      // 把字符数组里的内容拼接起来
        System.out.println(s3);

        // 4、public String(byte[] b):  根据字节数组的内容,来创建字符串对象   -128-127【字节数组】
        byte[] bytes = {97, 98, 99, 65, 66, 67};
        String s4 = new String(bytes);          // 把字节数组里的整数全部转化成字符 内容再拼接成一个字符串
        System.out.println(s4);

        System.out.println("---------------------------------------");
        String ss1 = "abc";
        String ss2 = "abc";
        System.out.println(ss1 == ss2);     // == 比较两个字符串变量存储的地址
        // == 比较的是ss1的值和ss2的值,也就是两个变量指向的字符串的内容地址
        // 【因为以“”方式给出的字符串对象,在字符串常量池中存储,而且相同内容只会在其中存储一份】 所以这里返回 true

        char[] chars1 = {'a' , 'b' , 'c'};
        String ss3 = new String(chars1);
        String ss4 = new String(chars1);
        System.out.println(ss3 == ss4);
        // 通过构造器new对象,每new一次都会产生一个新对象,放在堆内存中
        // 每次 new一下在堆内存中产生不同的对象,所以这里返回 false
    }
}

20:Java存在编译优化机制,程序在编译时: “a” + “b” + “c” 会直接转成 "abc"

package com.itheima.string;

public class StringDemo3 {
    public static void main(String[] args) {
        String s1 = "abc";
        String s2 = "a" + "b" + "c";
        System.out.println(s1 == s2);
        System.out.println("----------------------");
        ms1();
        System.out.println("----------------------");
        ms2();
        System.out.println("----------------------");
        ms3();
    }

    public static void ms1() {
        String s2 = new String("abc");      // 字符串常量池 存储 "abc" + 堆内存中new 存储一个 "abc",s2指向堆内存的 "abc"
        String s1 = "abc";          // 发生 字符串常量池中有  "abc"  那么 这里s1直接指向常量池中的 "abc",不创建了
        System.out.println(s1 == s2);   // s1 和s2 指向不同
        //
    }

    public static void ms2() {
        String s1 = "abc";      // 字符串常量池 存储 "abc",s1指向常量池的 "abc"
        String s2 = "ab";       // 字符串常量池 存储 "ab"
        String s3 = s2 + "c";   // 计算出来的等同 new创建,堆内存中再存储一个  "abc",s3是运算出来的,s3指向堆内存中的 "abc"
        System.out.println(s1 == s3);       // false
        // 这里没有 编译优化机制,因为需要代码跑起来才知道 s2等于啥,跑起来才知道 s2指向"ab"的
        // 变量和字面量的区别
    }

    public static void ms3() {
        String s1 = "abc";
        String s2 = "a" + "b" + "c";
        System.out.println(s1 == s2);   // true
        // Java存在编译优化机制,程序在编译时: “a” + “b” + “c” 会直接转成 "abc"
        // 编译把代码先 翻译成 class文件,翻译成class文件的时候 s2已经等于  "abc" 了
        // java代码运行的时候 s1 和s2 都指向 常量池的 "abc",返回 true
        // 假设不这样优化,需要常量池产生 3个对象 "a"  "b"  "c",然后new运算在堆内存中再生成一个 "abc"   ——>浪费性能和内存【不存储那么多数据,少+ 和new两步运算】
    }
}

21:集合的概念  ArryList

package com.itheima.arraylist;

import java.util.ArrayList;

/**
目标: 创建ArrayList对象,代表集合容器,往里面添加元素。

引用类型变量 list 存储的是集合对象的地址
    打印的时候会去获取 集合地址里存储的内容【改进】

 add 方法 会有一个布尔类型的返回值,添加成功返回真,添加失败返回假,ArrayList集合一般不会添加元素失败
 */
public class ArrayListDemo1 {
    public static void main(String[] args) {
        ArrayList list = new ArrayList();       // 1、创建ArrayList集合的对象【调用 ArrayList 的无参构造器】

        // 2、添加数据
        list.add("Java");
        list.add("Java");
        list.add("MySQL");
        list.add("黑马");
        list.add(23);
        list.add(23.5);
        list.add(false);
        System.out.println(list.add('中'));
        System.out.println(list);

        // 3、给指定索引位置插入元素,插入后 后面的元素自动往后移动一位
        list.add(1, "赵敏");
        System.out.println(list);
    }
}

22:ArryList集合——泛型概念【ArryList<E>】

package com.itheima.arraylist;

import java.util.ArrayList;

/**
目标: 能够使用泛型约束ArrayList集合操作的数据类型
 ArrayList 容器默认能够存储任意类型的元素,实际开发不建议这样做,因为java是强类型的语言
    最好需要能够确定数据的类型,比如存分数
泛型概述
    ArrayList<E>:其实就是一个泛型类,可以在编译阶段约束集合对象只能操作某种数据类型
    ArrayList<String> :此集合只能操作字符串类型的元素。
    ArrayList<Integer>:此集合只能操作整数类型的元素。
    泛型只能支持引用数据类型,不支持基本数据类型,里面存储的都是一个对象,整数的引用类型 Integer
 泛型定义集合就是一直规范和标准
     ArrayList list = new ArrayList();      默认是就可以存储任意类型的集合     但是一般不这样写
     ArrayList<object> list = new ArrayList<object>();      这样使用Object泛型来定义,标准化,这样也可以存储任意数据类型--标准
    定义集合都要采用泛型
 */
public class ArrayListDemo2 {
    public static void main(String[] args) {
        // ArrayList<String> list = new ArrayList<String>();
        ArrayList<String> list = new ArrayList<>(); // JDK 1.7开始,泛型后面的类型申明可以不写
        list.add("Java");
        list.add("MySQL");
//        list.add(23);
//        list.add(23.5);

        ArrayList<Integer> list2 = new ArrayList<>();
        list2.add(23);
        list2.add(100);
        // list2.add("Java");
    }
}

23:ArryList集合——>之遍历,遍历并删除元素,存储自定义类型,元素搜索

package com.itheima.arraylist;

import java.util.ArrayList;

/**
目标:掌握ArrayList集合的常用API
 */
public class ArrayListDemo3 {
    public static void main(String[] args) {
        ArrayList<String> list = new ArrayList<>();
        list.add("Java");
        list.add("Java");
        list.add("MySQL");
        list.add("MyBatis");
        list.add("HTML");

        // 1、public E get(int index):获取某个索引位置处的元素值
        String e = list.get(3);
        System.out.println(e);

        // 2、public int size():获取集合的大小(元素个数)
        System.out.println(list.size());

        // 3、完成集合的遍历
        for (int i = 0; i < list.size(); i++) {
            System.out.println(list.get(i));
        }

        // 4、public E remove(int index):删除某个索引位置处的元素值,并返回被删除的元素值
        System.out.println(list); // [Java, Java, MySQL, MyBatis, HTML]
        String e2 = list.remove(2);     // 删除某个索引位置处的元素值,并返回被删除的元素值
        System.out.println(e2);
        System.out.println(list);

        // 5、public boolean remove(Object o):直接删除元素值,删除成功返回true,删除失败返回false
        System.out.println(list.remove("MyBatis"));     // 删除的值 集合里有多个,只会默认删除前面的 第一个数据
        System.out.println(list);

        ArrayList<String> list1 = new ArrayList<>();
        list1.add("Java");
        list1.add("王宝强");
        list1.add("Java");
        list1.add("MySQL");
        System.out.println(list1);
        // 只会删除第一次出现的这个元素值,后面的不删除
        System.out.println(list1.remove("Java"));
        System.out.println(list1);


        // 6、public E set(int index,E element):修改某个索引位置处的元素值。
        String e3 = list1.set(0 , "贾乃亮");       // 返回修改前的值
        System.out.println(e3);
        System.out.println(list1);
    }
}

24:ArryList集合里存储的数据内存分析

25:ArryList集合简单案例

package com.itheima.arraylist;

import java.util.ArrayList;

/**
案例:从集合中遍历元素且删除。

 ArrayList<Integer> scores = new ArrayList<>();     存储整数引用类型
 ArrayList<Double> scores = new ArrayList<>();      存储 小数引用类型

边遍历 边删除 操作需要各位注意
 */
public class ArrayListTest4 {
    public static void main(String[] args) {
        // 1、创建集合对象:存入学生成绩(98,77,66,89,79,50,100)
        ArrayList<Integer> scores = new ArrayList<>();
        scores.add(98);
        scores.add(77);
        scores.add(66);
        scores.add(89);
        scores.add(79);
        scores.add(50);
        scores.add(100);
        System.out.println(scores);
        // [98, 77, 66, 89, 79, 50, 100]
        // [98, 66, 89, 50, 100]
        //                   i

        // 1、遍历集合中的每个元素
//        for (int i = 0; i < scores.size(); i++) {
//            int score = scores.get(i);
//            // 2、判断这个分数是否低于80分,如果低于则从集合中删除它
//            if(score < 80){
//                scores.remove(i);
//            }
//        }
//        System.out.println(scores);
// 这样写 有 bug,无法删除 80分的数据
// i=0 一开始在98 的位置 不低于80,不删除
// i=1 在77的位置,77小于80把77删除,77删除了66往前移动了到 i=1的位置了
// i=2 到了89的位置了,不删除
// for循环执行的时候会一直调用()里的代码,scores.size()一直获取 scores的长度,因为要一直判断条件是否还满足
// 删除元素之后后面的元素往前移动导致跳位了

        // [98, 77, 66, 89, 79, 50, 100]
        // [98,  89, 100]
        //   i
// 解决方案一:每删除成功一个数据,i往后退一步,保证下次回到位置,这样不会跳过数据
// 解决方案二:从后面倒着遍历删除就可以       i在100最后面的位置,起始索引集合大小-1,i往前走最终走到0这个位置所以 i >= 0 ,小于0就走完了
        // 从后往前走需要 i--
        // 倒着删除,删除一个数据后经过扫描的数据往前提,所有的前面的数据都能扫描到,不会跳数据
        for (int i = scores.size() - 1; i >= 0 ; i--) {
            int score = scores.get(i);      // 提取数据
            // 2、判断这个分数是否低于80分,如果低于则从集合中删除它
            if(score < 80){
                scores.remove(i);
            }
        }
        System.out.println(scores);
    }
}
package com.itheima.arraylist;

import java.util.ArrayList;

/**
案例:集合存储自定义元素并遍历。
    需求:定义电影类(名称,分值,演员),创建3个电影对象,代表三部影片,存入集合中并遍历。
    《肖生克的救赎》, 9.7 , 罗宾斯
    《霸王别姬》, 9.6 , 张国荣、张丰毅
    《阿甘正传》, 9.5 , 汤姆.汉克斯
 */
public class ArrayListTest5{
    public static void main(String[] args) {
        // 1、定义一个电影类:Movie

        ArrayList<Movie> movies = new ArrayList<>();         // 2、定义一个ArrayList集合存储这些影片对象。

        // 3、创建影片对象封装电影数据,把对象加入到集合中去。
//        Movie m1 = new Movie("《肖生克的救赎》", 9.7 , "罗宾斯");
//        movies.add(m1);
        movies.add(new Movie("《肖生克的救赎》", 9.7 , "罗宾斯"));
        movies.add(new Movie("《霸王别姬》", 9.6 , "张国荣、张丰毅"));
        movies.add(new Movie("《阿甘正传》", 9.5 , "汤姆.汉克斯"));

        System.out.println(movies);  // 打印:[com.itheima.arraylist.Movie@776ec8df, com.itheima.arraylist.Movie@4eec7777, com.itheima.arraylist.Movie@3b07d329]
        // 打印集合里的内容,因为这里的Movie类没特殊处理,打印的还是集合里存储的对象的地址,Movie不像String做了特殊处理,集合里存储的就是对象的地址

        // 4、遍历集合中的影片对象并展示出来
        for (int i = 0; i < movies.size(); i++) {
            Movie movie = movies.get(i);     // movies.get(i)取值的是 影片对象的地址
            System.out.println("片名:" + movie.getName());
            System.out.println("评分:" + movie.getScore());
            System.out.println("主演:" + movie.getActor());
        }
    }
}
package com.itheima.arraylist;

import java.util.ArrayList;
import java.util.Scanner;

/**
案例:学生信息系统:展示数据,并按照学号完成搜索
     学生类信息(学号,姓名,性别,班级)
     测试数据:
     "20180302","叶孤城",23,"护理一班"
     "20180303","东方不败",23,"推拿二班"
     "20180304","西门吹雪",26,"中药学四班"
     "20180305","梅超风",26,"神经科2班"
 */
public class ArrayListTest6 {
    public static void main(String[] args) {
        // 1、定义一个学生类,后期用于创建对象封装学生数据

        // 2、定义一个集合对象用于装学生对象
        ArrayList<Student> students = new ArrayList<>();
        students.add(new Student("20180302","叶孤城",23,"护理一班"));
        students.add(new Student("20180303","东方不败",23,"推拿二班"));
        students.add(new Student( "20180304","西门吹雪",26,"中药学四班"));
        students.add(new Student( "20180305","梅超风",26,"神经科2班"));
        System.out.println("学号\t\t名称\t\t年龄\t\t班级");

        // 3、遍历集合中的每个学生对象并展示其数据
        for (int i = 0; i < students.size(); i++) {
            Student s = students.get(i);
            System.out.println(s.getStudyId() +"\t\t" + s.getName()+"\t\t"
                    + s.getAge() +"\t\t" + s.getClassName());
        }

        // 4、让用户不断的输入学号,可以搜索出该学生对象信息并展示出来(独立成方法)
        Scanner sc = new Scanner(System.in);
        while (true) {
            System.out.println("请您输入要查询的学生的学号:");
            String id = sc.next();
            Student s = getStudentByStudyId(students, id);
            // 判断学号是否存在
            if(s == null){
                System.out.println("查无此人!");
            }else {
                // 找到了该学生对象了,信息如下
                System.out.println(s.getStudyId() +"\t\t" + s.getName()+"\t\t"
                        + s.getAge() +"\t\t" + s.getClassName());
            }
        }
    }

    /**
      根据学号,去集合中找出学生对象并返回。
     * @param students
     * @param studyId
     * @return
     */
    public static Student getStudentByStudyId(ArrayList<Student> students, String studyId){
        // 返回学生对象
        for (int i = 0; i < students.size(); i++) {     // 遍历集合中的学生对象
            Student s = students.get(i);
            if(s.getStudyId().equals(studyId)){     // 判断学生id是不是等于传入的id,找到了返回s学生对象
                return s;
            }
        }
        return null; // 查无此学号!可能循环找完了都没有匹配到学生对象,返回null
    }
}
package com.itheima.arraylist;

public class Movie {
    private String name;        // 电影名字
    private double score;       // 电影评分
    private String actor;       // 电影主演

    public Movie() {        // 无参构造器
    }

    public Movie(String name, double score, String actor) {     // 有参构造器
        this.name = name;
        this.score = score;
        this.actor = actor;
    }

    public String getName() {
        return name;
    }

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

    public double getScore() {
        return score;
    }

    public void setScore(double score) {
        this.score = score;
    }

    public String getActor() {
        return actor;
    }

    public void setActor(String actor) {
        this.actor = actor;
    }
}
package com.itheima.arraylist;

public class Student {
    private String studyId;
    private String name;
    private int age;
    private String className;

    public Student() {
    }

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

    public String getStudyId() {
        return studyId;
    }

    public void setStudyId(String studyId) {
        this.studyId = studyId;
    }

    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 getClassName() {
        return className;
    }

    public void setClassName(String className) {
        this.className = className;
    }
}

26:第一阶段综合案例 ——>ATM取款系统

package com.itheima;

/**
   账户类:创建账户信息
 */
public class Account {
    /**
       成员变量,私有
     */
    private String cardId;      // 卡号
    private String userName; // 用户名
    private String passWord; // 密码
    private double money; // 账户余额
    private double quotaMoney; // 每次取现额度

    // 默认有无参构造器,这里不写了

    public String getCardId() {
        return cardId;
    }

    public void setCardId(String cardId) {
        this.cardId = cardId;
    }

    public String getUserName() {
        return userName;
    }

    public void setUserName(String userName) {
        this.userName = userName;
    }

    public String getPassWord() {
        return passWord;
    }

    public void setPassWord(String passWord) {
        this.passWord = passWord;
    }

    public double getMoney() {
        return money;
    }

    public void setMoney(double money) {
        this.money = money;
    }

    public double getQuotaMoney() {
        return quotaMoney;
    }

    public void setQuotaMoney(double quotaMoney) {
        this.quotaMoney = quotaMoney;
    }
}
package com.itheima;

import java.util.ArrayList;
import java.util.Random;
import java.util.Scanner;

/**
ATM系统的入口类
private static void login:private修饰的方法表示只能本地访问
*/
public class ATMSystem {
    public static void main(String[] args) {
        // 1、定义账户类      Account

        // 2、定义一个集合容器,负责以后存储全部的账户对象,进行相关的业务操作。
        ArrayList<Account> accounts = new ArrayList<>();

        // 3、展示系统的首页
        Scanner sc = new Scanner(System.in);
        while (true) {
            System.out.println("===============ATM系统=================");
            System.out.println("1、账户登录");
            System.out.println("2、账户开户");

            System.out.println("请您选择操作:");
            int command = sc.nextInt();     // 接受整型,switch分支
            switch (command){
                case 1:
                    login(accounts, sc);        // 用户登录操作
                    break;
                case 2:
                    register(accounts,sc);      // 用户账户开户(ALT + ENTER快捷生成方法)
                    break;
                default:
                    System.out.println("您输入的操作命令不存在~~");
            }
        }
    }

    /**
     * 登录功能
     * @param accounts 全部账户对象的集合
     * @param sc 扫描器
     */
    private static void login(ArrayList<Account> accounts, Scanner sc) {
        System.out.println("===================系统登录操作========================");
        // 1、判断账户集合中是否存在账户,如果不存在账户,登录功能不能进行。
        if(accounts.size() == 0) {
            System.out.println("对不起,当前系统中,无任何账户,请先开户,再来登录~~");
            return; // 卫语言风格,结束方法的执行。
        }

        // 2、正式进入登录操作
        while (true) {
            System.out.println("请您输入登录卡号:");
            String cardId = sc.next();

            Account acc = getAccountByCardId(cardId, accounts); // 3、判断卡号是否存在:根据卡号去账户集合中查询账户对象
            if(acc != null){                // 卡号存在的
                while (true) {
                    System.out.println("请您输入登录密码:");
                    String passWord = sc.next();            // 4、让用户输入密码,认证密码
                    if(acc.getPassWord().equals(passWord)) {        // 判断当前账户对象的密码是否与用户输入的密码一致
                        // 登录成功了
                        System.out.println("恭喜您," + acc.getUserName() +"先生/女生进入系统,您的卡号是:" + acc.getCardId());
                        // .... 查询 转账 取款 ....

                        showUserCommand(sc, acc, accounts);      // 展示登录后的操作页。
                        return; // 干掉登录方法

                    }else {     // 密码有问题,再次输入继续认证
                        System.out.println("对不起,您输入的密码有误~~");
                    }
                }
            }else {     // 卡号不存在
                System.out.println("对不起,系统中不存在该账户卡号~~");
            }
        }

    }

    /**
      展示登录后的操作页
     */
    private static void showUserCommand(Scanner sc, Account acc, ArrayList<Account> accounts) {
        while (true) {
            System.out.println("===============用户操作页===================");
            System.out.println("1、查询账户");
            System.out.println("2、存款");
            System.out.println("3、取款");
            System.out.println("4、转账");
            System.out.println("5、修改密码");
            System.out.println("6、退出");
            System.out.println("7、注销账户");
            System.out.println("请选择:");
            int command = sc.nextInt();
            switch (command) {
                case 1:
                    showAccount(acc);       // 查询账户(展示当前登录的账户信息)
                    break;
                case 2:
                    depositMoney(acc, sc);      // 存款
                    break;
                case 3:
                    drawMoney(acc, sc);      // 取款
                    break;
                case 4:
                    transferMoney(sc, acc, accounts);       // 转账
                    break;
                case 5:
                    updatePassWord(sc, acc);         // 修改密码
                    return; // 让当前方法停止执行,跳出去
                case 6:
                    System.out.println("退出成功,欢迎下次光临");      // 退出
                    return; // 让当前方法停止执行,跳出去        干掉当前方法的执行,
                case 7:
                    if(deleteAccount(acc,sc,accounts)){     // 注销账户
                        // 销户成功了,回到首页
                        return; // 让当前方法停止执行,跳出去
                    }else {
                        // 没有销户成功, 还是在操作页玩
                        break;
                    }
                default:
                    System.out.println("您输入的操作命令不正确~~");
            }
        }
    }

    /**
     * 销户功能
     * @param acc
     * @param sc
     * @param accounts
     */
    private static boolean deleteAccount(Account acc, Scanner sc, ArrayList<Account> accounts) {
        System.out.println("===================用户销户========================");
        System.out.println("您真的要销户?y/n");
        String rs = sc.next();
        switch (rs) {
            case "y":
                // 真正的销户
                // 从当前账户集合中,删除当前账户对象,销毁就完成了。
                if(acc.getMoney() > 0){
                    System.out.println("您账户中还有钱没有取完,不允许销户~");
                }else {
                    accounts.remove(acc);
                    System.out.println("您的账户销户完成~~");
                    return true; // 销户成功
                }
                break;
            default:
                System.out.println("好的,当前账户继续保留~");
        }
        return false;
    }

    /**
     * 修改密码
     * @param sc 扫描器
     * @param acc 当前登录成功的账户对象。
     */
    private static void updatePassWord(Scanner sc, Account acc) {
        System.out.println("===================用户密码修改========================");
        while (true) {
            System.out.println("请您输入当前密码:");
            String passWord = sc.next();
            if(acc.getPassWord().equals(passWord)){     // 1、判断这个密码是否正确
                while (true) {      // 密码正确
                    // 2、输入新密码。
                    System.out.println("请您输入新密码:");
                    String newPassWord = sc.next();

                    System.out.println("请您确认新密码:");
                    String okPassWord = sc.next();

                    if(newPassWord.equals(okPassWord)) {
                        // 2次密码一致,可以修改了
                        acc.setPassWord(newPassWord);
                        System.out.println("恭喜您,您密码修改成功了~~");
                        return;
                    }else {
                        System.out.println("您输入的2次密码不一致~~");
                    }
                }
            }else {
                System.out.println("您输入的密码不正确~");
            }
        }
    }

    /**
     * 转账功能
     * @param sc 扫描器
     * @param acc  自己的账户对象
     * @param accounts 全部账户的集合。
     */
    private static void transferMoney(Scanner sc, Account acc, ArrayList<Account> accounts) {
        System.out.println("===================用户转账操作========================");
        if(accounts.size() < 2){        // 1、判断是否足够2个账户
            System.out.println("当前系统中,不足2个账户,不能进行转账,请去开户吧~~");
            return; // 不能转账那么 return 结束当前方法
        }

        if(acc.getMoney() == 0) {       // 2、判断自己的账户是否有钱
            System.out.println("对不起,您自己都都没钱,就别转了吧~~");
            return; // 没有前那么 结束当前转账方法
        }

        while (true) {      // 有两个账户并且 账号有钱,真正转账逻辑
            // 3、真正开始转账
            System.out.println("请您输入对方账户的卡号:");
            String cardId = sc.next();

            if(cardId.equals(acc.getCardId())){     // 这个卡号不能是自己的卡号
                System.out.println("对不起,您不可以给自己进行转账~~");
                continue; // 结束当次执行,死循环进入下一次
            }

            Account account = getAccountByCardId(cardId, accounts);     // 判断这个卡号是存在的:根据这个卡号去查询对方账户对象。
            if(account == null){        // 卡号不存在
                System.out.println("对不起,您输入对方的这个账号不存在~~");
            }else {     // 这个账户对象存在了:继续认证他的姓氏
                String userName = account.getUserName(); // 黑马周芷若       获取的全名
                String tip = "*" + userName.substring(1);   // userName.substring(1); 从 第1 个位置开始截
                System.out.println("请您输入["+ tip +"]的姓氏");
                String preName = sc.next();     //  接受姓氏

                if(userName.startsWith(preName)) {      // 认证姓氏是否输入正确。
                    while (true) {      // 认证通过,真正开始转账了
                        System.out.println("请您输入转账金额:");
                        double money = sc.nextDouble();
                        if(money > acc.getMoney()) {        // 判断余额是否足够
                            System.out.println("对不起,您余额不足,您最多可以转账:" + acc.getMoney());
                        }else {     // 余额足够,可以转了
                            acc.setMoney(acc.getMoney() - money);
                            account.setMoney(account.getMoney() + money);
                            System.out.println("转账成功!您的账户还剩余:" + acc.getMoney());
                            return; // 直接干掉转账方法
                        }
                    }
                }else {      // 认证姓氏 错误
                    System.out.println("对不起,您输入的信息有误~~");
                }
            }
        }
    }

    /**
     * 取钱功能
     * @param acc 当前账户对象
     * @param sc  扫描器
     */
    private static void drawMoney(Account acc, Scanner sc) {
        System.out.println("===================用户取钱操作========================");
        if(acc.getMoney() < 100) {      // 1、判断是否足够100元
            System.out.println("对不起,当前账户中不够100元,不能取钱~");
            return;
        }

        while (true) {
            System.out.println("请您输入取款金额:");            // 2、提示用户输入取钱金额
            double money = sc.nextDouble();

            if(money > acc.getQuotaMoney()) {           // 3、判断这个金额是否满足要求。
                System.out.println("对不起,您当前取款金额超过每次限额,每次最多可取:" + acc.getQuotaMoney());
            }else {     // 没有超过当次限额。
                if(money > acc.getMoney()){     // 4、判断是否超过了账户的总余额。
                    System.out.println("余额不足,您账户目前总余额是:" + acc.getMoney());
                }else {     // 可以取钱了。
                    System.out.println("恭喜您,取钱" + money +"元,成功!");
                    acc.setMoney(acc.getMoney() - money);       // 更新余额
                    showAccount(acc);            // 取钱结束了。
                    return; // 取钱取完了,那么干掉取钱方法
                }
            }
        }

    }

    /**
     * 存钱
     * @param acc 当前账户对象
     * @param sc  扫描器
     */
    private static void depositMoney(Account acc, Scanner sc) {
        System.out.println("===================用户存钱操作========================");
        System.out.println("请您输入存款金额:");
        double money = sc.nextDouble();

        // 更新账户余额:原来的钱 + 新存入的钱
        acc.setMoney(acc.getMoney() + money);
        System.out.println("恭喜您,存钱成功,当前账户信息如下:");
        showAccount(acc);
    }

    /**
     * 展示账户信息
     * @param acc
     */
    private static void showAccount(Account acc) {
        System.out.println("===================当前账户信息如下========================");
        System.out.println("卡号:" + acc.getCardId());
        System.out.println("户主:" + acc.getUserName());
        System.out.println("余额:" + acc.getMoney());
        System.out.println("限额:" + acc.getQuotaMoney());
    }

    /**
     * 用户开户功能的实现            这是一个标准注释
     * @param accounts 接收的账户集合。
     */
    private static void register(ArrayList<Account> accounts, Scanner sc) {
        System.out.println("===================系统开户操作========================");

        Account account = new Account();        // 1、创建一个账户对象,用于后期封装账户信息

        System.out.println("请您输入账户用户名:");       // 2、录入当前这个账户的信息,注入到账户对象中去
        String userName = sc.next();            // 接受用户名并且属性放到类里
        account.setUserName(userName);

        while (true) {
            System.out.println("请您输入账户密码:");
            String passWord = sc.next();
            System.out.println("请您输入确认密码:");
            String okPassWord = sc.next();
            if(okPassWord.equals(passWord)){        // 密码认证通过,可以注入给账户对象
                account.setPassWord(okPassWord);
                break; // 密码已经录入成功了,死循环没有必要继续了!
            }else {
                System.out.println("对不起,您输入的2次密码不一致,请重新确认~~");
            }
        }

        System.out.println("请您输入账户当次限额:");
        double quotaMoney = sc.nextDouble();        // 限额
        account.setQuotaMoney(quotaMoney);

        // 为账户随机一个8位且与其他账户的卡号不重复的号码。(独立功能,独立成方法)。
        String cardId = getRandomCardId(accounts);
        account.setCardId(cardId);

        accounts.add(account);           // 3、把账户对象添加到账户集合中去
        System.out.println("恭喜您," + userName + "先生/女生,您开户成功,您的卡号是:" + cardId + ",请您妥善保管卡号" );
    }

    /**
     *  为账户生成8位与其他账户卡号不同的号码。
     * @return
     */
    private static String getRandomCardId(ArrayList<Account> accounts) {
        Random r = new Random();
        while (true) {
            // 1、先生成8位数字
            String cardId = ""; // 03442522
            for (int i = 0; i < 8; i++) {       // 8位
                cardId += r.nextInt(10);    // 生成0-9的数字
            }

            // 2、判断这个8位的卡号是否与其他账户的卡号重复了
            Account acc = getAccountByCardId(cardId, accounts);     // 根据这个卡号去查询账户的对象
            if(acc == null){
                // 说明cardId 此时没有重复,这个卡号是一个新卡号了,可以使用这个卡号作为新注册账户的卡号了
                return cardId;
            }
        }
    }

    /**
     * 根据卡号查询出一个账户对象出来
     * @param cardId  卡号
     * @param accounts 全部账户的集合
     * @return  账户对象 | null
     */
    private static Account getAccountByCardId(String cardId,ArrayList<Account> accounts){
        for (int i = 0; i < accounts.size(); i++) {     // 遍历每个账户
            Account acc = accounts.get(i);      // 集合根据索引取当前对象的地址
            if(acc.getCardId().equals(cardId)){     // 卡号存在,返回acc账户对象
                return acc;
            }
        }
        return null; // 查无此账户,返回 null
    }
}

 

 

 

 

 

 

 

 

 

posted @ 2023-04-24 23:59  至高无上10086  阅读(16)  评论(0编辑  收藏  举报