黑马程序员Java教程学习笔记(五)

学习视频:https://www.bilibili.com/video/BV1Cv411372m
如侵权,请私信联系本人删除


黑马程序员Java教程学习笔记(五)

日期时间:Date、SimpleDateFormat、Calendar

在这里插入图片描述

在这里插入图片描述

package com.mochu.d1_date;

import java.util.Date;

public class DateDemo1 {
    public static void main(String[] args) {
        Date d = new Date();
        System.out.println(d);
        // 获取毫秒级时间戳
        long t = d.getTime();
        System.out.println(t);
        System.out.println("-----------------");
        Date d1 = new Date();
        System.out.println(d1);
        // 当前时间往后走一小时121秒
        long time = System.currentTimeMillis();
        time += (60 * 60 + 121) * 100;
        // 把时间戳转换成日期
        Date d2 = new Date(time);
        System.out.println(d2);

        Date d3 = new Date();
        d3.setTime(time);
        System.out.println(d3);
    }
}

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

package com.mochu.d2_simpledateformat;

import java.text.SimpleDateFormat;
import java.util.Date;

public class Test {
    public static void main(String[] args) {
        Date d = new Date();
        System.out.println(d);
        // 格式化日期对象
        SimpleDateFormat sdf = new SimpleDateFormat("YYYY年MM月DD日 HH:mm:ss EEE a");
        String rs = sdf.format(d);
        System.out.println(rs);
        System.out.println("---------------------------");
        // 格式化时间戳
        long time = System.currentTimeMillis() + 121 * 1000;
        String rs2 = sdf.format(time);
        System.out.println(rs2);
        System.out.println("---------------------------");
        // 解析时间
    }
}

在这里插入图片描述

在这里插入图片描述

package com.mochu.d2_simpledateformat;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;

public class SimpleFormatDemo {
    public static void main(String[] args) throws ParseException {
        // 解析字符串时间为日期对象
        String date = "2021年08月06日 11:11:11";
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy年MM月dd日 HH:mm:ss");
        Date d = sdf.parse(date);
        long time = d.getTime() + (2L * 24 * 60 * 60 + 14 * 60 * 60 + 49 * 60 + 6) * 1000;
        System.out.println(sdf.format(time));
    }
}

在这里插入图片描述

在这里插入图片描述

package com.mochu.d2_simpledateformat;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;

public class SimpleDateFormatTest {
    public static void main(String[] args) throws ParseException {
        String startTime = "2021-11-11 00:00:00";
        String endTime = "2021-11-11 00:10:00";
        String xiaoJia = "2021-11-11 00:03:47";
        String xiaoPi = "2021-11-11 00:10:11";

        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        Date d1 = sdf.parse(startTime);
        Date d2 = sdf.parse(endTime);
        Date d3 = sdf.parse(xiaoJia);
        Date d4 = sdf.parse(xiaoPi);

        if(d3.after(d1) && d3.before(d2)) {
            System.out.println("小贾秒杀成功");
        }else {
            System.out.println("小贾秒杀失败");
        }
        if(d4.after(d1) && d4.before(d2)) {
            System.out.println("小皮秒杀成功");
        }else {
            System.out.println("小皮秒杀失败");
        }
    }
}

Caledar概述:

  • Calendar代表了系统此时日期对应的日历对象
  • Calendar是一个抽象类,不能直接创建对象

在这里插入图片描述

package com.mochu.d3_calendar;

import java.util.Calendar;
import java.util.Date;

public class Test {
    public static void main(String[] args) {
        Calendar cal = Calendar.getInstance();
        System.out.println(cal);
        // 获取其中某个字段的信息
        int year = cal.get(Calendar.YEAR);
        System.out.println(year);
        int month = cal.get(Calendar.MONTH) + 1;
        System.out.println(month);
        int day = cal.get(Calendar.DAY_OF_YEAR);
        System.out.println(day);

        // 修改其中的某个字段,一般不会修改
        // cal.set(Calendar.HOUR, 12);
        // System.out.println(cal);

        // 为某个字段增加/减少值
        cal.add(Calendar.DAY_OF_YEAR, 64);
        cal.add(Calendar.MINUTE, 59);

        // 拿到此日期的对象
        Date d = cal.getTime();
        System.out.println(d);

        // 拿到此刻时间的毫秒值(时间戳)
        long time = cal.getTimeInMillis();
        System.out.println(time);
    }
}

JDK8开始新增日期API

在这里插入图片描述
在这里插入图片描述

package com.mochu.d4_jdk8time;

import java.time.LocalDate;
import java.time.Month;

public class Demo01LocalDate {
    public static void main(String[] args) {
        // 获取本地日期对象
        LocalDate nowDate = LocalDate.now();
        System.out.println("今天的日期:" + nowDate);

        int year = nowDate.getYear();
        System.out.println("Year: " + year);

        int month = nowDate.getMonthValue();
        System.out.println("Month:" + month);

        int day = nowDate.getDayOfMonth();
        System.out.println("Day: " + day);

        // 今年的第几天
        int dayOfYear = nowDate.getDayOfYear();
        System.out.println("Day of year: " + dayOfYear);

        // 星期
        System.out.println(nowDate.getDayOfWeek());
        System.out.println(nowDate.getDayOfWeek().getValue());

        // 月份
        System.out.println(nowDate.getMonth());
        System.out.println(nowDate.getMonth().getValue());

        LocalDate bt = LocalDate.of(1921, 11, 11);
        System.out.println(bt);
        System.out.println(LocalDate.of(1991, Month.NOVEMBER, 11));
    }
}

在这里插入图片描述

package com.mochu.d4_jdk8time;

import java.time.LocalTime;

public class Demo02LocalTime {
    public static void main(String[] args) {
        // 获取本地事件对象
        LocalTime nowTime = LocalTime.now();
        System.out.println("今天的时间:" + nowTime);

        // 时
        int hour = nowTime.getHour();
        System.out.println("Hour: " + hour);

        // 分
        int minute = nowTime.getMinute();
        System.out.println("Minute: " + minute);

        // 秒
        int second = nowTime.getSecond();
        System.out.println("Second: " + second);

        // 纳秒
        int nano = nowTime.getNano();
        System.out.println("nano: " + nano);

        System.out.println("---------------------");
        System.out.println(LocalTime.of(8, 20)); // 时分
        System.out.println(LocalTime.of(8, 20, 30)); // 时分秒
        System.out.println(LocalTime.of(8, 20, 30, 150)); // 时分秒纳秒
        LocalTime mTime = LocalTime.of(8, 20, 30, 150);
    }
}

在这里插入图片描述
在这里插入图片描述

package com.mochu.d4_jdk8time;

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;

public class Demo03LocalDateTime {
    public static void main(String[] args) {
        // 日期 时间
        LocalDateTime nowDateTime = LocalDateTime.now();
        System.out.println("今天是:" + nowDateTime);
        System.out.println("年:" + nowDateTime.getYear());
        System.out.println("月:" + nowDateTime.getMonthValue());
        System.out.println("日:" + nowDateTime.getDayOfMonth());
        System.out.println("时:" + nowDateTime.getHour());
        System.out.println("分:" + nowDateTime.getMinute());
        System.out.println("秒:" + nowDateTime.getSecond());
        System.out.println("纳秒:" + nowDateTime.getNano());
        // 日,当年的第几天
        System.out.println("Day Of Year: " + nowDateTime.getDayOfYear());
        // 星期
        System.out.println("星期:" + nowDateTime.getDayOfWeek());
        System.out.println("星期:" + nowDateTime.getDayOfWeek().getValue());
        // 月份
        System.out.println("月份:" + nowDateTime.getMonth());
        System.out.println("月份:" + nowDateTime.getMonth().getValue());

        LocalDate ld = nowDateTime.toLocalDate();
        System.out.println(ld);
        LocalTime lt = nowDateTime.toLocalTime();
        System.out.println(lt.getHour());
        System.out.println(lt.getMinute());
        System.out.println(lt.getSecond());
    }
}

在这里插入图片描述

在这里插入图片描述

package com.mochu.d4_jdk8time;

import java.time.LocalDate;
import java.time.LocalTime;

public class Demo04UpdateTime {
    public static void main(String[] args) {
        LocalTime nowTime = LocalTime.now();
        System.out.println("当前时间:" + nowTime);
        System.out.println("一小时前:" + nowTime.minusHours(1));
        System.out.println("一小分钟前:" + nowTime.minusMinutes(1));
        System.out.println("一小秒钟前:" + nowTime.minusSeconds(1));
        System.out.println("一小纳秒前:" + nowTime.minusNanos(1));

        System.out.println("一小时后:" + nowTime.plusHours(1));
        System.out.println("一分钟后:" + nowTime.plusMinutes(1));
        System.out.println("一秒钟后:" + nowTime.plusSeconds(1));
        System.out.println("一纳秒后:" + nowTime.plusNanos(1));

        LocalDate myDate = LocalDate.of(2018, 9, 5);
        LocalDate nowDate = LocalDate.now();
    }
}

在这里插入图片描述

package com.mochu.d4_jdk8time;

import java.time.Instant;
import java.time.ZoneId;
import java.util.Date;

public class Demo05Instant {
    public static void main(String[] args) {
        Instant instant = Instant.now();
        System.out.println(instant);

        // 输出本机默认时间
        Instant instant1 = Instant.now();
        System.out.println(instant1.atZone(ZoneId.systemDefault()));

        // 返回Date对象
        Date date = Date.from(instant);
        System.out.println(date);

        Instant i2 = date.toInstant();
        System.out.println(i2);
    }
}

在这里插入图片描述

在这里插入图片描述

package com.mochu.d4_jdk8time;

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;

public class Demo06DateTimeFormat {
    public static void main(String[] args) {
        // 本地此刻、日期对象
        LocalDateTime ldt = LocalDateTime.now();
        System.out.println(ldt);

        // 解析 格式化器
        DateTimeFormatter dtf = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss EEE a");
        // 正向格式化
        System.out.println(dtf.format(ldt));
        // 逆向格式化
        System.out.println(ldt.format(dtf));

        //解析字符串时间
        DateTimeFormatter dtf1 = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
        String dateStr = "2019-11-11 11:11:11";
        LocalDateTime ldt1 = LocalDateTime.parse(dateStr, dtf1);
        System.out.println(ldt1);

        System.out.println(ldt1.getDayOfYear());
    }
}

在这里插入图片描述

package com.mochu.d4_jdk8time;

import java.time.LocalDate;
import java.time.Period;

public class Demo07Period {
    public static void main(String[] args) {
        LocalDate today = LocalDate.now();
        System.out.println(today);

        LocalDate birthDate = LocalDate.of(1998, 10, 13);
        System.out.println(birthDate);

        Period period = Period.between(birthDate,  today); //第二个参数减第一个参数
        System.out.println(period.getYears());
        System.out.println(period.getMonths());
        System.out.println(period.getDays());
    }
}

在这里插入图片描述
在这里插入图片描述

package com.mochu.d4_jdk8time;

import java.time.Duration;
import java.time.LocalDateTime;

public class Demo08Duration {
    public static void main(String[] args) {
        LocalDateTime today = LocalDateTime.now();
        System.out.println(today);

        LocalDateTime birthDate = LocalDateTime.of(2023, 03, 14, 20, 00, 00);
        System.out.println(birthDate);

        Duration duration = Duration.between(today, birthDate);
        System.out.println(duration.toDays());
        System.out.println(duration.toHours());
        System.out.println(duration.toMinutes());
        System.out.println(duration.toMillis());
        System.out.println(duration.toNanos());
    }
}

在这里插入图片描述

package com.mochu.d4_jdk8time;

import java.time.LocalDateTime;
import java.time.temporal.ChronoUnit;

