java学习笔记part2


面向对象oop

设计对象并使用

  • 类:对象共同特征的描述
  • 对象:真实存在的具体实例

对象在内存中的运行机制

  • 方法区:字节码文件加载时进入的内存
  • 栈内存:方法运行时,进入的内存,变量也在这里,变量中存储 对象在堆内存的地址
  • 堆内存:new出来的对象,在这块内存中开辟空间并产生地址,放置成员变量,在对象中放置成员方法的引用地址
  • 堆内存中的对象,没有任何变量应用时,就会判定为内存中的垃圾

面向对象练习

模拟购物车

package oop;


import java.util.Scanner;

public class ShowCarTest{
    public static void main(String[] args) {
        //定义商品类,用于创建商品对象
        //定义购物车对象,使用数组对象表示
        Goods[] shopCar = new Goods[100];//商品类型的数组
        //搭建操作架构
        while (true) {
            System.out.println("选择下面命令操作");
            System.out.println("添加商品到购物车 add");
            System.out.println("查询购物车商品 query");
            System.out.println("修改商品购买数量  update");
            System.out.println("结算商品 pay");
            Scanner sc = new Scanner(System.in);
            System.out.println("输入命令");

            String command = sc.next();
            switch (command){
                case "add":
                    //添加商品到购物车
                    addGoods(shopCar, sc);
                    break;
                case "query":
                    //查询购物车商品
                    queryGoods(shopCar);
                    break;
                case "update":
                    //修改商品购买数量
                    updateGoods(shopCar, sc);
                    break;
                case "pay":
                    //结算商品
                    payGoods(shopCar);
                    break;
                default:
                    System.out.println("没有该功能");
            }
        }
    }

    public static void payGoods(Goods[] shopCar) {
        queryGoods(shopCar);
        //定义求和遍历,累加金额
        double money = 0;
        //遍历购物车数组中全部商品对象,单价*数量
        for (int i = 0; i < shopCar.length; i++) {
            Goods g =shopCar[i];
            if(g != null){
                money += (g.price * g.buyNumber);
            }else {
                break;
            }
        }
        System.out.println("订单金额" + money);
    }

    //修改购买数量
    public static void updateGoods(Goods[] shopCar, Scanner sc) {
        //让用户输入要修改商品的id,id查询要修改的对象
        while (true) {
            System.out.println("输入要修改的商品id");
            int id = sc.nextInt();
            Goods g = getGoodsById(shopCar, id);
            if(g == null){
                //没有商品
                System.out.println("没有该商品");
            }else {
                //存在该商品
                System.out.println("输入"+g.name+"购买数量");
                g.buyNumber = sc.nextInt();
                System.out.println("修改完成");
                queryGoods(shopCar);
                break;
            }
        }
    }

    //    根据id查询要修改的对象
    public static Goods getGoodsById(Goods[] shopCar, int id){
        for (int i = 0; i < shopCar.length; i++) {
            Goods g = shopCar[i];
            if(g != null){
                //判断商品id是不是要找的
                if(g.id == id){
                    return g;
                }
            }else {
                return null;//找完前面存在的都没找到
            }
        }
        //所有位置都不是null,都有数据,不匹配
        return null;
    }


    //查询购物车中商品信息
    public static void queryGoods(Goods[] shopCar) {
        System.out.println("--------购物车信息如下--------");
        System.out.println("编号\t\t名称\t\t价格\t\t购买数量");
        for (int i = 0; i < shopCar.length; i++) {
            Goods g = shopCar[i];
            if(g != null){
                //展示这个对象
                System.out.println(g.id+"\t\t"+g.name+"\t\t"+g.price+"\t\t"+g.buyNumber);
            }else {
                //遍历结束
                break;
            }
        }
    }

    //商品添加到购物车
    public static void addGoods(Goods[] shopCar, Scanner sc) {

        //1.录入用户输入的购买商品的信息
        System.out.println("输入购买商品的编号");
        int id = sc.nextInt();
        System.out.println("输入购买商品的名称");
        String name = sc.next();
        System.out.println("输入购买商品的数量");
        int buyNumber = sc.nextInt();
        System.out.println("商品价格");
        double price = sc.nextDouble();

        //把购买商品的信息,封装成商品对象
        Goods g = new Goods();
        g.id = id;
        g.name = name;
        g.buyNumber = buyNumber;
        g.price = price;

        //商品对象添加到购物车数组中
        for (int i = 0; i < shopCar.length; i++) {
            if(shopCar[i] == null){
                //这个位置没有元素
                shopCar[i] = g;
                break;//商品成功存进去,退出
            }
        }
        System.out.println(g.name + "\t添加到购物车");
    }
}

