1200字范文,内容丰富有趣,写作的好帮手!
1200字范文 > 黑马程序员Java教程学习笔记(五)

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

时间:2023-09-03 05:36:03

相关推荐

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

学习视频:/video/BV1Cv411372m

如侵权,请私信联系本人删除

文章目录

黑马程序员Java教程学习笔记(五)日期时间:Date、SimpleDateFormat、CalendarJDK8开始新增日期API包装类正则表达式Arrays类选择排序、二分查找Lambda表达式集合概述、Collection集合的体系特点Collection常用API、遍历方式、存储自定义类型对象常见数据结构List系列集合、集合的并发修改异常问题泛型深入、自定义泛型、泛型通配符、上下限Set系列集合、Collection体系的总结可变参数、集合操作的工具类Collections斗地主游戏Map集合概述、API、遍历方式Map集合案例、其他实现类集合嵌套创建不可变集合Stream流体系异常概述、体系异常的处理机制异常的强大演示、自定义异常日志概述、日志技术体系Logback日志框架的快速入门、日志级别设置等影院系统开发

黑马程序员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 = "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 = "-11-11 00:00:00";String endTime = "-11-11 00:10:00";String xiaoJia = "-11-11 00:03:47";String xiaoPi = "-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(, 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 = "-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(, 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(, 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 parator;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>() {@Overridepublic 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>() {@Overridepublic int compare(Student o1, Student o2) {// 制定比较规则// return o1.getAge() - o2.getAge(); // 按照年龄升序排序// return o2.getAge() - o1.getAge(); // 按照年龄降序// return pare(o1.getHeight(), o2.getHeight()); // 按照身高升序return pare(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>() {@Overridepublic 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循环 foreachfor(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集合去重的原因:先判断哈希值再判断equalsStudent 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;}@Overridepublic 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);}@Overridepublic int hashCode() {return Objects.hash(name, age, gender);}@Overridepublic 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 parator;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>() {@Overridepublic int compare(Apple o1, Apple o2) {// 降序// return o2.getWeight() - o1.getWeight();// 价格比较(降序),浮点型使用parereturn pare(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;}@Overridepublic String toString() {return "Apple{" +"name='" + name + '\'' +", price=" + price +", color='" + color + '\'' +", weight=" + weight +'}';}/*** 第一种比较方式:类自定义比较方法* @param o* @return*/@Overridepublic 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;}@Overridepublic String toString() {return size + color;}}

package com.mochu.d4_game;import java.util.ArrayList;import java.util.Collections;import parator;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>() {@Overridepublic 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>() {@Overridepublic 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;}@Overridepublic 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;}@Overridepublic 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) -> pare(e1.getSalary() + e1.getBouns(), e1.getSalary()+ e2.getBouns())).get();// System.out.println(e);TopperFormer top = department1.stream().max((e1, e2) -> pare(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) -> pare(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) -> pare(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);// 判断价格是否大于0if(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.htmlLogback是基于slf4j的日志规范实现的框架

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

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

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

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

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

Logback jar包的下载:/yumengqifei/p/16407919.html

然后全部选中,右键Add as Library

将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>

在代码中获取日志对象

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();}// 结束loginreturn;}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":// 退出系统// 结束showCustomerMainreturn;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;}}

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。