public class Demo09ChronoUnit {
    public static void main(String[] args) {
        LocalDateTime today = LocalDateTime.now();
        System.out.println(today);

        LocalDateTime birthDate = LocalDateTime.of(2023, 03, 14, 20, 00, 00);
        System.out.println(birthDate);

        System.out.println("相差的年数:" + ChronoUnit.YEARS.between(birthDate, today));
        System.out.println("相差的月数:" + ChronoUnit.MONTHS.between(birthDate, today));
        System.out.println("相差的周数:" + ChronoUnit.WEEKS.between(birthDate, today));
        System.out.println("相差的天数:" + ChronoUnit.DAYS.between(birthDate, today));
        System.out.println("相差的时数:" + ChronoUnit.HOURS.between(birthDate, today));
        System.out.println("相差的分数:" + ChronoUnit.MINUTES.between(birthDate, today));
        System.out.println("相差的秒数:" + ChronoUnit.SECONDS.between(birthDate, today));
        System.out.println("相差的毫秒数:" + ChronoUnit.MILLIS.between(birthDate, today));
        System.out.println("相差的微妙数:" + ChronoUnit.MICROS.between(birthDate, today));
        System.out.println("相差的纳秒数:" + ChronoUnit.NANOS.between(birthDate, today));
        System.out.println("相差的半天数:" + ChronoUnit.HALF_DAYS.between(birthDate, today));
        System.out.println("相差的十年数:" + ChronoUnit.DECADES.between(birthDate, today));
        System.out.println("相差的世纪(百年)数:" + ChronoUnit.CENTURIES.between(birthDate, today));
        System.out.println("相差的千年数:" + ChronoUnit.MILLENNIA.between(birthDate, today));
        System.out.println("相差的纪元数:" + ChronoUnit.ERAS.between(birthDate, today));
    }
}

包装类

在这里插入图片描述

自动装箱:基本类型的数据和变量可以直接赋值给包装类型的变量。
自动拆箱:包装类型的变量可以直接赋值给基本数据类型的变量。

包装类的特有功能:

  • 包装类的变量的默认值可以是null,容错率高。
  • 可以把基本类型的数据转换成字符串类型(用处不大)
    – 调用toString()方法得到字符串结果
    – 调用Integer.toString(基本类型的数据)
  • 可以把字符串类型的数值转换成真实的数据类型
    integer.parseInt("字符串类型的整数")
    Double.parseDouble("字符串类型的浮点数")
package com.mochu.d5_integer;

public class Test {
    public static void main(String[] args) {
        int a = 10;
        Integer a1 = 11;
        Integer a2 = a; // 自动装箱
        System.out.println(a);
        System.out.println(a1);

        Integer it = 100;
        int it1 = it; // 自动拆箱
        System.out.println(it1);

        double db = 8.9;
        Double db1 = db;
        double db2 = db1;
        System.out.println(db2);

        Integer age = null;
        System.out.println("------------------");
        // 包装类可以把基本类型的数据转换成字符串类型
        Integer i3 = 23;
        String rs = i3.toString();
        System.out.println(rs + 1);

        String rs1 = Integer.toString(i3);
        System.out.println(rs + 1);

        String rs2 = i3 + "";
        System.out.println(rs2 + 1);
        System.out.println("------------------");
        String number = "23";
        // 转换成整数
        // int age1 = Integer.parseInt(number);
        int age1 = Integer.valueOf(number);
        System.out.println(age1 + 1);
        // 转换成小数
        String number1 = "59.5";
        // double score = Double.parseDouble(number1);
        double score = Double.valueOf(number1);
        System.out.println(score + 0.5);
    }
}

正则表达式

package com.mochu.d6_regex;

public class RegexDemo {
    public static void main(String[] args) {
        // 匹配QQ号
        System.out.println(checkQQ("2392517666"));
    }
    public static boolean checkQQ(String qq) {
        return qq != null && qq.matches("\\d{6,20}");
    }
}

在这里插入图片描述

package com.mochu.d6_regex;

public class RegexDemo {
    public static void main(String[] args) {
        System.out.println("a".matches("[abc]"));
        System.out.println("z".matches("[abc]"));

        System.out.println("a".matches("[^abc]"));
        System.out.println("z".matches("[^abc]"));

        System.out.println("a".matches("\\d"));
        System.out.println("3".matches("\\d"));
        System.out.println("333".matches("\\d"));
        System.out.println("z".matches("\\w"));
        System.out.println("2".matches("\\w"));
        System.out.println("21".matches("\\w"));
        System.out.println("你".matches("\\w"));
        System.out.println("你".matches("\\W"));

        System.out.println("123456".matches("\\w{6,}"));
        System.out.println("1234".matches("\\w{6,}"));

        System.out.println("a6Hv".matches("[a-zA-Z0-9]{4}"));
        System.out.println("8_f3".matches("[a-zA-Z0-9]{4}"));
        System.out.println("23dF".matches("[\\w&&[^_]]{4}"));
        System.out.println("23_F".matches("[\\w&&[^_]]{4}"));
    }
}
package com.mochu.d6_regex;

import java.util.Scanner;

public class RegexDemo {
    public static void main(String[] args) {
        // 匹配手机号码 邮箱 电话号码
        matchTell();
    }

    public static void matchPhoneNnumber(){
        Scanner sc = new Scanner(System.in);
        while (true) {
            System.out.println("请输入您的手机号:");
            String phonenum = sc.next();
            if(phonenum.matches("1[3-9]\\d{9}")) {
                System.out.println("手机号码格式正确");
                break;
            }else {
                System.out.println("手机号码格式有误");
            }
        }
    }

    public static void matchEmail() {
        Scanner sc = new Scanner(System.in);
        while (true) {
            System.out.println("请输入您的邮箱:");
            String email = sc.next();
            if(email.matches("\\w{1,}@[a-zA-Z0-9]{2,}(\\.[a-zA-Z0-9]{2,}){1,}")) {
                System.out.println("邮箱格式正确");
                break;
            }else {
                System.out.println("邮箱格式有误");
            }
        }
    }

    public static void matchTell() {
        Scanner sc = new Scanner(System.in);
        while (true) {
            System.out.println("请输入您的电弧号码:");
            String tellNum = sc.next();
            if(tellNum.matches("0\\d{2,6}-?\\d{5,20}")) {
                System.out.println("电话号码格式正确");
                break;
            }else {
                System.out.println("电话号码格式有误");
            }
        }
    }
}

在这里插入图片描述

package com.mochu.d6_regex;

public class RegexDemo {
    public static void main(String[] args) {
        String name = "末初gdg末初69ga末初ohow";
        String[] arrs = name.split("\\w+");
        for (int i = 0; i < arrs.length; i++) {
            System.out.println(arrs[i]);
        }
        String name2 = name.replaceAll("\\w+", " ");
        System.out.println(name2);
    }
}

在这里插入图片描述
在这里插入图片描述

Arrays类

在这里插入图片描述

package com.mochu.d7_arrays;

import java.util.Arrays;

public class ArraysDemo {
    public static void main(String[] args) {
        int arr[] = {10, 24, 7, 89, 51};
        // 打印输出
        System.out.println(Arrays.toString(arr));

        // 数组排序(升序)
        Arrays.sort(arr);
        System.out.println(Arrays.toString(arr));

        // 二分搜索(前提必须先排序),返回不存在元素的规律:-(应该插入的位置索引 + 1)
        int index = Arrays.binarySearch(arr, 51);
        System.out.println(index);
    }
}

在这里插入图片描述
在这里插入图片描述

package com.mochu.d7_arrays;

import java.util.Arrays;
import java.util.Comparator;

public class ArraysDemo02 {
    public static void main(String[] args) {
        // 子定义数组的排序规则:Comparator比较器对象
        // 降序
        Integer[] ages = {11, 92, 21, 7, 45, 22, 56, 31};
        /**
         * 参数一:被排序的数组,引用类型的数组
         * 参数二:匿名内部类对象,代表一个比较器对象
         */
        Arrays.sort(ages, new Comparator<Integer>() {
            @Override
            public int compare(Integer o1, Integer o2) {
                // 制定比较规则
//                if(o1 > o2) {
//                    return 1;
//                }else if(o1 < o2){
//                    return -1;
//                }
//                return 0;
                // return o1 - o2; // 默认升序
                return - (o1 - o2); // 降序
            }
        });
        System.out.println(Arrays.toString(ages));
        Student[] students = new Student[3];
        students[0] = new Student("mochu7", 21, 175.5);
        students[1] = new Student("Slevin", 18, 182.5);
        students[2] = new Student("Shinn", 25, 165.5);
        System.out.println(Arrays.toString(students));
        Arrays.sort(students, new Comparator<Student>() {
            @Override
            public int compare(Student o1, Student o2) {
                // 制定比较规则
                // return o1.getAge() - o2.getAge(); // 按照年龄升序排序
                // return o2.getAge() - o1.getAge(); // 按照年龄降序
                // return Double.compare(o1.getHeight(), o2.getHeight()); // 按照身高升序
                return Double.compare(o2.getHeight(), o1.getHeight()); // 按照身高降序
            }
        });
        System.out.println(Arrays.toString(students));
    }
}

选择排序、二分查找

在这里插入图片描述

package com.mochu.d8_binsearch;

import java.util.Arrays;

public class Test {
    public static void main(String[] args) {
        int[] arr = {5, 1, 3, 2};
        for (int i = 0; i < arr.length - 1; i++) {
            for (int j = i + 1; j < arr.length; j++) {
                if(arr[i] > arr[j]) {
                    int temp = arr[i];
                    arr[i] = arr[j];
                    arr[j] = temp;
                }
            }
        }
        System.out.println(Arrays.toString(arr));
    }
}
package com.mochu.d8_binsearch;

public class Test {
    public static void main(String[] args) {
        int[] arr = {10, 14, 16, 25, 28, 30, 35, 88, 100};
        System.out.println(binarySearch(arr, 35));
        System.out.println(binarySearch(arr, 350));
    }

    /**
     * 二分法查找
     * @param arr 排序过后的数组
     * @param data 要找的数据
     * @return
     */
    public static int binarySearch(int[] arr, int data) {
        int left = 0;
        int right = arr.length - 1;
        while (left <= right) {
            int midIndex = (left + right) / 2;
            if(data > arr[midIndex]) {
                left = midIndex + 1;
            }else if(data < arr[midIndex]) {
                right = midIndex - 1;
            }else {
                return midIndex;
            }
        }
        return -1;
    }
}

Lambda表达式

  • Lambda表达式是JDK8开始后的一种新语法形式。
  • 作用:简化匿名内部类的代码写法。
(匿名内部类被重写方法的形参列表) -> {
	被重写方法的方法体代码
}

注意:Lambda表达式只能简化函数式接口的匿名内部类的写法形式

函数式接口:

  • 首先必须是接口,其次接口中有且仅有一个抽象方法的形式
  • 通常会在接口上加上一个@FunctionalInterface注解,标记该接口必须是满足函数式接口
package com.mochu.d9_Lambda;

public class LambdaDemo {
    public static void main(String[] args) {
//        Swimming s1 = new Swimming() {
//            @Override
//            public void swim() {
//                System.out.println("Swimming...");
//            }
//        };
        // 匿名类简化
        Swimming s2 = () -> {
            System.out.println("Swimming...");
        };
        go(s2);

//        go(new Swimming() {
//            @Override
//            public void swim() {
//                System.out.println("Swimming");
//            }
//        });

        go(() -> {
            System.out.println("Swimming");
        });
    }

    public static void go(Swimming s){
        s.swim();
    }
}

@FunctionalInterface // 一旦加上这个注解则必须是函数式接口,里面只能有一个抽象方法
interface Swimming() {
    void swim();
}

Lambda表达式简化Comparator接口的匿名形式

在这里插入图片描述
在这里插入图片描述

Lambda表达式的省略写法(进一步在Lambda表达式的基础上继续简化)

  • 参数类型可以省略不写
  • 如果只有一个参数,参数类型可以省略,同时()也可以省略
  • 如果Lambda表达式的方法体代码只有一行代码,可以省略大括号不写,同时要省略分号
  • 如果Lambda表达式的方法体代码只有一行代码,可以省略大括号不写,此时,如果这行代码是return语句,必须省略return不写,同时也必须省略;不写

集合概述、Collection集合的体系特点