构造器

  • 定义在类中,可以用于初始化一个类的对象,并返回对象地址
  • 无参数构造器:默认存在的,初始化对象时,成员变量的数据采用默认值
  • 有参数构造器:在初始化对象时,同时可以接收参数为对象进行赋值
  • 调用构造器得到对象的格式Car c = new Car()
public  class Car{
	public Car(){
	//无参构造器
	}
	public Car(String n){
	//有参构造器
	}
}
//测试类
package constructor;

import org.w3c.dom.ls.LSOutput;

public class Test {
    public static void main(String[] args) {
        //调用无参数构造器,得到对象
        Car c = new Car();
        c.namr = "bmw";
        c.price = 33.33;
        System.out.println(c.price);
        System.out.println(c.namr);


        //调用有参数构造器
        Car c2 = new Car("bbb", 55.55);
        System.out.println(c2.namr);
        System.out.println(c2.price);

    }
}

//Car类
package constructor;

public class Car {
    String namr;
    double price;


//    无参数构造器
    public Car(){
        System.out.println("调用无参数构造器");
    }

//    有参数构造器
    public Car(String n, double p){
        System.out.println("调用有参数构造器");
        namr = n;
        price = p;
    }
}

注意事项:

  1. 任何类定义出来,默认自带无参数构造器,
  2. 一旦定义了有参数构造器,那无参数构造器就没有了,如果还想用无参数构造器,就需要自己写一个无参数构造器

this 关键字

  • this可以出现在构造器,方法中
  • this代表当前对象的地址
  • 可以用于指定访问当前对象的成员变量,成员方法
//测试类
package thist;

public class Test {
    public static void main(String[] args) {
//        Car c = new Car();
//        c.run();
//        System.out.println(c);
        Car c = new Car("bmw", 55.55);
        System.out.println(c.name);
        System.out.println(c.price);

        c.gowith("bbb");
    }
}



//Car类
package thist;

public class Car {
    String name;
    double price;
//  定义无参数构造器
//    public Car(){
//        System.out.println("无参数构造器中的" + this);
//    }
//
//    public void run(){
//        System.out.println("方法中的" + this);
//    }

    public Car(String name, double price){
        this.name =name;
        this.price = price;
        //指定访问当前对象的成员变量
    }
    public void gowith(String name){
        System.out.println(this.name + "和" + name + "一起比赛");
    }
}


封装

  • 面向对象的三大特征:封装,继承,多态

  • 封装:如何正确设计对象的属性和方法

  • 封装的原则:对象代表什么,就得封装对应的数据,并对数据提供对应的行为

  • private

标准javabean

  • 实体类,对象可以用于程序中封装数据

标注javabean书写要求

  • 成员变量使用private修饰
  • 提供成员变量get,set方法
  • 必须提供一个无参构造器,有参构造器可写可不写

面向对象案例

//测试类

package demo;

public class Test {
    public static void main(String[] args) {
//        1.设计电影类
//        2.创建三个电影对象,封装电影信息
//        3.定义电影类型的数组,存储电影对象
        Movie[] movies = new Movie[3];
        movies[0] = new Movie("长津湖", 8.7, "吴京");
        movies[1] = new Movie("我和我的父辈", 5.5, "吴京");
        movies[2] = new Movie("少年", 6.6, "王");
        
        
//        4.遍历数组中电影对象
        for (int i = 0; i < movies.length; i++) {
            Movie m = movies[i];
            System.out.println(m);//输出地址
            System.out.println(m.getName());
            System.out.println(m.getScore());
            System.out.println(m.getActor());
            System.out.println("-----------------------------");

        }
    }
}



package demo;

public class Movie {
    //1.成员变量
    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;
    }


    //2.get,set

    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;
    }
}

常用api

  • java写好的功能代码,可直接调用

String类

  • String类定义的变量可以用来存储字符串
  • 常被称为不可变字符串类型,对象创建后不能修改
  • String变量每次修改,都是产生并指向了新的字符串对象,原来的字符串对象没有改变

String创建对象的两种方式

  • “ ”方法给出的字符串,在字符串常量池中存储,相同内容只会在其中存储一份
  • 通过构造器new对象,每new一次都会产生新的对象,放在堆内存