集合和数组都是容器

  • 数组定义完成并启动后,类型确定、长度固定
  • 数组在进行增删数据操作的时候,数组是不太合适的,增删数据都需要放弃原有数组或者移位

数组适合业务数据个数固定的,且都是同一批数据类型的时候,可以采取定义数组存储

集合是Java中存储对象数据的一种容器

  • 集合的大小不固定、启动后可以动态变化,类型也可以选择不固定
  • 集合非常适合元素的增删操作

注意:集合中只能存储引用类型的数据,如果要存储基本类型数据需要包装类


集合分为以下两类:

  • Collection单列集合,每个元素(数据)只包含一个值
  • Map双列集合,每个元素包含两个值(键值对)

在这里插入图片描述
在这里插入图片描述

集合对于泛型的支持

  • 集合都是支持泛型的,可以在编译阶段约束集合只能操作某种数据类型

注意:集合和泛型都只能支持引用数据类型,不支基本数据类型,所以集合中存储的元素都认为是对象。

package com.mochu.d1_collection;

import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;

public class CollectionDemo01 {
    public static void main(String[] args) {
        // List体系特点:有序、可重复、有索引
        Collection list = new ArrayList();
        list.add("java");
        list.add("java");
        list.add("python");
        list.add("php");
        System.out.println(list);

        // Set体系特点:无序、不重复、无索引
        Collection set = new HashSet();
        set.add("java");
        set.add("java");
        set.add("python");
        set.add("php");
        System.out.println(set);

        System.out.println("-----------------");
        Collection<String> list2 = new ArrayList<>();
        list2.add("mochu7");
        list2.add("slevin");
        // 集合和泛型都只能支持引用类型
        Collection<Integer> list3 = new ArrayList<>();
        list3.add(23);
        list3.add(100);

        Collection<Double> list4 = new ArrayList<>();
        list4.add(59.9);
    }
}

Collection常用API、遍历方式、存储自定义类型对象

在这里插入图片描述

package com.mochu.d2_collection_api;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;

public class CollectionDemo {
    public static void main(String[] args) {
        Collection<String> list = new ArrayList<>();
        list.add("Java");
        list.add("HTML");
        list.add("PHP");
        list.add("Python");
        System.out.println(list);
        // list.clear();
        // System.out.println(list);
        System.out.println(list.isEmpty());
        System.out.println(list.size());
        System.out.println(list.contains("Java"));
        list.remove("PHP");
        System.out.println(list);
        Object[] arr = list.toArray();
        System.out.println("数组:" + Arrays.toString(arr));

        Collection<String> c1 = new ArrayList<>();
        c1.add("java");
        c1.add("slevin");
        Collection<String> c2 = new ArrayList<>();
        c2.add("mochu7");
        c1.addAll(c2);
        System.out.println(c1);
    }
}

Collection集合的遍历方式

方式一:迭代器

package com.mochu.d2_collection_api;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Iterator;

public class CollectionDemo {
    public static void main(String[] args) {
        Collection<String> list = new ArrayList<>();
        list.add("Java");
        list.add("HTML");
        list.add("PHP");
        list.add("Python");
        Iterator<String> it = list.iterator();
//        String ele = it.next();
//        System.out.println(it.next());
//        System.out.println(it.next());
//        System.out.println(it.next());
        while(it.hasNext()) {
            String ele = it.next();
            System.out.println(ele);
        }
    }
}

在这里插入图片描述

第二种:foreach遍历/增强for循环

增强for循环:

  • 增强for循环既可以遍历集合也可以遍历数组
  • JDK5之后出现的,其内部原理是一个iterator迭代器,遍历集合相当于是迭代器的简化写法
  • 实现iterable接口的类才可以使用迭代器和增强for,Collection接口已经实现了Iterable接口

格式

for(元素数据类型 变量名: 数组或者Collection集合) {
	// 在此处使用变量即可,该变量就是元素
}
package com.mochu.d2_collection_api;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Iterator;

public class CollectionDemo {
    public static void main(String[] args) {
        Collection<String> list = new ArrayList<>();
        list.add("Java");
        list.add("HTML");
        list.add("PHP");
        list.add("Python");
        for(String ele: list) {
            System.out.println(ele);
        }
        double[] scores = {100.0, 99.5, 59.5};
        for (double score : scores) {
            System.out.println(score);
        }
    }
}

第三种:Lambda表达式

在这里插入图片描述

package com.mochu.d2_collection_api;

import java.util.ArrayList;
import java.util.Collection;
import java.util.function.Consumer;

public class CollectionDemo {
    public static void main(String[] args) {
        Collection<String> list = new ArrayList<>();
        list.add("Java");
        list.add("HTML");
        list.add("PHP");
        list.add("Python");
        list.forEach(new Consumer<String>() {
            @Override
            public void accept(String s) {
                System.out.println(s);
            }
        });
        System.out.println("------------------");
        list.forEach(s -> {
            System.out.println(s);
        });
        System.out.println("------------------");
        list.forEach(s -> System.out.println(s));
        System.out.println("------------------");
        list.forEach(System.out::println);
    }
}

在这里插入图片描述

package com.mochu.d3_collection_object;

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.mochu.d3_collection_object;

import java.util.ArrayList;
import java.util.Collection;

public class Test {
    public static void main(String[] args) {
        Collection<Movie> movies = new ArrayList<>();
        movies.add(new Movie("《流浪地球2》", 9.5, "吴京、刘德华"));
        movies.add(new Movie("《唐人街探案》", 8.5, "王宝强、刘昊然"));
        movies.add(new Movie("《刺杀小说家》", 8.7, "雷佳音、杨幂"));

        for (Movie movie : movies) {
            System.out.println("电影名称:" + movie.getName());
            System.out.println("电影评分:" + movie.getScore());
            System.out.println("电影主演:" + movie.getActor());
        }
    }
}

在这里插入图片描述

常见数据结构

数据结构、栈、队列

数据结构概述:

  • 数据结构是计算机底层存储、组织数据的方式。是指数据相互之间是以什么方式排列在一起的
  • 通常情况下、精心选择的数据结构可以带来更高的运行或者存储效率

数据进入栈模型的过程称为:压/进栈
数据离开栈模型的过程称为:弹/出栈

栈数据结构的执行特点:后进先出、先进后出

在这里插入图片描述


队列数据结构的执行特点:先进先出、 后进后出

数据从后端进入队列模型的过程称为:入队列
数据从前端离开队列模型的过程称为:出队列

在这里插入图片描述

常见数据结构之数组

数据结构的特点

  • 查询速度快:查询数据通过地址值和索引定位、查询任意数据耗时相同。(元素在内存中是连续存储的)
  • 删除效率低:要将原始数据删除、同时后面每个数据迁移
  • 添加效率极低:添加位置后的每个数据后移、再添加元素

数据查询数据:起始地址 + 偏移地址

综上所述:数组是一种根据索引查询快、增删慢的模型

常见数据结构之链表

  • 链表中的元素是在内存中不连续存储的,每个元素节点包含数据值和下一个元素的地址

在这里插入图片描述
在这里插入图片描述
链表的特点:

  • 链表查询慢:无论查询哪个数据都要从头开始找
  • 链表增删较快

在这里插入图片描述

链表是一种查询慢、增删快(相对数组)的模型

链表分为:

  • 单项链表:只能从前往后找
  • 双向链表:可以从前往后也可以从后往前找

在这里插入图片描述
双链表增删中间的数据不一定快、但增删首尾的数据很快

常见数据结构之二叉树

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

常见数据结构之红黑树

  • 红黑树是一种平衡的二叉查找树
  • 1972年出现,当时被称为“平衡二叉B树”,1978年被修改为如今的“红黑树”
  • 每一个节点可以是红或者黑;红黑树不是通过高度平衡的,它的平衡是通过“红黑规则”进行实现的

在这里插入图片描述
在这里插入图片描述

List系列集合、集合的并发修改异常问题

List集合特点、特有API

List系列集合特点:

  • ArrayList、LinekdList: 有序、可重复、有索引
  • 有序:存储和取出的元素顺序一致
  • 有索引:可以通过索引操作元素
  • 可重复:存储的元素可以重复

在这里插入图片描述

package com.mochu.d4_collection_list;

import java.util.ArrayList;
import java.util.List;

public class ListDemo01 {
    public static void main(String[] args) {
        List<String> list = new ArrayList<>();
        list.add("java");
        list.add("python");
        list.add("php");
        list.add(2, "html");
        System.out.println(list);
        list.remove(2);
        System.out.println(list);
        System.out.println(list.get(2));
        // 修改指定索引的值
        System.out.println(list.set(1, "go"));
        System.out.println(list);
    }
}

在这里插入图片描述

List集合遍历

  • 迭代器
  • 增强for循环
  • Lambda表达式
  • for循环(因为List集合存在索引)
package com.mochu.d4_collection_list;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

public class ListDemo01 {
    public static void main(String[] args) {
        List<String> list = new ArrayList<>();
        list.add("java");
        list.add("python");
        list.add("php");
        list.add("go");
        list.add("html");

        // for循环
        for (int i = 0; i < list.size(); i++) {
            System.out.println(list.get(i));
        }

        // 迭代器
        Iterator<String> it = list.iterator();
        while(it.hasNext()) {
            System.out.println(it.next());
        }

        // 增强for循环 foreach
        for(String ele : list){
            System.out.println(ele);
        }

        // Lambda表达式
        list.forEach(s -> {
            System.out.println(s);
        });
    }
}

在这里插入图片描述

package com.mochu.d4_collection_list;

import java.util.LinkedList;

public class ListDemo01 {
    public static void main(String[] args) {
        // LinkedList可以完成队列结构、栈结构(双链表)
        // 栈
        LinkedList<String> stack = new LinkedList<>();
        // 压栈、入栈
        stack.addFirst("第1颗子弹");
        // stack.push();
        stack.addFirst("第2颗子弹");
        stack.addFirst("第3颗子弹");
        stack.addFirst("第4颗子弹");
        stack.addFirst("第5颗子弹");
        System.out.println(stack);
        System.out.println("---------------");
        // 出栈、弹栈
        System.out.println(stack.removeFirst());
        // System.out.println(stack.pop());
        System.out.println(stack.removeFirst());
        System.out.println(stack.removeFirst());
        System.out.println(stack);
        System.out.println("-------------------");
        // 队列
        LinkedList<String> queue = new LinkedList<>();
        // 入列
        queue.addLast("1号");
        queue.addLast("2号");
        queue.addLast("3号");
        queue.addLast("4号");
        queue.addLast("5号");
        // 出列
        System.out.println(queue.removeFirst());
        System.out.println(queue.removeFirst());
        System.out.println(queue.removeFirst());
        System.out.println(queue);
    }
}

集合的并发修改异常问题

package com.mochu.d4_collection_list;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

public class ListDemo01 {
    public static void main(String[] args) {
        List<String> list = new ArrayList<>();
        list.add("java");
        list.add("python");
        list.add("php");
        list.add("java");
        list.add("go");
        list.add("html");
        list.add("java");
        System.out.println(list);

        // 删除全部的Java信息
        // 迭代器遍历删除
        Iterator<String> it = list.iterator();
        while(it.hasNext()) {
            String ele = it.next();
            if(ele.equals("java")) {
                // list.remove("java") // 会后移导致报错
                it.remove(); // 使用迭代器删除当前所在元素,不会后移
            }
        }
        System.out.println(list);
        
        // for循环遍历删除也会存在后移问题,但是可以通过逆序遍历删除或者每次删除一次指针前移一下
        // 逆序
//        for (int i = list.size() - 1; i >= 0; i--) {
//            String ele = list.get(i);
//            if(ele.equals("java")) {
//                list.remove("java");
//            }
//        }
        // 每次删除后索引前移一位
        for (int i = 0; i < list.size(); i++) {
            String ele = list.get(i);
            if(ele.equals("java")) {
                list.remove("java");
                i--;
            }
        }

    }
}

在这里插入图片描述

泛型深入、自定义泛型、泛型通配符、上下限

泛型的概述和优势

  • 泛型:是JDK5引入的特性,可以在编译阶段约束操作的数据类型,并进行检查
  • 泛型的格式:<数据类型>; 注意:泛型只能支持引用数据类型
  • 集合体系的全部接口和实现类都是支持泛型的使用的

泛型的好处:

  • 统一数据类型
  • 把运行时期的问题提前到编译期间,避免了强制类型转换可能出现的异常

自定义泛型类

泛型类的概述

  • 定义类时同时定义了泛型的类就是泛型类
  • 泛型类的格式:修饰符 class 类名<泛型变量>{}
  • 此处泛型变量T可以随便写为任意标识,常见的如ETKV
  • 作用:编译阶段可以指定数据类型,类似于集合的作用

泛型类的原理:把出现泛型变量的地方全部替换成传输的真实数据类型

自定义泛型方法

泛型方法的概述:

  • 定义方法时同时定义了泛型的方法就是泛型方法
  • 泛型方法的格式:修饰符 <泛型变量> 方法返回值 方法名称(形参列表){}

作用:方法中可以使用泛型接受一切实际类型的参数,方法更具备通用性

package com.mochu.d6_genericity_class;

public class Test {
    public static void main(String[] args) {
        Integer[] ages = {10, 20, 30, 40, 50};
        String[] names = {"mochu7", "slevin", "shinn"};
        printArray(ages);
        printArray(names);
    }

    public static <T> void printArray(T[] arr) {
        if(arr != null) {
            StringBuilder sb = new StringBuilder("[");
            for (int i = 0; i < arr.length; i++) {
                sb.append(arr[i]).append(i == arr.length - 1 ? "" : ", ");
            }
            sb.append("]");
            System.out.println(sb);
        }else {
            System.out.println(arr);
        }
    }
}

自定义泛型接口

  • 使用了泛型定义的接口就是泛型接口
  • 泛型接口的格式:修饰符 interface 接口名称<泛型变量>{}
  • 作用: 泛型接口可以让实现类选择当前功能需要操作的数据类型
  • 泛型接口的原理:实现类可以在实现接口的时候传入自己操作的数据类型,这样重写的方法都将是针对该类型的操作。

泛型通配符、上下限

通配符:?

  • ?可以在使用泛型的时候代表一切类型
  • E T K V是在定义泛型的时候使用的

泛型上下限:

  • ? extends Car?必须是Car或者其子类 泛型上限
  • ? extends Car: ?必须是Car或者其父类 泛型下限
package com.mochu.d8_genericity_limit;

import java.util.ArrayList;

public class GenericityDemo {
    public static void main(String[] args) {
        ArrayList<BMW> bmws = new ArrayList<>();
        bmws.add(new BMW());
        bmws.add(new BMW());
        bmws.add(new BMW());
        go(bmws);

        ArrayList<BENZ> benzs = new ArrayList<>();
        benzs.add(new BENZ());
        benzs.add(new BENZ());
        benzs.add(new BENZ());
        go(benzs)
    }

    public static void go(ArrayList<? extends Car> cars) {

    }
}
class Car {

}

class BENZ extends Car {

}

class BMW extends Car {

}

Set系列集合、Collection体系的总结

在这里插入图片描述
Set系列集合特点:

  • 无序:存储顺序不一致
  • 不重复:可以去重复
  • 无索引:没有带索引的方法,所以不能使用for循环遍历,也不能通过索引获取元素

Set集合实现类特点:

  • HashSet:无序、不重复、无索引
  • LinkedHashSet:有序、不重复、无索引
  • TreeSet:排序、不重复、无索引

Set集合的功能基本上与Collection的API一致

package com.mochu.d1_Set;

import java.util.HashSet;
import java.util.LinkedHashSet;
import java.util.Set;

public class SetDemo {
    public static void main(String[] args) {
        // 查看Set集合特点:Hashset LinkedHashSet TreeSet
        // Set<String> sets = new HashSet<>(); // HashSet特点:无序、不重复、无索引
        Set<String> sets = new LinkedHashSet<>(); // LinkedHashSet特点:有序、不重复、无索引
        sets.add("Java");
        sets.add("Python");
        sets.add("PHP");
        sets.add("HTML");
        sets.add("SpringBoot");
        System.out.println(sets);
    }
}

HashSet元素无序的底层原理:哈希表

  • HashSet集合底层采取哈希表存储的数据
  • 哈希表是一种对于增删改查数据性能都比较好的结构

哈希表的组成:

  • JDK8之前,底层使用数组 + 链表组成
  • JDK8之后,底层采用数组 + 链表 + 红黑树组成

哈希值:哈希值是JDK根据对象地址,按照某种规则算出来的int类型的数值。

Object类的API:public int hashCode():返回对象的哈希值

对象哈希值的特点:

  • 同一个对象多次调用hashCode()方法返回的哈希值是相同的
  • 默认情况下,不同对象的哈希值是不同的
package com.mochu.d1_Set;

public class SetDemo02 {
    public static void main(String[] args) {
        // 获取对象的哈希值
        String name = "mochu7";
        String name1 = "slevin";
        System.out.println(name.hashCode());
        System.out.println(name.hashCode());
        System.out.println(name1.hashCode());
        System.out.println(name1.hashCode());
    }
}

在这里插入图片描述
在这里插入图片描述

JDK1.8版本开始HashSet原理解析

  • 底层结构:哈希表(数组、链表、红黑树的结合体)
  • 当挂在元素下面的数据过多时,查询性能降低,从JDK8开始后,当链表长度超过8的时候,自动转换为红黑树

在这里插入图片描述

HashSet元素去重复的底层原理

在这里插入图片描述
在这里插入图片描述

package com.mochu.d2_hashset;

import java.util.HashSet;
import java.util.Set;

public class HashSetDemo {
    public static void main(String[] args) {
        Set<Student> sets = new HashSet<>();
        // Set集合去重的原因:先判断哈希值再判断equals
        Student s1 = new Student("mochu7", 22, "male");
        Student s2 = new Student("slevin", 21, "male");
        Student s3 = new Student("mochu7", 22, "male");
        System.out.println(s1.hashCode());
        System.out.println(s2.hashCode());
        System.out.println(s3.hashCode());
        sets.add(s1);
        sets.add(s2);
        sets.add(s3);
        // 重写hashcode方法后,s1和s3的哈希值和内容是一样的,会被去重
        System.out.println(sets);
    }
}
package com.mochu.d2_hashset;

import java.util.Objects;

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

    public Student() {
    }

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

    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 getGender() {
        return gender;
    }

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

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        Student student = (Student) o;
        return age == student.age && Objects.equals(name, student.name) && Objects.equals(gender, student.gender);
    }

    @Override
    public int hashCode() {
        return Objects.hash(name, age, gender);
    }

    @Override
    public String toString() {
        return "Student{" +
                "name='" + name + '\'' +
                ", age=" + age +
                ", gender='" + gender + '\'' +
                '}';
    }
}

实现类:LinkedHashSet

LinkedHashSet集合概述和特点:有序、不重复、无索引

package com.mochu.d2_hashset;

import java.util.LinkedHashSet;
import java.util.Set;

public class LinkedHashSetDemo {
    public static void main(String[] args) {
        Set<String> sets = new LinkedHashSet<>();
        sets.add("Java");
        sets.add("Python");
        sets.add("PHP");
        sets.add("HTML");
        System.out.println(sets);
    }
}

原理:底层数据结构是依然哈希表,只是每个元素又额外多了一个双链表的机制记录存储的顺序

实现类:TreeSet

TreeSet集合概述和特点:

  • 不重复、无索引、可排序
  • 可排序:按照元素的大小默认升序(有小到大)排序
  • TreeSet集合底层是基于红黑树的数据结构实现排序的,增删改查性能都较好
  • 注意:TreeSet集合是一定要排序的,可以将元素按照指定的规则进行排序

TreeSet集合默认的规则

  • 对于数值类型:Integer、Double,官方默认按照大小进行升序排序
  • 对于字符串类型:默认按照首字符的ASCII编号升序排序
  • 对于自定义类型如Student对象,TreeSet无法直接排序(需要制定排序规则)

TreeSet集合存储对象的时候有两种方式可以设计自定义比较规则:

  • 方式一:让自定义的类实现Comparable接口重写里面的compareTo方法制定比较规则
  • 方式二:TreeSet集合有参数构造器,可以设置Comparator接口对应的比较器对象,来定制比较规则

两种方式中,关于返回值的规则:

  • 如果认为第一个元素大于第二个元素返回正整数即可
  • 如果认为第一个元素小于第二个元素返回负整数即可
  • 如果认为第一个元素等于第二个元素返回0即可,此时Treeset集合只会保留一个元素,认为两种重复

注意:如果TreeSet集合存储的对象有实现比较规则,集合也自带比较器,默认使用集合自带的比较器排序

package com.mochu.d2_hashset;

import java.util.Comparator;
import java.util.Set;
import java.util.TreeSet;

public class SetDemo {
    public static void main(String[] args) {
        Set<Integer> sets = new TreeSet<>(); // 不重复、无索引、可排序
        sets.add(23);
        sets.add(12);
        sets.add(87);
        sets.add(67);
        sets.add(43);
        System.out.println(sets);
        System.out.println("---------------------");

        Set<String> set1 = new TreeSet<>();
        set1.add("Java");
        set1.add("Python");
        set1.add("末初");
        set1.add("PHP");
        set1.add("HTML");
        set1.add("Slevin");
        set1.add("mochu7");
        System.out.println(set1);
        System.out.println("-------------------");
        // 第二种比较方法:集合自带比较器方法
        Set<Apple> apples = new TreeSet<>(new Comparator<Apple>() {
            @Override
            public int compare(Apple o1, Apple o2) {
                // 降序
                // return o2.getWeight() - o1.getWeight();
                // 价格比较(降序),浮点型使用Double.compare
                return Double.compare(o2.getPrice(), o1.getPrice());
            }
        });
        apples.add(new Apple("红苹果", 10.5, "红色", 500));
        apples.add(new Apple("青苹果", 7.5, "青色", 450));
        apples.add(new Apple("绿苹果", 8.5, "绿色", 520));
        apples.add(new Apple("黄苹果", 12.5, "黄色", 510));
        // 指定TreeSet排序规则
        System.out.println(apples);

    }
}
package com.mochu.d2_hashset;

public class Apple implements Comparable<Apple>{
    private String name;
    private Double price;
    private String color;
    private int weight;

    public Apple() {
    }

    public Apple(String name, Double price, String color, int weight) {
        this.name = name;
        this.price = price;
        this.color = color;
        this.weight = weight;
    }

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

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

    public int getWeight() {
        return weight;
    }

    public void setWeight(int weight) {
        this.weight = weight;
    }

    @Override
    public String toString() {
        return "Apple{" +
                "name='" + name + '\'' +
                ", price=" + price +
                ", color='" + color + '\'' +
                ", weight=" + weight +
                '}';
    }

    /**
     * 第一种比较方式:类自定义比较方法
     * @param o
     * @return
     */
    @Override
    public int compareTo(Apple o) {
        // 按照重量进行比较(升序)
        return this.weight - o.weight >= 0 ? 1 : -1;
    }
}

在这里插入图片描述
在这里插入图片描述

可变参数、集合操作的工具类Collections

可变参数:

  • 可变参数用在形参中可以接受多个数据
  • 可变参数的格式:数据类型...参数名称

可变参数的作用:传输参数非常灵活,方便。可以不传输参数,可以传输1个或者多个,也可以传输一个数组

可变参数在方法内部本质上就是一个数组

可变参数的注意事项:

  • 一个形参列表中可变参数只能有一个
  • 可变参数必须在形参列表的最后面
package com.mochu.d3_params;

import java.util.Arrays;

public class MethodDemo {
    public static void main(String[] args) {
        // 不传参
        sum();
        // 传输一个参数
        sum(10);
        // 传输多个参数
        sum(10, 20, 30);
        // 传输数组参数
        sum(new int[]{10, 20, 30, 40, 50});
    }

    public static void sum(int...nums) {
        // 注意:可变参数在方法内部就是一个数组
        System.out.println("元素个数:" + nums.length);
        System.out.println("元素内容:" + Arrays.toString(nums));
    }
}