package StringLei;

public class StringDemo {
    public static void main(String[] args) {
//        1.使用双引号,得到字符串对象
        String name = "rrr";
//        2.通过构造器创建对象
//        public String();创建一个空白字符串对象,不用
        String s1 = new String();
//        public String(String);根据传入的字符串内容,创建字符串对象,不用
        String s2 = new String("tttttt");
//        public String(char[] c);根据字符数组的内容,创建字符串对象
        char[] chars = {'2', '3', '4'};
        String s3 = new String(chars);
//        public String(byte[] b);根据字节数组的内容,创建字符串对象
        byte[] bytes = {1, 2, 3, 4, 5};
        String s4 = new String(bytes);

    }
}

String类常用api

  • 比较
package StringLei;

import java.util.Scanner;

public class StringEqualsDemo {
    public static void main(String[] args) {
        // 正确登录名和密码
        String okName = "heima";//指向常量池
        String okPasswd = "123456";

        //输入登录名和密码
        Scanner sc = new Scanner(System.in);
        System.out.println("用户名");
        String name = sc.next();
        System.out.println("密码");//堆内存
        String passwd = sc.next();


        //判断用户输入
       if(okName.equals(name) && okPasswd.equals(passwd)){//比较地址
            System.out.println("对了");
        }else {
            System.out.println("错误");
        }
       
    }
}
package StringLei;

import java.nio.charset.StandardCharsets;

public class StringDemo11 {
    public static void main(String[] args) {
        //获取字符串长度
        String name = "好家伙";
        System.out.println(name.length());

        //获取索引位置处的字符
        System.out.println(name.charAt(1));

        //遍历字符串中的每个字符
        for (int i = 0; i < name.length(); i++) {
            System.out.println(name.charAt(i));
        }

        //字符串转换成字符数组
        System.out.println(name.toCharArray());


        //截取字符串
        String name2 = "haojiahuo";
        System.out.println(name2.substring(0, 4));//包括前面,不包括后面


        //从当前索引截取到结尾
        System.out.println(name2.substring(1));

        //替换,后面的字符串替换前面的字符串
        String name3 = "niubi";
        System.out.println(name3.replace("bi", "bidal"));


        //判断是否包含,生成一个布尔值
        System.out.println(name3.contains("bi"));

        //判断开头
        System.out.println(name3.startsWith("niu"));


        //将字符串分割,返回
        String name4 = "niu, bi, da, l";
        String[] name5 = name4.split(",");
        for (int i = 0; i < name5.length; i++) {
            System.out.println(name5[i]);
        }
    }
}

案例

//验证码
package StringLei;

import java.util.Random;

public class StringDemo2 {
    public static void main(String[] args) {
        String data = "qwertyuioplkjhgfdsazxcvbnmQWERTYUIOPLKMNJHBGVFCDXSZA1234567890";

        //循环5次,每次生成一个随机索引,提取对应字符
        String code = "";
        Random r = new Random();
        for (int i = 0; i < 5; i++) {
            //随机一个索引
            int index = r.nextInt(data.length());
            char c =data.charAt(index);
            code += c;
        }
        System.out.println(code);
    }
}



//登录
package StringLei;

import java.util.Scanner;

public class StringDemo3 {
    public static void main(String[] args) {
        //1. 定义名称密码
        String okname = "root";
        String okpasswd = "root";

        //2. 定义循环三次
        Scanner sc = new Scanner(System.in);
        for (int i = 0; i < 3; i++) {
            System.out.println("输入名称");
            String name = sc.next();
            System.out.println("输入密码");
            String passwd = sc.next();

            //3. 判断登录成功
            if(okname.equals(name)){
                if(okpasswd.equals(passwd)) {
                    System.out.println("登录成功");
                    break;
                }else {
                    System.out.println("passwd错误");
                }
            }else {
                System.out.println("name错误");
            }
        }
    }
}


//屏蔽手机号
package StringLei;

import java.util.Scanner;