Collections集合工具类

  • java.utils.Collections是集合工具类
  • 作用:Collections并不属于集合,是用来操作集合的工具类

在这里插入图片描述
在这里插入图片描述

package com.mochu.d3_params;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

public class CollectionsDemo {
    public static void main(String[] args) {
        List<String> list = new ArrayList<>();
        // 批量添加元素
        Collections.addAll(list, "mochu7", "Slevin", "Shinn", "末初");
        System.out.println(list);
        // list集合打乱顺序 public static void shuffle(List<?> list)
        Collections.shuffle(list);
        System.out.println(list);
        // list集合排序 public static <T> void sort(List<T> list)
        List<Integer> list1 = new ArrayList<>();
        Collections.addAll(list1, 12, 54, 67, 23, 63, 97, 56);
        Collections.sort(list1);
        System.out.println(list1);

    }
}

在这里插入图片描述

斗地主游戏

在这里插入图片描述

package com.mochu.d4_game;

public class Card {
    private String size;
    private String color;
    private int index;

    public Card() {
    }

    public Card(String size, String color, int index) {
        this.size = size;
        this.color = color;
        this.index = index;
    }

    public String getSize() {
        return size;
    }

    public void setSize(String size) {
        this.size = size;
    }

    public String getColor() {
        return color;
    }

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

    public int getIndex() {
        return index;
    }

    public void setIndex(int index) {
        this.index = index;
    }

    @Override
    public String toString() {
        return size + color;
    }
}
package com.mochu.d4_game;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;

public class GameDemo {
    /**
     * 定义一个静态集合存储54张牌对象
     */
    public static List<Card> allCards = new ArrayList<>();

    /**
     * 定义静态代码块初始化牌数据
     */
    static{
        String[] sizes = {"3", "4", "5", "6", "7", "8", "9", "J", "Q", "K", "A", "2"};
        String[] colors = {"♦", "♥", "♣", "♠"};
        int index = 0; // 牌的权重
        for(String size : sizes) {
            index++;
            for(String color : colors) {
                // 封装牌对象
                Card c = new Card(size, color, index);
                // 存储集合容器
                allCards.add(c);
            }
        }
        // 大小王存储牌集合
        Card c1 = new Card("", "小王", ++index);
        Card c2 = new Card("", "大王", ++index);
        Collections.addAll(allCards, c1, c2);
        System.out.println("新牌:" + allCards);
    }

    public static void main(String[] args) {
        // 洗牌
        Collections.shuffle(allCards);
        System.out.println("洗牌后:" + allCards);

        // 定义三个玩家,每个玩家定义一个集合容器
        List<Card> player1 = new ArrayList<>();
        List<Card> player2 = new ArrayList<>();
        List<Card> player3 = new ArrayList<>();

        // 开始发牌:从牌堆中发出51张牌,剩余三张作为底牌
        for (int i = 0; i < allCards.size() - 3; i++) {
            Card c = allCards.get(i);
            if(i % 3 == 0){
                // player1拿牌
                player1.add(c);
            }else if(i % 3 == 1) {
                // player2拿牌
                player2.add(c);
            }else if(i % 3 == 2) {
                // player3拿牌
                player3.add(c);
            }
        }
        // 把最后三张牌底牌截取截取到一个子集合
        List<Card> lastTreeCard = allCards.subList(allCards.size() - 3, allCards.size());

        // 玩家拿到牌之后排序(从大到小)
        sortCards(player1);
        sortCards(player2);
        sortCards(player3);

        // 输出玩家的牌
        System.out.println("\n");
        System.out.println("Player1的牌:" + player1);
        System.out.println("Player2的牌:" + player2);
        System.out.println("Player3的牌:" + player3);
        System.out.println("三张底牌:" + lastTreeCard);

    }

    /**
     * 给玩家的牌做排序(从大到小)
     * @param cards
     */
    private static void sortCards(List<Card> cards) {
        Collections.sort(cards, (o1, o2) -> o2.getIndex() - o1.getIndex());
    }
}

Map集合概述、API、遍历方式

Map集合概述

  • Map集合是一种双列集合,每个元素包含两个数据
  • Map集合的每个元素的格式:key=value(键值对元素)
  • Map集合也被称为”键值对集合“
  • Map集合的键:无序、不重复的
    Map集合的值:值可以重复

Map集合体系特点

Map集合体系的特点:

  • Map集合的特点都是由键决定的
  • Map集合的键是无序,不重复的,无索引的,值不做要求(可以重复)
  • Map集合后面重复的键对应的值会覆盖前面重复键的值
  • Map集合的键值对都可以为null

Map集合实现类特点:

  • HashMap:元素按照键是无序的,不重复,无索引,值不做要求
  • LinkedHashMap:元素按照键有序的,不重复,无索引,值不做要求

在这里插入图片描述

package com.mochu.d5_map;

import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.Map;

public class MapDemo {
    public static void main(String[] args) {
        Map<String, Integer> maps = new HashMap<>();
        maps.put("iPhone14", 10000);
        maps.put("HUAWEI mate50", 6000);
        maps.put("JAVA从入门到入土", 50);
        maps.put(null, null);
        System.out.println(maps);

        Map<String, Integer> maps1 = new LinkedHashMap<>();
        maps1.put("iPhone14", 10000);
        maps1.put("HUAWEI mate50", 6000);
        maps1.put("JAVA从入门到入土", 50);
        maps1.put(null, null);
        System.out.println(maps1);
    }
}

在这里插入图片描述

Map集合常用的API

在这里插入图片描述

package com.mochu.d5_map;

import java.util.*;

public class MapDemo {
    public static void main(String[] args) {
        Map<String, Integer> maps = new HashMap<>();
        maps.put("iPhone14", 10000);
        maps.put("HUAWEI mate50", 6000);
        maps.put("JAVA从入门到入土", 50);
        maps.put(null, null);
        System.out.println(maps);

        // 清空集合
        // maps.clear();

        // 判断集合是否为空
        System.out.println(maps.isEmpty());

        // 根据键值取值(没有这个键取出来的就是null)
        System.out.println(maps.get("iPhone14"));
        System.out.println(maps.get("HUAWEI mate50"));

        // 根据键值删除
        maps.remove("HUAWEI mate50");
        System.out.println(maps);

        // 判断是否包含某个键值
        System.out.println(maps.containsKey("iPhone14"));

        // 判断是否包含某个值
        System.out.println(maps.containsValue(50));

        // 获取全部键集合 public Set<K> keySet()
        Set<String> keys = maps.keySet();
        System.out.println(keys);

        // 获取所有值 Collection<V> values()
        Collection<Integer> values = maps.values();
        System.out.println(values);

        // 集合的大小
        System.out.println(maps.size());

        // 合并其他map集合
        Map<String, Integer> map1 = new HashMap<>();
        map1.put("JAVA", 100);
        map1.put("Python", 80);
        map1.put("C++", 90);
        Map<String, Integer> map2 = new HashMap<>();
        map2.put("GO", 110);
        map2.put("PHP", 70);
        map2.put("JavaScript", 120);
        map1.putAll(map2);
        System.out.println(map1);
    }
}

Map集合遍历方式一:键找值

在这里插入图片描述

package com.mochu.d5_map;

import java.util.*;

public class MapDemo {
    public static void main(String[] args) {
        Map<String, Integer> maps = new HashMap<>();
        maps.put("iPhone14", 10000);
        maps.put("HUAWEI mate50", 6000);
        maps.put("JAVA从入门到入土", 50);
        maps.put("xiaomi13", 4500);
        System.out.println(maps);

        Set<String> keys = maps.keySet();
        for(String key : keys) {
            int value = maps.get(key);
            System.out.println(key + " ==> " + value);
        }
    }
}

Map遍历集合方式二:键值对
在这里插入图片描述

package com.mochu.d5_map;

import java.util.*;

public class MapDemo {
    public static void main(String[] args) {
        Map<String, Integer> maps = new HashMap<>();
        maps.put("iPhone14", 10000);
        maps.put("HUAWEI mate50", 6000);
        maps.put("JAVA从入门到入土", 50);
        maps.put("xiaomi13", 4500);
        System.out.println(maps);

        // 把map集合转换成set集合,map集合的元素是键值没有类型,foreach遍历不了,可以通过entrySet()转换成键值对类型然后foreach遍历
        Set<Map.Entry<String, Integer>> entries = maps.entrySet();
        // 开始遍历
        for(Map.Entry<String, Integer> entry : entries) {
            String key = entry.getKey();
            int value = entry.getValue();
            System.out.println(key + " ==> " + value);
        }
    }
}

Map集合遍历方式三:Lambda

在这里插入图片描述

package com.mochu.d5_map;

import java.util.*;
import java.util.function.BiConsumer;

public class MapDemo {
    public static void main(String[] args) {
        Map<String, Integer> maps = new HashMap<>();
        maps.put("iPhone14", 10000);
        maps.put("HUAWEI mate50", 6000);
        maps.put("JAVA从入门到入土", 50);
        maps.put("xiaomi13", 4500);
        System.out.println(maps);

        maps.forEach(new BiConsumer<String, Integer>() {
            @Override
            public void accept(String key, Integer value) {
                System.out.println(key + " ==> " + value);
            }
        });
        // 简化
        maps.forEach((key, value) -> {
            System.out.println(key + " ==> " + value);
        });
    }
}

Map集合案例、其他实现类

在这里插入图片描述

package com.mochu.d6_map_test;

import java.util.HashMap;
import java.util.Map;
import java.util.Random;

public class MapTest1 {
    public static void main(String[] args) {
        String[] selects = {"A", "B", "C", "D"};
        StringBuilder sb = new StringBuilder();
        Random rd = new Random();
        for (int i = 0; i < 80; i++) {
            sb.append(selects[rd.nextInt(selects.length)]);
        }
        System.out.println(sb);
        // 统计结果,封装成键值对
        Map<Character, Integer> infos = new HashMap<>();
        // 遍历80个学生选择数据
        for (int i = 0; i < sb.length(); i++) {
            // 提取当前选择的经典字符
            char ch = sb.charAt(i);
            // 判断Map集合中是否存在这个值
            if(infos.containsKey(ch)) {
                infos.put(ch, infos.get(ch) + 1);
            }else {
                // 第一次选择该经典
                infos.put(ch, 1);
            }
        }
        System.out.println(infos);
    }
}

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

Map集合的实现类LinkedHashMap

在这里插入图片描述

Map集合的实现类:TreeMap

在这里插入图片描述
在这里插入图片描述

集合嵌套

在这里插入图片描述

package com.mochu.d6_map_test;

import java.util.*;

public class MapTest1 {
    public static void main(String[] args) {
        // 记录每个学生选择的情况,使用Map集合
        Map<String, List<String>> data = new HashMap<>();

        List<String> selects = new ArrayList<>();
        Collections.addAll(selects, "A", "C");
        data.put("甲", selects);

        List<String> selects1 = new ArrayList<>();
        Collections.addAll(selects1, "B", "C", "D");
        data.put("乙", selects1);

        List<String> selects2 = new ArrayList<>();
        Collections.addAll(selects2, "A", "B", "C", "D");
        data.put("丙", selects2);
        System.out.println(data);

        // 统计每个景点选择的人数
        Map<String, Integer> infos = new HashMap<>();
        Collection<List<String>> values = data.values();
        for (List<String> value : values) {
            for (String s : value) {
                // 判断是否包含景点
                if(infos.containsKey(s)) {
                    infos.put(s, infos.get(s) + 1);
                }else {
                    infos.put(s, 1);
                }
            }
        }
        System.out.println(infos);
    }
}

在这里插入图片描述

创建不可变集合

什么是不可变集合?

  • 不可变集合,就是不可被修改的集合
  • 集合的数据项在创建的时候提供,并且在整个生命周期中都不可改变,否则报错

在这里插入图片描述

package com.mochu.d1_unchange_collection;

import java.util.List;
import java.util.Map;
import java.util.Set;

public class CollectionDemo {
    public static void main(String[] args) {
        // 不可变list集合
        List<Integer> lists = List.of(10, 20, 30, 40, 50);
        // lists.add(11); // 不能添加,否则报错
        // lists.set(2, 22); // 不能修改,否则报错
        System.out.println(lists.get(1));

        // 不可变set集合
        Set<String> names = Set.of("Mochu7", "Slevin", "Shinn");
        // names.add("test");
        System.out.println(names);

        // 不可变的map集合
        Map<String, Integer> maps = Map.of("iPhone14", 10000, "HUAWEI mate50", 5000);
        // maps.put("JAVA从入门到入土", 50);
        System.out.println(maps);
    }
}

Stream流体系

什么是Stream流?

  • 在Java8中,得益于Lambda所带来的函数式编程,引入了一个全新的Stream流概念
  • 目的:用于简化集合和数组操作的API

在这里插入图片描述

package com.mochu.d2_stream;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

public class StreamTest {
    public static void main(String[] args) {
        List<String> names = new ArrayList<>();
        Collections.addAll(names, "张三丰", "张无忌", "周芷若", "赵敏", "张强");
        System.out.println(names);

        // 从集合中找出姓张的放到一个新的集合
        List<String> zhangList = new ArrayList<>();
        for (String name : names) {
            if(name.startsWith("张")) {
                zhangList.add(name);
            }
        }
        System.out.println(zhangList);

        // 找名称长度为3的
        List<String> zhangThreeList = new ArrayList<>();
        for(String name : names) {
            if(name.length() == 3) {
                zhangThreeList.add(name);
            }
        }
        System.out.println(zhangThreeList);

        // 使用Stream实现
        names.stream().filter(s -> s.startsWith("张")).filter(s -> s.length() == 3).forEach(s -> System.out.println(s));
    }
}

在这里插入图片描述
在这里插入图片描述

Stream流的获取

Stream流的三类方法:

  • 获取Stream流
    – 创建一条流水线,并把数据放到流水线上准备进行操作
  • 中间方法
    – 流水线上操作。一次操作完毕之后,还可以继续进行其他操作
  • 终结方法
    – 一个Stream流只能由一个终结方法,是流水线上的最后一个操作

在这里插入图片描述

package com.mochu.d2_stream;

import java.util.*;
import java.util.stream.Stream;

public class StreamDemo {
    public static void main(String[] args) {
        // Collection获取Stream流
        Collection<String> list = new ArrayList<>();
        Stream<String> s = list.stream();

        // Map集合获取流
        Map<String, Integer> map = new HashMap<>();
        Stream<String> keyStream = map.keySet().stream(); // 键流
        Stream<Integer> valueStream = map.values().stream(); // 值流
        Stream<Map.Entry<String, Integer>> keyAndValueStream = map.entrySet().stream(); // 键值对流

        // 数组获取流
        String[] names = {"mochu7", "slevin", "shinn"};
        Stream<String> nameStream = Arrays.stream(names);

        Stream<String> nameStream2 = Stream.of(names);
    }
}

Stream流常用的API

在这里插入图片描述

package com.mochu.d2_stream;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.function.Function;
import java.util.function.Predicate;
import java.util.stream.Stream;

public class StreamDemo01 {
    public static void main(String[] args) {
        List<String> list = new ArrayList<>();
        Collections.addAll(list, "mochu7", "Slevin", "Shinn", "末初");
//        list.stream().filter(new Predicate<String>() {
//            @Override
//            public boolean test(String s) {
//                return s.startsWith("S");
//            }
//        });
        // 简化
        list.stream().filter(s -> s.startsWith("S")).forEach(s -> System.out.println(s));

        long size = list.stream().filter(s -> s.length() == 5).count();
        System.out.println(size);

        list.stream().filter(s -> s.startsWith("S")).limit(2).forEach(s -> System.out.println(s));
        list.stream().filter(s -> s.startsWith("S")).limit(2).forEach(System.out::println);

        list.stream().filter(s -> s.startsWith("S")).skip(2).forEach(System.out::println);

        // Map加工方法,在每个元素前加个前缀
        list.stream().map(new Function<String, String>() {
            @Override
            public String apply(String s) {
                return "名称:" + s;
            }
        });

        list.stream().map(s -> "名称:" + s).forEach(s -> System.out.printf(s));

        // 把所有名称加工成一个学生对象
        list.stream().map(s -> new Student(s)).forEach(s -> System.out.println(s));
        // list.stream().map(Student::new).forEach(System.out::println); // 构造器引用 方法引用

        // 合并流
        Stream<String> s1 = list.stream().filter(s -> s.startsWith("S"));
        Stream<String> s2 = Stream.of("Java", "Python");
        Stream<String> s3 = Stream.concat(s1, s2);
    }
}

终结方法和非终结方法的含义:终结方法后流不可以继续使用,非终结方法会返回新的流,支持链式编程

Stream流的综合应用

在这里插入图片描述

package com.mochu.d3_stream_app;

public class Employee {
    private String name;
    private char sex;
    private double salary;
    private double bouns;
    private String punish;

    public Employee() {
    }

    public Employee(String name, char sex, double salary, double bouns, String punish) {
        this.name = name;
        this.sex = sex;
        this.salary = salary;
        this.bouns = bouns;
        this.punish = punish;
    }

    public String getName() {
        return name;
    }

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

    public char getSex() {
        return sex;
    }

    public void setSex(char sex) {
        this.sex = sex;
    }

    public double getSalary() {
        return salary;
    }

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

    public double getBouns() {
        return bouns;
    }

    public void setBouns(double bouns) {
        this.bouns = bouns;
    }

    public String getPunish() {
        return punish;
    }

    public void setPunish(String punish) {
        this.punish = punish;
    }

    @Override
    public String toString() {
        return "Employee{" +
                "name='" + name + '\'' +
                ", sex=" + sex +
                ", salary=" + salary +
                ", bouns=" + bouns +
                ", punish='" + punish + '\'' +
                '}';
    }
}
package com.mochu.d3_stream_app;

public class TopperFormer {
    private String name;
    private double salary;

    public TopperFormer() {
    }

    public TopperFormer(String name, double salary) {
        this.name = name;
        this.salary = salary;
    }

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

    @Override
    public String toString() {
        return "TopperFormer{" +
                "name='" + name + '\'' +
                ", salary=" + salary +
                '}';
    }
}
package com.mochu.d3_stream_app;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Stream;

public class StreamApp {
    public static double allMoney;
    public static double allMoney2; // 两个部门薪资总和

    public static void main(String[] args) {
        List<Employee> department1 = new ArrayList<>();
        department1.add(new Employee("希尔伯特·让·昂热", '男', 5000000, 1000000, "不听董事会命令"));
        department1.add(new Employee("莱昂纳多·弗拉梅尔", '男', 1000000, 500000, null));
        department1.add(new Employee("古德里安", '男', 500000, 200000, null));
        department1.add(new Employee("格尔德·鲁道夫·曼施坦因", '男', 200000, 100000, null));

        List<Employee> department2 = new ArrayList<>();
        department2.add(new Employee("路明非", '男', 1000000, 2000000, null));
        department2.add(new Employee("楚子航", '男', 80000, 100000, "血统存在龙化风险"));
        department2.add(new Employee("芬格尔", '男', 100000, 200000, null));
        department2.add(new Employee("凯撒·加图索", '男', 100000, 200000, "不听家族安排"));

        // 一部的员工最高工资
//        Employee e = department1.stream().max((e1, e2) -> Double.compare(e1.getSalary() + e1.getBouns(), e1.getSalary()+ e2.getBouns())).get();
//        System.out.println(e);
        TopperFormer top = department1.stream().max((e1, e2) -> Double.compare(e1.getSalary() + e1.getBouns(), e1.getSalary()+ e2.getBouns()))
                .map(e -> new TopperFormer(e.getName(), e.getSalary() + e.getBouns())).get();
        System.out.println(top);

        // 统计年均工资(去掉最高和最低工资)
        department1.stream().sorted((e1, e2) -> Double.compare(e1.getSalary() + e1.getBouns(), e1.getSalary()+ e2.getBouns())).
                skip(1).limit(department1.size() - 2).forEach(e -> {
                    // 求剩余员工薪资总和
                    allMoney += (e.getSalary() + e.getBouns());
                });
        System.out.println("Department1的平均薪资:" + allMoney / (department1.size() - 2));

        // 合并两个集合流,再统计
        Stream<Employee> s1 = department1.stream();
        Stream<Employee> s2 = department2.stream();
        Stream<Employee> s3 = Stream.concat(s1, s2);
        s3.sorted((e1, e2) -> Double.compare(e1.getSalary() + e1.getBouns(), e1.getSalary()+ e2.getBouns())).
                skip(1).limit(department1.size() + department2.size() - 2).forEach(e -> {
                    // 求剩余员工薪资总和
                    allMoney2 += (e.getSalary() + e.getBouns());
                });
        BigDecimal a = BigDecimal.valueOf(allMoney2);
        BigDecimal b = BigDecimal.valueOf(department1.size() + department2.size() - 2);
        System.out.println("两个部门的平均薪资:" + a.divide(b, 2, RoundingMode.HALF_UP));
    }
}

在这里插入图片描述

收集Stream流

Stream流的收集操作

  • 收集Stream流的含义:就是把Stream流操作后的结果数据转会到集合或者数组中去
  • Stream流:方便操作集合/数组的手段
  • 集合/数组:才是开发中的目的

在这里插入图片描述

package com.mochu.d3_stream_app;

import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 * 收集Stream流到集合或者数组中
 */
public class StreamDemo {
    public static void main(String[] args) {
        List<String> list = new ArrayList<>();
        Collections.addAll(list, "Mochu7", "Slevin", "Shinn");

        // 收集到list中
        Stream<String> s1 = list.stream().filter(s -> s.startsWith("S"));
        List<String> list1 = s1.collect(Collectors.toList());
        System.out.println(list1);

        // 收集到set中
        // 注意:流只能使用一次,使用完之后会关闭
        Stream<String> s2 = list.stream().filter(s -> s.startsWith("S"));
        Set<String> set = s2.collect(Collectors.toSet());
        System.out.println(set);

        // 收集到数组
        Stream<String> s3 = list.stream().filter(s -> s.startsWith("S"));
        Object[] arr = s3.toArray();
        System.out.println(Arrays.toString(arr));
    }
}

异常概述、体系

什么是异常?

  • 异常是程序在“编译”或者“执行”的过程中可能会出现的问题
  • 注意:语法错误不算在异常体系中
  • 异常一旦出现了,如果没有提前处理,程序就会退出JVM虚拟机而终止

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

常见运行时异常

在这里插入图片描述
在这里插入图片描述

异常的处理机制

编译时异常的处理机制

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

异常的强大演示、自定义异常

在这里插入图片描述

package com.mochu.d4_exception;

import java.util.Scanner;

public class ExceptionDemo {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        while(true) {
            try {
                System.out.println("请输入合法的价格:");
                String priceStr = sc.nextLine();
                // 转换成Double类型的价格
                double price = Double.valueOf(priceStr);

                // 判断价格是否大于0
                if(price > 0) {
                    System.out.println("定价:" + price);
                    break;
                }else {
                    System.out.println("价格必须为正数");
                }
            } catch (Exception e) {
                System.out.println("用户输入的数据有误,请重新输入");
            }
        }
    }
}

自定义异常

在这里插入图片描述
1、自定义编译时异常

  • 定义一个异常类继承Exception
  • 重写构造器
  • 在出现异常的地方用throw new自定义对象抛出
package com.mochu.d4_exception;

public class AgeIlleagalException extends Exception{
    public AgeIlleagalException() {

    }

    public AgeIlleagalException(String message) {
        super(message);
    }
}

2、自定义运行时异常

  • 定义一个异常类继承RuntimeException
  • 重写构造器
  • 在出现异常的地方用throw new自定义对象抛出
package com.mochu.d4_exception;

public class AgeIlleagalRuntimeException extends RuntimeException{
    public AgeIlleagalRuntimeException() {

    }

    public AgeIlleagalRuntimeException(String message) {
        super(message);
    }
}
package com.mochu.d4_exception;