public class StringDemo5 {
    public static void main(String[] args) {
        // 输入号码
        Scanner sc = new Scanner(System.in);
        System.out.println("输入号码");
        String tel = sc.next();


        //截取号码,前三后四
        String before = tel.substring(0, 3);
        String after = tel.substring(7);


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

ArrayList集合

  • 支持索引的集合
package ArrayLIst1;

import java.util.ArrayList;

public class Demo1 {
    public static void main(String[] args) {
        // 1.创建arraylist对象
        ArrayList list = new ArrayList();

        //添加数据
        list.add("java");
        list.add("mysql");
        list.add(2);
        list.add(false);
        System.out.println(list);


        //指定索引插入元素
        list.add(1, 666);
        System.out.println(list);
    }
}

泛型

ArrayList:其实就是一个泛型类,可以在编译阶段约束集合对象只能操作某种数据类型

  • ArrayList:此集合只能操作字符串类型的元素

集合中只能存储引用类型,支持基本数据类型

package ArrayLIst1;

import java.util.ArrayList;

public class Demo2 {
    public static void main(String[] args) {
        ArrayList list = new ArrayList<>();//jdk1.7开始,泛型 后面的类型声明可以不写
        list.add("6666666");
//        list.add(6666666);//只有字符串加进去

        ArrayList list2 = new ArrayList<>();
        list2.add(33333);
        
    }
}

常用api,遍历

package ArrayLIst1;

import java.util.ArrayList;

public class Demo3 {
    public static void main(String[] args) {
        ArrayList list = new ArrayList<>();
        list.add("java");
        list.add("mysql");
        list.add("6666");

        //获取每个索引位置的元素值
        System.out.println(list.get(2));

        //获取集合元素的个数
        System.out.println(list.size());

        //集合元素遍历
        for (int i = 0; i < list.size(); i++) {
            System.out.println(list.get(i));
        }


        //根据索引删除元素值,返回被删除的元素值
        System.out.println(list);
        System.out.println(list.remove(1));
        System.out.println(list);


        //直接删除元素值,成功返回ture,失败返回false
        //删除集合的相同元素,会删除第一个
        System.out.println(list.remove("java"));
        System.out.println(list);



        //修改索引处的元素值,返回修改前的元素值
        System.out.println(list.set(0, "333333333"));
        System.out.println(list);

    }
}

ArrayList案例

  1. 99.77.66.89.79.50.100,去掉低于80的
package ArrayLIst1;

import java.util.ArrayList;

public class Demo4 {
    public static void main(String[] args) {
     //1. 创建ArrayList集合存储一个班级学生成绩
        ArrayList score = new ArrayList<>();
        score.add(98);
        score.add(77);
        score.add(66);
        score.add(89);
        score.add(79);
        score.add(100);
        score.add(50);
        System.out.println(score);


        //低于80的成绩在集合中去掉
        //方案1
/*        for (int i = 0; i < score.size(); i++) {
            int s = score.get(i);
            if(s < 80 ){
                //删除分数
                score.remove(i);
                i--;
            }
        }
        System.out.println(score);*/

        //方案2
        for (int i = score.size() - 1; i >= 0 ; i--) {
            int s = score.get(i);
            if(s < 80){
                score.remove(i);
            }
        }
        System.out.println(score);
    }
}

  1. 展示三个对象
//测试类
package ArrayLIst1;

import java.util.ArrayList;

public class Demo5 {
    public static void main(String[] args) {

    //定义电影类
    //创建电影对象'
    Movie m1 = new Movie("小", 6.6,"xiao");
    Movie m2 = new Movie("中", 6.7,"zhong");
    Movie m3 = new Movie("大", 6.8,"da");

    //创建电影类型的集合
    ArrayList movies = new ArrayList<>();

    movies.add(m1);
    movies.add(m2);
    movies.add(m3);

    //遍历电影类集合中的对象
        for (int i = 0; i < movies.size(); i++) {
            Movie m = movies.get(i);
            System.out.println("name" + m.getName());
            System.out.println("score" + m.getScore());
            System.out.println("actor" + m.getActor());
            System.out.println("--------------------------");
        }
    }
}





package ArrayLIst1;

public class Movie {
    private String name;
    private double score;
    private String actor;

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

    //get,set
    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;
    }
}


  1. 元素所搜
    存储学生信息并展示,提供安宁庄学号搜索的功能
//测试类
package ArrayLIst1;

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

public class Demo6 {