public class ExceptionDemo {
    public static void main(String[] args) {
        // 需求:年龄小于0或者大于200就是异常

    }

    public static void checkAge(int age) throws AgeIlleagalException{
        if(age < 0 || age > 200) {
            // 抛出异常对象给调用者
            // throw:在方法内部直接创建一个异常对象,并从此点抛出
            // throws:用在方法声明上的,抛出方法内部的异常
            throw new AgeIlleagalException(age + "瞎搞");
            // throw new AgeIlleagalRuntimeException(age + "瞎搞");
        }else {
            System.out.println("年龄合法");
        }
    }
}

日志概述、日志技术体系

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
Logback日志框架:

  • logback是由log4j创始人设计的另一个开源日志组件,性能比log4j要好
  • 官方网站:https://logback.qos.ch/index.html
  • Logback是基于slf4j的日志规范实现的框架

Logback主要分为三个技术模块:

  • logback-core:logback-core模块为其他两个模块奠定了基础,必须有
  • logback-classic:它是log4j的一个改良版本,同时它完整的实现了slf4j API
  • logback-access:模块与Tomcat和Jetty等Servlet容器集成,以提供HTTP访问日志功能

Logback日志框架的快速入门、日志级别设置等

首先需要导入Logback日志技术到项目中,用于记录系统的日志信息

  1. 在项目下新建文件夹lib,导入Logback的相关jar包到该文件夹下,并添加到项目依赖库中去。

Logback jar包的下载:https://www.cnblogs.com/yumengqifei/p/16407919.html

在这里插入图片描述
然后全部选中,右键Add as Library

在这里插入图片描述

  1. 将Logback的核心配置文件logback.xml直接拷贝到src目录下
    logback.xml
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
    <!--定义日志文件的存储地址 勿在 LogBack 的配置中使用相对路径-->
    <property name="LOG_HOME" value="D:/Java/log" />
    <!-- 控制台输出 -->
    <appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
        <!-- 日志输出编码 -->
        <Encoding>UTF-8</Encoding>
        <layout class="ch.qos.logback.classic.PatternLayout">
            <!--格式化输出:%d表示日期,%thread表示线程名,%-5level:级别从左显示5个字符宽度%msg:日志消息,%n是换行符-->
            <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n
            </pattern>
        </layout>
    </appender>
    <!-- 按照每天生成日志文件 -->
    <appender name="FILE"  class="ch.qos.logback.core.rolling.RollingFileAppender">
        <Encoding>UTF-8</Encoding>
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <!--日志文件输出的文件名-->
            <FileNamePattern>${LOG_HOME}/myApp.log.%d{yyyy-MM-dd}.log</FileNamePattern>
            <MaxHistory>30</MaxHistory>
        </rollingPolicy>
        <layout class="ch.qos.logback.classic.PatternLayout">
            <!--格式化输出:%d表示日期,%thread表示线程名,%-5level:级别从左显示5个字符宽度%msg:日志消息,%n是换行符-->
            <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n
            </pattern>
        </layout>
        <!--日志文件最大的大小-->
        <triggeringPolicy class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy">
            <MaxFileSize>1MB</MaxFileSize>
        </triggeringPolicy>
    </appender>
 
    <!-- 日志输出级别 -->
    <root level="ALL">
        <appender-ref ref="CONSOLE" />
        <appender-ref ref="FILE" />
    </root>
 
</configuration>

在这里插入图片描述

  1. 在代码中获取日志对象

public static final Logger LOGGER = LoggerFactory.getLogger("类对象");

package com.mochu.logback;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * 快速搭建Logback日志框架,记录程序执行情况到文件中
 */
public class Test {
    // 创建Logback的日志对象
    public static final Logger LOGGER = LoggerFactory.getLogger("Test.class");
    public static void main(String[] args) {
        try {
            LOGGER.debug("main方法开始执行");
            LOGGER.info("我开始记录第二行日志");
            int a = 10;
            int b = 0;
            LOGGER.trace("a=" + a);
            LOGGER.trace("b=" + b);
            System.out.println(a / b);
        } catch (Exception e) {
            e.printStackTrace();
            LOGGER.error("功能出现异常" + e);
        }
    }
}

在这里插入图片描述

Logback配置详解-输出位置、格式位置

Logback日志输出位置、格式设置

  • 通过logback.xml中的<append>标签可以设置输出位置和日志信息的详细格式
  • 通常可以设置2个日志输出位置:一个是控制台、一个是系统文件

输出到控制台的配置:<appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
输出到系统文件的配置:<appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">

Logback配置详解-日志级别设置

日志级别:

  • 级别程度依次是:TRACE < DEBUG < INFO < WARN < ERROR;默认级别是debug(忽略大小写),对应其方法
  • 作用:用于控制系统中哪些日志级别是可以输出的,只输出级别不低于设定级别的日志信息
  • ALLOFF分别是打开全部日志信息,以及关闭全部日志信息
    <!-- 日志输出级别 -->
    <root level="ALL">
        <appender-ref ref="CONSOLE" />
        <appender-ref ref="FILE" />
    </root>

影院系统开发

日志框架搭建、系统角色分析、容器定义

在这里插入图片描述

首页、登录、商家界面、用户界面实现

在这里插入图片描述

商家功能:展示详情、影片上架、退出

在这里插入图片描述

影片下架、修改、展示排片信息、用户购票

在这里插入图片描述

用户功能-展示全部影片

在这里插入图片描述

用户功能-购票操作

在这里插入图片描述

package com.mochu.bean;

public class Business extends User{
    private String shopName; // 店铺名称
    private String address; // 店铺地址

    public String getShopName() {
        return shopName;
    }

    public void setShopName(String shopName) {
        this.shopName = shopName;
    }

    public String getAddress() {
        return address;
    }

    public void setAddress(String address) {
        this.address = address;
    }
}
package com.mochu.bean;

/**
 * 客户类
 */
public class Customer extends User{
}
package com.mochu.bean;

import java.util.Date;

public class Movie {
    private String name;
    private String actor;
    private double score;
    private double time;
    private double price;
    private int number; // 余票
    private Date startTime; // 上映时间

    public Movie() {
    }

    public Movie(String name, String actor, double time, double price, int number, Date startTime) {
        this.name = name;
        this.actor = actor;
        this.score = score;
        this.time = time;
        this.price = price;
        this.number = number;
        this.startTime = startTime;
    }

    public String getName() {
        return name;
    }

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

    public String getActor() {
        return actor;
    }

    public void setActor(String actor) {
        this.actor = actor;
    }

    public double getScore() {
        return score;
    }

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

    public double getTime() {
        return time;
    }

    public void setTime(double time) {
        this.time = time;
    }

    public double getPrice() {
        return price;
    }

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

    public int getNumber() {
        return number;
    }

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

    public Date getStartTime() {
        return startTime;
    }

    public void setStartTime(Date startTime) {
        this.startTime = startTime;
    }
}
package com.mochu.bean;

/**
 * 用户类(客户和商家的父类)
 */
public class User {
    private String loginName;
    private String userName;
    private String passWord;
    private char sex;
    private String phone;
    private double money;

    public User() {
    }

    public User(String loginName, String userName, String passWord, char sex, String phone, double money) {
        this.loginName = loginName;
        this.userName = userName;
        this.passWord = passWord;
        this.sex = sex;
        this.phone = phone;
        this.money = money;
    }

    public String getLoginName() {
        return loginName;
    }

    public void setLoginName(String loginName) {
        this.loginName = loginName;
    }

    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 char getSex() {
        return sex;
    }

    public void setSex(char sex) {
        this.sex = sex;
    }

    public String getPhone() {
        return phone;
    }

    public void setPhone(String phone) {
        this.phone = phone;
    }

    public double getMoney() {
        return money;
    }

    public void setMoney(double money) {
        this.money = money;
    }
}
package com.mochu.run;

import com.mochu.bean.Business;
import com.mochu.bean.Customer;
import com.mochu.bean.Movie;
import com.mochu.bean.User;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.math.BigDecimal;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;


public class MovieSystem {
    // 存储用户数据的容器
    public static final List<User> ALL_USERS = new ArrayList<>();
    // 商家信息容器
    public static final Map<Business, List<Movie>> ALL_MOVIES = new HashMap<>();
    // 扫描器对象
    public static final Scanner SYS_SC = new Scanner(System.in);
    // 静态的用户变量,记录当前登陆成功的对象
    public static User loginUser;
    public static SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss");
    public static final Logger LOGGER= LoggerFactory.getLogger("MovieSystem.class");


    // 利用静态代码块加载一些测试数据
    static {
        Customer c = new Customer();
        c.setLoginName("mochu7");
        c.setPassWord("mochu777");
        c.setUserName("末初");
        c.setSex('男');
        c.setMoney(10000);
        c.setPhone("18888888888");
        ALL_USERS.add(c);

        Customer c1 = new Customer();
        c1.setLoginName("Slevin");
        c1.setPassWord("123456");
        c1.setUserName("斯莱文");
        c1.setSex('男');
        c1.setMoney(100000);
        c1.setPhone("17777777777");
        ALL_USERS.add(c1);

        Business b = new Business();
        b.setLoginName("Shinn");
        b.setPassWord("Shinn888");
        b.setUserName("楚末");
        b.setMoney(0);
        b.setSex('男');
        b.setPhone("16666666666");
        b.setAddress("银河太阳系地球星光大道1号");
        b.setShopName("星河国际影城");
        ALL_USERS.add(b);
        List<Movie> movies = new ArrayList<>();
        ALL_MOVIES.put(b, movies);

        Business b1 = new Business();
        b1.setLoginName("movoc");
        b1.setPassWord("movoc777");
        b1.setUserName("莫莫扣");
        b1.setMoney(0);
        b1.setSex('女');
        b1.setPhone("15555555555");
        b1.setAddress("银河太阳系地球银河大道8号");
        b1.setShopName("银河国际影城");
        ALL_USERS.add(b1);
        List<Movie> movies1 = new ArrayList<>();
        ALL_MOVIES.put(b1, movies1);
    }

    public static void main(String[] args) {
        showMain();
    }

    /**
     * 首页展示
     */
    private static void showMain() {
        while (true) {
            System.out.println("=======================电影首页=======================");
            System.out.println("1、登录:");
            System.out.println("2、用户注册:");
            System.out.println("3、商家注册:");
            System.out.println("请输入操作命令:");
            String command = SYS_SC.nextLine();
            switch(command) {
                case "1":
                    login();
                    break;
                case "2":
                    break;
                case "3":
                    break;
                default:
                    System.out.println("命令有误,请重新确认");
            }
        }


    }

    /**
     * 登录功能
     */
    private static void login() {
        while (true) {
            System.out.println("请输入登录名称:");
            String loginName = SYS_SC.nextLine();
            System.out.println("请输入用户密码:");
            String passWord = SYS_SC.nextLine();

            User u = getUserByLoginName(loginName);
            if(u != null) {
                // 登录名核验成功
                if(u.getPassWord().equals(passWord)) {
                    // 登录成功,判断用户还是商家
                    loginUser = u;
                    LOGGER.info(u.getUserName() + "登录系统");
                    if(u instanceof Customer) {
                        // 普通用户
                        showCustomerMain();
                    }else {
                        // 商家
                        showBusinessMain();
                    }
                    // 结束login
                    return;
                }else {
                    System.out.println("密码错误");
                }
            }else {
                System.out.println("登录名称错误");
            }
        }
    }

    /**
     * 商家页面
     */
    private static void showBusinessMain() {
        while(true) {
            System.out.println("=======================商家页面=======================");
            System.out.println(loginUser.getUserName() + (loginUser.getSex() == '男' ? "先生" : "女士") + "欢迎您~");
            System.out.println("1. 展示详情:");
            System.out.println("2. 上架电影:");
            System.out.println("3. 下架电影:");
            System.out.println("4. 修改电影:");
            System.out.println("5. 退出系统:");
            System.out.println("请输入你要操作的命令:");
            String command = SYS_SC.nextLine();
            switch(command) {
                case "1":
                    // 展示商家详细信息
                    showBusinessInfos();
                    break;
                case "2":
                    // 上架电影
                    addMovie();
                    break;
                case "3":
                    // 下架电影
                    deleteMovie();
                    break;
                case "4":
                    // 修改电影
                    updateMovie();
                    break;
                case "5":
                    System.out.println(loginUser.getUserName() + (loginUser.getSex() == '男' ? "先生" : "女士") + "感谢您的使用~");
                    // 退出系统
                    return;
                default:
                    System.out.println("命令有误,请重新输入");
            }
        }
    }

    /**
     * 修改影片
     */
    private static void updateMovie() {
        System.out.println("=======================修改电影=======================");
        Business business = (Business) loginUser;
        List<Movie> movies = ALL_MOVIES.get(business);
        if(movies.size() == 0) {
            System.out.println("当前没有影片可以修改");
            return;
        }

        while (true) {
            System.out.println("请输入需要修改的电影名称:");
            String movieName = SYS_SC.nextLine();
            // 根据电影名称查询是否有这个电影对象
            Movie movie = getMovieByName(movieName);
            if(movie != null) {
                System.out.println("请输入修改后的电影名称:");
                String name = SYS_SC.nextLine();
                System.out.println("请输入修改后的电影主演:");
                String actor = SYS_SC.nextLine();
                System.out.println("请输入修改后的电影时长:");
                String time = SYS_SC.nextLine();
                System.out.println("请输入修改后的电影票价:");
                String price = SYS_SC.nextLine();
                System.out.println("请输入修改后的电影票数:");
                String totalNumber = SYS_SC.nextLine();
                while (true) {
                    try {
                        System.out.println("请输入修改后的电影放映时间:");
                        String startTime = SYS_SC.nextLine();
                        movie.setName(name);
                        movie.setActor(actor);
                        movie.setTime(Double.valueOf(time));
                        movie.setPrice(Double.valueOf(price));
                        movie.setNumber(Integer.valueOf(totalNumber));
                        movie.setStartTime(sdf.parse(startTime));
                        System.out.println("电影修改成功");
                        showBusinessInfos();
                        return;
                    } catch (Exception e) {
                        e.printStackTrace();
                        LOGGER.error("时间解析出错");
                    }
                }
            }else {
                System.out.println("您的店铺没有上架该影片");
                System.out.println("是否继续下架?y/n");
                String command = SYS_SC.nextLine();
                switch(command) {
                    case "y":
                        break;
                    default:
                        System.out.println("ok");
                        return;
                }
            }
        }

    }

    /**
     * 影片下架
     */
    private static void deleteMovie() {
        System.out.println("=======================下架电影=======================");
        Business business = (Business) loginUser;
        List<Movie> movies = ALL_MOVIES.get(business);
        if(movies.size() == 0) {
            System.out.println("当前没有影片可以下架");
            return;
        }

        while (true) {
            System.out.println("请输入需要下架的电影名称:");
            String movieName = SYS_SC.nextLine();
            // 根据电影名称查询是否有这个电影对象
            Movie movie = getMovieByName(movieName);
            if(movie != null) {
                movies.remove(movie);
                System.out.println("您的店铺已经成功下架了:" + movie.getName());
                showBusinessInfos();
                return;
            }else {
                System.out.println("您的店铺没有上架该影片");
                System.out.println("是否继续下架?y/n");
                String command = SYS_SC.nextLine();
                switch(command) {
                    case "y":
                        break;
                     default:
                        System.out.println("ok");
                        return;
                }
            }
        }
    }

    /**
     * 根据名称查询影片对象
     * @param movieName
     * @return
     */
    public static Movie getMovieByName(String movieName) {
        Business business = (Business) loginUser;
        List<Movie> movies = ALL_MOVIES.get(business);
        for(Movie movie : movies) {
            if(movie.getName().contains(movieName)) {
                return movie;
            }
        }
        return null;
    }

    /**
     * 商家电影添加
     */
    private static void addMovie() {
        System.out.println("=======================商家电影=======================");
        Business business = (Business) loginUser;
        List<Movie> movies = ALL_MOVIES.get(loginUser);
        System.out.println("请输入电影名称:");
        String name = SYS_SC.nextLine();
        System.out.println("请输入电影主演:");
        String actor = SYS_SC.nextLine();
        System.out.println("请输入电影时长:");
        String time = SYS_SC.nextLine();
        System.out.println("请输入电影票价:");
        String price = SYS_SC.nextLine();
        System.out.println("请输入电影票数:");
        String totalNumber = SYS_SC.nextLine();
        while (true) {
            try {
                System.out.println("请输入电影放映时间:");
                String startTime = SYS_SC.nextLine();
                //  Movie(String name, String actor, double time, double price, int number, Date startTime)
                Movie movie = new Movie(name, actor, Double.valueOf(time), Double.valueOf(price), Integer.valueOf(totalNumber), sdf.parse(startTime));
                movies.add(movie);
                System.out.println("电影上架成功");
                return;
            } catch (ParseException e) {
                e.printStackTrace();
                LOGGER.error("时间解析出错");
            }
        }
    }

    /**
     * 展示商家信息
     */
    private static void showBusinessInfos() {
        System.out.println("=======================商家详情=======================");
        LOGGER.info(loginUser.getUserName() + "商家展示详情");
        // 根据商家对象作为Map集合的键,提取对应的影片信息:Map<Busines, List<Movie>>
        // loginUser就是当前登录用户
        Business business = (Business) loginUser;
        System.out.println("店铺:" + business.getShopName() + "\t\t电话:" + business.getPhone() + "\t\t地址:" + business.getAddress() + "\t\t余额:" + business.getMoney());
        List<Movie> movies = ALL_MOVIES.get(loginUser);
        System.out.println("片名\t\t\t主演\t\t时长\t\t评分\t\t票价\t\t余票数量\t\t上映时间");
        if (movies.size() > 0) {
            for(Movie movie : movies) {
                System.out.println(movie.getName() + "\t\t\t" + movie.getActor() + "\t\t" + movie.getTime() + "\t\t" + movie.getScore() +
                        "\t\t" + movie.getPrice() + "\t\t" + movie.getNumber() + "\t\t" + sdf.format(movie.getStartTime()));
            }
        }else {
            System.out.println("您的店铺当前没有电影上架");
        }

    }

    /**
     * 客户页面
     */
    private static void showCustomerMain() {
        while(true) {
            System.out.println("=======================客户页面=======================");
            System.out.println(loginUser.getUserName() + (loginUser.getSex() == '男' ? "先生" : "女士") + "欢迎您~" + "\t\t余额:" + loginUser.getMoney());
            System.out.println("1. 展示全部影片信息功能:");
            System.out.println("2. 根据电影名称查询电影信息:");
            System.out.println("3. 评分功能:");
            System.out.println("4. 购票功能:");
            System.out.println("5. 退出系统:");
            System.out.println("请输入你要操作的命令:");
            String command = SYS_SC.nextLine();
            switch(command) {
                case "1":
                    // 展示全部影片信息
                    showAllMovies();
                    break;
                case "2":
                    // 根据影片名查询信息
                    break;
                case "3":
                    // 评分
                    break;
                case "4":
                    // 购票
                    buyMovie();
                    break;
                case "5":
                    // 退出系统
                    // 结束showCustomerMain
                    return;
                default:
                    System.out.println("命令有误,请重新输入");
            }
        }
    }

    /**
     * 用户购票功能
     */
    private static void buyMovie() {
        showAllMovies();
        System.out.println("=======================用户购票=======================");
        while (true) {
            System.out.println("请您输入需要买票的门店:");
            String shopName = SYS_SC.nextLine();
            // 查询是否存在该商家
            Business business = getBusinessByShopName(shopName);
            if(business == null) {
                System.out.println("对不起,没有该店铺");
            }else {
                // 商家全部排片
                List<Movie> movies = ALL_MOVIES.get(business);
                // 判断是否存在上映的电影
                if(movies.size() > 0) {
                // 选片
                    while (true) {
                        System.out.println("请输入需要购买电影的名称:");
                        String movieName = SYS_SC.nextLine();
                        // 在当前商家下,查询电影
                        Movie movie = getMovieByShopAndName(business, movieName);
                        if(movie != null) {
                            // 开始购买
                            while (true) {
                                System.out.println("请您输入要购买的电影票数:");
                                String number = SYS_SC.nextLine();
                                int buyNumber = Integer.valueOf(number);
                                // 判断电影是否购票
                                if(movie.getNumber() >= buyNumber) {
                                    double money = BigDecimal.valueOf(movie.getPrice()).multiply(BigDecimal.valueOf(buyNumber)).doubleValue();
                                    if(loginUser.getMoney() >= money) {
                                        // 钱够了,可以买票了
                                        System.out.println("您成功购买了" + movie.getName() + "的影票 " + buyNumber + "张,总金额是:" + money);
                                        // 更新自己和商家金额
                                        loginUser.setMoney(loginUser.getMoney() - money);
                                        business.setMoney(business.getMoney() + money);
                                        movie.setNumber(movie.getNumber() - buyNumber);
                                        return;
                                    }else {
                                        // 钱不够
                                        System.out.println("是否继续买票?y/n");
                                        String command = SYS_SC.nextLine();
                                        switch(command) {
                                            case "y":
                                                break;
                                            default:
                                                System.out.println("感谢光临" + shopName);
                                                return;
                                        }
                                    }
                                }else {
                                    System.out.println("您当前最多可以购买:" + movie.getNumber());
                                    System.out.println("是否继续买票?y/n");
                                    String command = SYS_SC.nextLine();
                                    switch(command) {
                                        case "y":
                                            break;
                                        default:
                                            System.out.println("感谢光临" + shopName);
                                            return;
                                    }
                                }
                            }
                        }else {
                            System.out.println("您输入的电影名称有误");
                        }
                    }
                }else {
                    System.out.println("该影院暂时没有上架的影片");
                    System.out.println("是否继续买票?y/n");
                    String command = SYS_SC.nextLine();
                    switch(command) {
                        case "y":
                            break;
                        default:
                            System.out.println("感谢光临" + shopName);
                            return;
                    }
                }
            }
        }

    }

    /**
     * 根据商家查询电影是否存在
     * @param business
     * @param name
     * @return
     */
    public static Movie getMovieByShopAndName(Business business, String name) {
        List<Movie> movies = ALL_MOVIES.get(business);
        for (Movie movie : movies) {
            if(movie.getName().contains(name)) {
                return movie;
            }
        }
        return null;
    }

    /**
     * 根据店铺名称查询商家对象
     * @return
     */
    public static Business getBusinessByShopName(String shopName){
        Set<Business> businesses = ALL_MOVIES.keySet();
        for (Business business : businesses) {
            if(business.getShopName().equals(shopName)) {
                return business;
            }
        }
        return null;
    }

    /**
     * 展示所有商家排片信息
     */
    private static void showAllMovies() {
        System.out.println("=======================商家排片=======================");
        ALL_MOVIES.forEach(((business, movies) -> {
            System.out.println("店铺:" + business.getShopName() + "\t\t电话:" + business.getPhone() + "\t\t地址:" + business.getAddress());
            System.out.println("片名\t\t\t主演\t\t时长\t\t评分\t\t票价\t\t余票数量\t\t上映时间");
                for(Movie movie : movies) {
                    System.out.println(movie.getName() + "\t\t\t" + movie.getActor() + "\t\t" + movie.getTime() + "\t\t" + movie.getScore() +
                            "\t\t" + movie.getPrice() + "\t\t" + movie.getNumber() + "\t\t" + sdf.format(movie.getStartTime()));
                }
        }));
        return;
    }

    public static User getUserByLoginName(String loginName) {
        for (User user : ALL_USERS) {
            if(user.getLoginName().equals(loginName)) {
                return user;
            }
        }
        return null;
    }
}

在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

末初mochu7

你的鼓励将是我创作的最大动力

¥2 ¥4 ¥6 ¥10 ¥20
输入1-500的整数
余额支付 (余额:-- )
扫码支付
扫码支付:¥2
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值