    public static void main(String[] args) {
    //构建学生类
    //创建集合,存储学生对象,封装学生信息
        ArrayList students = new ArrayList<>();
        students.add(new Students("2222", "hao", 23, "yiban"));
        students.add(new Students("3333", "jia", 24, "erban"));
        students.add(new Students("4444", "huo", 25, "sanban"));

    //遍历,展示
        for (int i = 0; i < students.size(); i++) {
            Students s = students.get(i);
            System.out.println(s.getNumber()+ "\t" + s.getName() + "\t" + s.getAge() + "\t" + s.getClassname());
        }

    //定义搜索方法,按学号
        Scanner sc =new Scanner(System.in);
        while (true){
            System.out.println("输入学号查询学生");
            String num = sc.next();

            //调用方法查询
            Students s = getStudentnyid(students, num);

            //判断s中是否存在,地址
            if(s == null){
                System.out.println("找不到");
            }else {
                System.out.println("找到了");
                System.out.println(s.getNumber()+ "\t" + s.getName() + "\t" + s.getAge() + "\t" + s.getClassname());
            }
        }
    }



    /**
     * 根据学生的学号吗,查询学生对象返回
     * @param arrayList 存储学生对象的集合
     * @param num 学号
     * @return 学生对象 | null
     */
    public static Students getStudentnyid(ArrayList arrayList, String num){
        //遍历学生对象
        for (int i = 0; i < arrayList.size(); i++) {
            Students s = arrayList.get(i);
            //对比当前学号,和要搜索的学号
            if(s.getNumber().equals(num)){
                //找到了
                return s;
            }
        }
        //找不到
        return null;
    }
}




//学生类
package ArrayLIst1;

public class Students {
    private String number;
    private String name;
    private int age;
    private String classname;



    //构造器
    public Students(String number, String name, int age, String classname) {
        this.number = number;
        this.name = name;
        this.age = age;
        this.classname = classname;
    }

    public Students() {
    }



    //set,get
    public String getNumber() {
        return number;
    }

    public void setNumber(String number) {
        this.number = number;
    }

    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;
    }
}

ATM系统

package ATM;

import javax.crypto.spec.PSource;
import java.util.ArrayList;
import java.util.Random;
import java.util.Scanner;

/**
 * 入口类
 */
public class ATMSystem {
    public static void main(String[] args) {
        //1.定义账户类
        //2. 定义集合容器,存储全部账户对象
        ArrayList accounts = new ArrayList<>();
        //3. 展示系统首页,
        while (true) {
            System.out.println("--------ATM系统---------");
            System.out.println("1, 登录");
            System.out.println("2, 注册");
            Scanner sc = new Scanner(System.in);
            System.out.println("选择操作");
            int command = sc.nextInt();

            switch (command) {
                case 1 ->
                    //登录
                        login(accounts, sc);
                case 2 ->
                    //注册
                        register(accounts, sc);
                default -> System.out.println("没这功能");
            }
        }
    }


    /**
     * 登录功能,
     * @param accounts 全部账户对象集合
     * @param sc 扫描器
     */
    private static void login(ArrayList accounts, Scanner sc) {
        System.out.println("----------------登录-----------------");
        //1。判断账户集合中是否存在账户,没有的话不能运行
        if(accounts.size() == 0){
            System.out.println("系统中无任何用户,先注册");
            return;//结束方法的执行
        }

        //进入登录操作
        while (true) {
            System.out.println("输入卡号");
            String cardId = sc.next();

            //判断卡号是否存在
            Account acc = getAccountByCardId(cardId, accounts);
            if(acc != null){
                //卡号存在
                //用户输入密码认证
                while (true) {
                    System.out.println("输入密码");
                    String passwd = sc.next();
                    //判断密码是否正确
                    if(acc.getPasswd().equals(passwd)){
                        //登录成功
                        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 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);
                case 2 ->
                    //存款
                        depositMoney(acc, sc);
                case 3 ->
                    //取款
                        drawMoney(acc, sc);
                case 4 ->
                    //转账
                        transferMoney(sc, acc, accounts);
                case 5 -> {
                    //修改密码
                    updatepasswd(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 accounts) {
        System.out.println("-----------用户销户-----------");
        System.out.println("真的销户吗 y/n");
        String s = sc.next();
        switch (s){
            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 updatepasswd(Scanner sc, Account acc) {
        System.out.println("-----------用户改密码-----------");
        while (true) {
            System.out.println("输入当前密码");
            String passwd = sc.next();

            //判断密码
            if(acc.getPasswd().equals(passwd)){
                //正确
                //输入密码
                while (true) {
                    System.out.println("输入新密码");
                    String newpasswd = sc.next();
                    System.out.println("再次输入密码");
                    String newpasswd2 = sc.next();

                    if(newpasswd.equals(newpasswd2)){
                        //两次输入一致,可以修改了
                        acc.setPasswd(newpasswd2);
                        System.out.println("修改成功");
                        return;
                    }else {
                        System.out.println("两次密码不一致");
                    }
                }
            }else {
                System.out.println("当前密码不正确");
            }
        }

    }

    /**
     * 转账
     * @param sc 扫描
     * @param acc 自己账户
     * @param accounts 全部账户集合
     */
    private static void transferMoney(Scanner sc, Account acc, ArrayList accounts) {
        System.out.println("-----------用户取钱-----------");
        // 1.分析系统是否足够两个账户
        if(accounts.size() < 2){
            System.out.println("不够两个账户,不能转账");
            return;
        }

        //判断自己账户是否有钱
        if(acc.getMoney() == 0){
            System.out.println("自己没钱");
            return;
        }

        //3.开始转账

        while (true) {
            System.out.println("输入对方卡号");
            String  cardId = sc.next();

            //卡号不能自己
            if(cardId.equals(acc.getCardid())){
                System.out.println("不能给自己转账");
                continue;//结束当此执行,进行下一次
            }

            //根据卡号查账户
            Account a = getAccountByCardId(cardId, accounts);
            if(a == null){
                System.out.println("输入账户不存在");
            }else {
                //账户存在,继续认证姓氏
                String userName = a.getUsername();
                String tip = '*' + userName.substring(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);
                            a.setMoney(a.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){
            System.out.println("钱不够100,不能取");
            return;
        }
        // 提示用户输入取钱金额
        while (true) {
            System.out.println("输入取款金额");
            double money = sc.nextDouble();
            //判断金额
            if(money > acc.getQuotaMoney()){
                System.out.println("不能取,每次最多可取" + acc.getQuotaMoney());
            }else {
                //没超过限额
                // 判断是否超过总余额
                if(money > acc.getMoney()){
                    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);

    }

    /**
     * 展示账户信息
     */
    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 accounts, Scanner sc) {
        System.out.println("------------注册功能---------------");
        //创建账户对象,用于后期封装账户信息
        Account account = new Account();

        //录入当前账户的信息,注入到账户中
        System.out.println("输入用户名");
        String usereanme = sc.next();
        account.setUsername(usereanme);

        while (true) {
            System.out.println("输入密码");
            String passwd = sc.next();
            System.out.println("输入密码");
            String okpasswd = sc.next();
            if(okpasswd.equals(passwd)){
                //密码一样
                account.setPasswd(passwd);
                break;//录入成功,退出循环
            }else {
                System.out.println("两次密码不一样");
            }
        }

        System.out.println("输入账户限额");
        double quotamoney = sc.nextDouble();
        account.setQuotaMoney(quotamoney);


        //随机一个,8位不重复的号码(独立成方法)
        String cardId = getRandomCardId(accounts);
        account.setCardid(cardId);


        //把账户对象添加到账户集合中
        accounts.add(account);
        System.out.println(usereanme + "注册成功" + cardId);


    }

    /**
     * 为账户生成8位,不重复的卡号
     *
     */
    private static String getRandomCardId(ArrayList accounts) {
        Random r = new Random();
        while (true) {
            //生成八位数字
            String cardId = "";
            for (int i = 0; i < 8; i++) {
                cardId += r.nextInt(10);
            }

            //判断卡号是否重复
            //根据卡号查询账户对象
            Account acc = getAccountByCardId(cardId, accounts);
            if(acc == null){
                //cardid,没有重复,可以使用
                return cardId;//return可以立即跳出寻循环,并停止当前方法
            }
        }
    }

    /**
     * 根据卡号查询账户
     * @param cardId 卡号
     * @param accounts 全部账户集合
     * @return 账户对象
     */
    private static Account getAccountByCardId(String cardId, ArrayList accounts){
        for (int i = 0; i < accounts.size(); i++) {
            Account acc = accounts.get(i);
            if(acc.getCardid().equals(cardId)){
                return acc;
            }
        }
        return null;
    }

}
package ATM;

/**
 * 账户类
 */
public class Account {
    private String cardid;//卡号
    private String username;//用户名
    private String passwd;//密码
    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 getPasswd() {
        return passwd;
    }

    public void setPasswd(String passwd) {
        this.passwd = passwd;
    }

    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;
    }
}