uacs2024

导航

Java基础2

Exception 异常

ExceptionDemo1.java  时间日期异常、文件异常

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.InputStream;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;

public class ExceptionDemo1{
    public static void main(String[] args){
        try {
            //监视代码,出现异常,会被catch拦截住这个异常
            show2();
        } catch (ParseException e) {
            e.printStackTrace();// 打印异常信息
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }
    }

    private static void show2() throws ParseException, FileNotFoundException {
        System.out.println("-----show2() run-----");
        //编译异常:编译阶段报错,编译不通过。
        String str = "2024-07-29 11:45:14";//定义时间字符串str,格式为"yyyy-MM-dd HH:mm:ss"。
        //把字符串时间解析成Java中的一个日期对象。
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");//创建SimpleDateFormat对象sdf,指定与字符串匹配的格式//sdf.parse() 将字符串 "2024-07-29 11:45:14" 转换为 Date 对象(内部存储为时间戳)
        //java.util.Date 对象的 toString() 方法会返回一个固定格式的字符串: "EEE MMM dd HH:mm:ss zzz yyyy"
        //EEE:星期缩写(如 Mon)
        //MMM:月份缩写(如 Jul)
        //zzz:时区(如 CST,中国标准时间)
        Date date = sdf.parse(str);//编译时异常,提醒这里的程序很容易出错 //调用sdf.parse()方法将字符串解析为Date对象date(需处理ParseException异常)

        System.out.println(date);//Mon Jul 29 11:45:14 CST 2024

        InputStream is = new FileInputStream("D:/bafafbjzfka.png");

        System.out.println("-----show2() over-----");
    }
}

res

-----show2() run-----
Mon Jul 29 11:45:14 CST 2024
java.io.FileNotFoundException: D:\bafafbjzfka.png (系统找不到指定的文件。)
    at java.base/java.io.FileInputStream.open0(Native Method)
    at java.base/java.io.FileInputStream.open(FileInputStream.java:211)
    at java.base/java.io.FileInputStream.<init>(FileInputStream.java:153)
    at java.base/java.io.FileInputStream.<init>(FileInputStream.java:108)
    at com.itheima.demo1_exception.ExceptionDemo1.show2(ExceptionDemo1.java:39)
    at com.itheima.demo1_exception.ExceptionDemo1.main(ExceptionDemo1.java:14)

ExceptionDemo2.java

public class ExceptionDemo2 {
    public static void main(String[] args) {
        //异常是用来定位程序bug的关键信息,可以作为方法内部的一种特殊返回值,以便通知上层调用者,方法的执行问题
        //Exception,分为两类:编译时异常、运行时异常。
        //编译时异常:没有继承RuntimeException的异常,编译阶段就会出错。
        //运行时异常:继承自RuntimeException的异常或其子类,编译阶段不报错,运行时出现的
        System.out.println("main方法开始");
        try {
            int result = div(10, 0);
            System.out.println("div()执行成功");
        }
        catch (Exception e){
            System.out.println(e.getMessage());//除数不能为0
            e.printStackTrace();//红字打印异常信息
            System.out.println("div()执行失败");
        }
        System.out.println("main方法结束");
    }

    public static int div(int a, int b) throws Exception{
        if(b == 0){
            //System.out.println("除数不能为0");
            throw new Exception("除数不能为0");
        }
        int result = a / b;
        return result;
    }
}

res

main方法开始
除数不能为0
div()执行失败
main方法结束
java.lang.Exception: 除数不能为0
    at com.itheima.demo1_exception.ExceptionDemo2.div(ExceptionDemo2.java:25)
    at com.itheima.demo1_exception.ExceptionDemo2.main(ExceptionDemo2.java:11)

ExceptionDemo3.java

两种自定义异常。一种编译时异常,另一种运行时异常。

//Java无法为这个世界上全部的问题都提供异常类来代表,如果企业自己的某种问题想通过异常来表示,以便用异常来管理该问题,那就需要自己来定义异常类了
public class ExceptionDemo3 {
    public static void main(String[] args) { test1();test2(); }

    public static void test2(){
        //目标:认识自定义异常类
        System.out.println("test2()开始");
        try {
            saveAge2(500);
            System.out.println("saveAge2()执行成功");
        } catch (AgeRuntimeException e) {
            e.printStackTrace();
            System.out.println("年龄不合理");
        }
        System.out.println("test2()结束");
    }
    public static void test1(){
        //目标:认识自定义异常类
        System.out.println("test1()开始");
        try {
            saveAge(500);
            System.out.println("saveAge()执行成功");
        } catch (AgeException e) {
            e.printStackTrace();
            System.out.println("年龄不合理");
        }
        System.out.println("test1()结束");
    }

    //需求:我们公司的系统只要收到了年龄小于1岁或者大于200岁就是一个年龄非法异常
    public static void saveAge2(int age) throws AgeRuntimeException{
        if(age<1 || age>200){
            //自定义异常类
            throw new AgeRuntimeException("年龄非法异常");
        }else{
            System.out.println("年龄合法");
        }
    }

    //需求:我们公司的系统只要收到了年龄小于1岁或者大于200岁就是一个年龄非法异常
    public static void saveAge(int age) throws AgeException{
        if(age<1 || age>200){
            //自定义异常类
            throw new AgeException("年龄非法异常");
        }else{
            System.out.println("年龄合法");
        }
    }
}

//自定义 编译时异常类
//1.继承Exception类
//2.重写Exception类的构造方法
//3.哪里需要用这个异常返回,哪里就抛这个异常
class AgeException extends Exception {
    public AgeException() { }
    public AgeException(String message) { super(message); }
}

//自定义 运行时异常类
//1.继承RuntimeException类
//2.重写RuntimeException类的构造方法
//3.哪里需要用这个异常返回,哪里就抛这个异常
class AgeRuntimeException extends RuntimeException {
    public AgeRuntimeException() { }
    public AgeRuntimeException(String message) { super(message); }
}

res

test1()开始
年龄不合理
test1()结束
test2()开始
年龄不合理
test2()结束
com.itheima.demo1_exception.AgeException: 年龄非法异常
    at com.itheima.demo1_exception.ExceptionDemo3.saveAge(ExceptionDemo3.java:46)
    at com.itheima.demo1_exception.ExceptionDemo3.test1(ExceptionDemo3.java:23)
    at com.itheima.demo1_exception.ExceptionDemo3.main(ExceptionDemo3.java:5)
com.itheima.demo1_exception.AgeRuntimeException: 年龄非法异常
    at com.itheima.demo1_exception.ExceptionDemo3.saveAge2(ExceptionDemo3.java:36)
    at com.itheima.demo1_exception.ExceptionDemo3.test2(ExceptionDemo3.java:11)
    at com.itheima.demo1_exception.ExceptionDemo3.main(ExceptionDemo3.java:5)

ExceptionDemo5.java

package com.itheima.demo1_exception;
import java.util.Scanner;

public class ExceptionDemo5 {
    public static void main(String[] args) {
        //目标:掌握异常的处理方案  1: 底层异常都抛出去给最外层调用者,最外层捕获异常,记录异常,响应合适信息给用户观看。
        //                     2:捕获异常对象,尝试重新修复。
        // 接收用户的一个定价
        System.out.println("main()开始");
        while(true){
            try{
                double price = userInputPrice();
                System.out.println("正确输入价格");
                break;
            } catch (Exception e){
                //e.printStackTrace();
                System.out.println("价格输入有误,请重新输入");
            }
        }
        System.out.println("main()结束");
    }

    public static double userInputPrice() {
        // 1.接收用户的一个定价
        System.out.println("请输入一个价格:");
        Scanner sc = new Scanner(System.in);
        double price = sc.nextDouble();
        return price;
    }
}

 

Genericity 泛型

GenericDemo2.java  自定义list

import java.util.ArrayList;

public class GenericDemo2 {
    public static void main(String[] args) {
        //目标:学会自定义泛型类。
        //需求:请您模拟ArrayList集合自定义一个集合MyArrayList
        //MyArrayList<String> list = new MyArrayList<String>();
        MyArrayList<String> list = new MyArrayList<>();//JDK7 的新特性,可以省略掉<String>
        list.add("hello");
        list.add("world");
        for ( int i = 0; i < list.size(); i++){
            System.out.println(list.get(i));
        }
    }
}

class MyArrayList<E> {
    private E[] array;//array.length代表当前list占据多少空间
    private int size;//记录当前集合中有多少个有效的元素

    public MyArrayList() { array = (E[]) new Object[10]; }

    public int size() {return size;}

    public E get(int index) {
        if (index < 0 || index >= size) {
            throw new IndexOutOfBoundsException("OUT OF RANGE");
        }
        return array[index];
    }

    public void add(E e) {
        if (size == array.length) {
            E[] newArray = (E[]) new Object[array.length + 10];
            System.arraycopy(array, 0, newArray, 0, array.length);//第2个srcPos代表源阵列中的起始位置,第4个destPos代表目标数据中的起始位置
            array = newArray;
        }
        array[size++] = e;
    }
}

class MyArrayList2<E> {
    private ArrayList list = new ArrayList();
    public boolean add(E e) { return list.add(e); }
    public boolean remove(E e) { return list.remove(e); }

    @Override
    public String toString() { return list.toString(); }
}

 

泛型接口的基本作用

需要对学生数据进行增删改查操作

Data.java

public interface Data<T> {
    void add(T t);
    void delete(T t);
    void update(T t);
    T query(int id);
}

Student.java

public class Student { }

StudentData.java

public class StudentData implements Data<Student>{
    @Override
    public void add(Student student) { }

    @Override
    public void delete(Student student) { }

    @Override
    public void update(Student student) { }

    @Override
    public Student query(int id) { return null; }
}

 

泛型方法

GenericDemo4.java

public class GenericDemo4 {
    public static void main(String[] args) {
        //目标:学会定义泛型方法,搞清楚作用。
        //需求:打印任意数组的内容。
    }

    public static <T> void printArray(T[] arr) {
        for (T t : arr) {
            System.out.println(t);
        }
    }

    public static <T> T get(T[] arr, int index) { return arr[index]; }
}

 

GenericDemo5.java   泛型方法的通配符和上下符

import java.util.ArrayList;

public class GenericDemo5 {
    public static void main(String[] args) {
        //目标:理解通配符和上下限。
        //虽然Xiaomi和BYD是Car的子类,但是 ArrayList<Xiaomi> ArrayList<BYD>和 ArrayList<Car>是没有半毛钱关系
        ArrayList<Xiaomi> xiaomiList = new ArrayList<>();
        xiaomiList.add(new Xiaomi());
        xiaomiList.add(new Xiaomi());

        ArrayList<BYD> bydList = new ArrayList<>();
        bydList.add(new BYD());
        bydList.add(new BYD());

        ArrayList<Dog> dogList = new ArrayList<>();
        dogList.add(new Dog());
        dogList.add(new Dog());
    }

    //集合并不知道 对象之间是不是有继承关系,只知道是3个数据类型,而数据类型不一样
    //就是“?”可以在“使用泛型”的时候代表一切类型;ETKV是在定义泛型的时候使用
    //泛型上限:?extends Car:?能接收的必须是Car或者其子类。
    //泛型下限:?super Car:?能接收的必须是Car或者其父类。
    public static void go(ArrayList<? extends Car> cars){
        //限定泛型的使用,只能是Car或者Car的子类。防止Dog类也跑进来使用
    }
}

class Car{}
class Xiaomi extends Car{}
class BYD extends Car{}

class Dog {}

 

泛型包装拆箱基础类型

GenericDemo6.java

import java.util.ArrayList;

public class GenericDemo6 {
    public static void main(String[] args) {
        //目标:搞清楚泛型和集合不支持基本数据类型,只能支持对象类型(引用数据类型)。
        //包装类就是把基本类型的数据包装成对象的类型。比如Integer包装了int,Double包装了double,Character包装了char
        ArrayList<Integer> list = new ArrayList<>();
        list.add(100);//自动装箱

        //把基本数据类型变成包装类对象
        //手工包装:
        //Integer it = new Integer(100);//过时
        Integer it1 = Integer.valueOf(100);//推荐
        Integer it2 = Integer.valueOf(100);
        System.out.println(it1 == it2);//true,-128~127范围,都是放在常量池
        Integer it3 =Integer.valueOf(200);
        Integer it4 = Integer.valueOf(200);
        System.out.println(it3 == it4);//false

        //自动装箱:基本数据类型可以自动转换为包装类型。
        //自动拆箱:包装类型可以自动转换为基本数据类型
        Integer it11 = 100;//与Integer it1 = Integer.valueOf(100);作用完全一样

        //包装类新增的功能:
        //把基本类型的数据转换成字符串。
        int j1 = 1;
        String j1Str = Integer.toString(j1);//1.调用Integer.toString(intNum)转换为字符串
        Integer j2  = 2;
        String j2Str = j2.toString();//2.调用IntegerNum.toString()转换为字符串
        int j3 = 3;
        String j3Str = j3 + "";//3.intNum + ""转换为字符串

        System.out.println("-----------------------");
        String str = "123";
        int strInt1 = Integer.parseInt(str);
        int strInt2 = Integer.valueOf(str);

        String str2 = "123.456";
        double strDouble1 = Double.parseDouble(str2);
        double strDouble2 = Double.valueOf(str2);
    }
}

 

Collection  集合

CollectionDemo1.java

import java.util.*;

public class CollectionDemo1 {
    public static void main(String[] args) {
        /**
         * 目标:搞清楚Collection集合的整体特点
         *  1.List家族的集合:有序、可重复、有索引。
         *  2.Set家族的集合:无序、不重复、无索引。
         *  3.Map家族的集合:无序、不重复、键值对。
         *  4.Collection集合:集合的顶级接口,没有直接的实现类,只定义了共性的方法。
         *  5.Collection集合的实现类:ArrayList、LinkedList、Vector、HashSet、LinkedHashSet、TreeSet、HashMap、LinkedHashMap、TreeMap。
         */

        //1.List家族的集合:有序、可重复、有索引。
        List<String> list = new ArrayList<>();
        list.add("Java");list.add("Java");list.add("C");list.add("C++");list.add("C#");
        System.out.println(list);//[Java, Java, C, C++, C#]

        //2.Set家族的集合:无序、不重复、无索引。
        Set<String> set = new HashSet<>();
        set.add("Java");set.add("Java");set.add("C");set.add("C++");set.add("C#");
        System.out.println(set);//[C#, Java, C++, C]
    }
}

 

Collection  通用功能

CollectionDemo2.java

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

public class CollectionDemo2 {
    public static void main(String[] args) {
        /**
         * 目标:搞清楚Collection提供的通用集合功能
         *         Collection集合的通用功能:增删改查、遍历、判断、清空。
         *         1.增:add(E e)
         *         2.删:remove(Object o)
         *         3.改:set(int index, E element)
         *         4.查:get(int index)
         *         5.遍历:
         *           a.迭代器:Iterator<E> iterator()
         *           b.foreach:for(E e:集合)
         *           c.普通for循环:for()
         *         6.判断:contains(Object o)、isEmpty()、size()
         *         7.清空:clear()
         */

        Collection<String> list = new ArrayList<>();
        list.add("Java");list.add("C");list.add("C++");list.add("C#");list.add("Python");
        System.out.println(list.size());//5
        System.out.println(list.contains("Java"));//true
        System.out.println(list.isEmpty());// false
        list.remove("C++");
        System.out.println(list);//[Java, C, C#, Python]

        //把集合中的元素全部取出来,放到数组中
        Object[] arr = list.toArray();
        System.out.println(Arrays.toString(arr));//[Java, C, C#, Python]

        //把集合转换成字符串数组
        String[] arr3 = list.toArray(size -> new String[size]);//根据集合大小创建对应长度的新数组

        String[] arr2 = list.toArray(String[]::new);//lambda表达式
        System.out.println(arr2);//打印的是地址 //[Ljava.lang.String;@3feba861
        System.out.println(Arrays.toString(arr2));//[Java, C, C#, Python]
    }
}

 

Collection  遍历

CollectionTraversalDemo3.java

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

public class CollectionTraversalDemo3 {
    public static void main(String[] args) {
        //目标:掌握Collection的遍历方式一:迭代器遍历
        Collection<String> names = new ArrayList<>();
        names.add("张三");names.add("李四");names.add("王五");names.add("赵六");

        //1.得到这个集合的迭代器对象
        Iterator<String> it = names.iterator();
        /*System.out.println(it.next());
        System.out.println(it.next());
        System.out.println(it.next());
        System.out.println(it.next());*/
        //System.out.println(it.next());执行到这里会报错,因为迭代器已经遍历完了,没有元素了。

        //2.使用while循环遍历
        while (it.hasNext()) {
            System.out.println(it.next());
        }

        //3.lambda遍历
        names.forEach(new Consumer<String>() {
            @Override
            public void accept(String s) { System.out.println(s); }
        });

        names.forEach(s -> System.out.println(s));

        names.forEach(System.out::println);
    }
}

 

Collection  修改异常问题

CollectionTraversalTest6.java

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

public class CollectionTraversalTest6 {
    public static void main(String[] args) {
        //目标:认识并发修改异常问题,搞清楚每种遍历的区别
        ArrayList<String> list = new ArrayList<>();
        list.add("java");list.add("宁夏枸杞");list.add("黑枸杞");list.add("人字拖");list.add("特级枸杞");list.add("枸杞子");list.add("西洋参");
        //将list集合中的内容复制给一个新的集合list2
        ArrayList<String> list2 = new ArrayList<>();
        for (String s : list) {
            list2.add(s);
        }
        
        /*//这样会漏删
        for (int i = 0; i < list.size(); i++) {
            String s = list.get(i);
            if (s.contains("枸杞")) {
                list.remove(s);
            }
        }
        System.out.println(list);*/

        //需求:删除全部枸杞
        //解决方案:倒着遍历并删除(前提是支持索引)
        for (int i = list.size() - 1; i >= 0; i--) {
            String s = list.get(i);
            if (s.contains("枸杞")) {
                list.remove(s);
            }
        }
        System.out.println(list);

        //Java语言已经知道迭代器并发删除是有问题的,就不把产生问题的过程提上来了,直接写了个删除数据判定,一删除,就报错,就完了~
        //方案一:迭代器遍历并删除默认也存在并发修改异常问题。
        //方案二和三:用增强for还有Lambda(都没有办法解决并发修改异常问题)
        //可以解决:使用选代器自己的方法来删除
        System.out.println(list2);
        Iterator<String> it2 = list2.iterator();
        while(it2.hasNext()){
            String name = it2.next();
            if(name.contains("枸杞")){
                //list2.remove(name);报错
                it2.remove();
            }
        }
        System.out.println(list2);
    }
}

 

List

ArrayList

ListDemo1.java

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

public class ListDemo1 {
    public static void main(String[] args) {
        List<String> names = new ArrayList<>();
        names.add("张三");names.add("李四");names.add("王五");names.add("赵六");names.add("田七");names.add("王八");

        names.add(2,"哈基磊");//给定下标位置插入
        names.add(4,"哈基米");
        names.add(0,"哈基汪");
        System.out.println(names);//[哈基汪, 张三, 李四, 哈基磊, 王五, 哈基米, 赵六, 田七, 王八]

        names.remove(4);//删除指定下标位置的元素
        names.remove("李四");//删除指定元素
        System.out.println(names);//[哈基汪, 张三, 哈基磊, 哈基米, 赵六, 田七, 王八]

        System.out.println(names.set(1,"哈基人"));//根据下标修改,返回修改前的数据 //张三
        System.out.println(names);//[哈基汪, 哈基人, 哈基磊, 哈基米, 赵六, 田七, 王八]

        System.out.println(names.get(2));//根据下标获取元素 //哈基磊

        System.out.println("--------------------------");
        for(int i = 0; i < names.size(); i++){
            System.out.println(names.get(i));
        }

        System.out.println("--------------------------");
        for(String name : names){
            System.out.println(name);
        }

        System.out.println("--------------------------");
        names.forEach(name -> System.out.println(name));

        System.out.println("--------------------------");
        Iterator<String> it = names.iterator();
        while(it.hasNext()){
            String name = it.next();
            System.out.println(name);
        }
    }
}

 

ListDemo2.java

import java.util.LinkedList;
import java.util.List;

public class ListDemo2 {
    public static void main(String[] args) {
        //目标:用LinkedList实现一个队列。
        LinkedList<String> queue  = new LinkedList<>();
        queue.addLast("张三");queue.addLast("李四");queue.addLast("王五");queue.addLast("赵六");queue.addLast("田七");
        System.out.println(queue);//[张三, 李四, 王五, 赵六, 田七]

        System.out.println(queue.removeFirst());//张三
        System.out.println(queue.removeFirst());//李四

        System.out.println("---------------------");
        //实现一个栈
        LinkedList<String> stack = new LinkedList<>();
        //压栈
        stack.addFirst("张三");//放到序列第一个位置
        stack.addFirst("李四");
        stack.addFirst("王五");
        stack.addFirst("赵六");
        stack.push("田七");//放到序列第一个位置
        System.out.println(stack);//[田七, 赵六, 王五, 李四, 张三]

        System.out.println(stack.removeFirst());//田七
        System.out.println(stack.pop());//赵六
        System.out.println(stack);//[王五, 李四, 张三]
    }
}

 

demo8_MovieSys

Movie.java

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

@Data
@AllArgsConstructor
@NoArgsConstructor
public class Movie {
    private String name;
    private String actor;
    private double price;
    private double score;
}

MovieService.java

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

public class MovieService {
    private static List<Movie> movies = new ArrayList<>();
    private static Scanner sc = new Scanner(System.in);

    public void start(){
        while(true){
            System.out.println("----电影信息操作系统----");
            System.out.println("1.添加电影");
            System.out.println("2.删除电影");
            System.out.println("3.查询电影");
            System.out.println("4.封杀明星");
            System.out.println("5.展示全部电影");
            System.out.println("6.修改电影");
            System.out.println("7.退出系统");
            System.out.println("请输入您的指令");
            switch (sc.nextInt()){
                case 1: addMovie();break;
                case 2: deleteMovie();break;
                case 3: queryMovie();break;
                case 4: deleteStar();break;
                case 5: showAllMovie();break;
                case 6: modifyMovie();break;
                case 7: return;
                default: System.out.println("输入有误");
            }
        }
    }

    private void modifyMovie() {
        System.out.println("请输入电影名称");
        String name = sc.next();
        Movie m = queryMovieByName(name);
        if(m == null){
            System.out.println("没有找到");return;
        }
        System.out.println("请输入修改后的演员");
        m.setActor(sc.next());
        System.out.println("请输入修改后的价格");
        m.setPrice(sc.nextDouble());
        System.out.println("请输入修改后的评分");
        m.setScore(sc.nextDouble());
        System.out.println("修改成功");
    }

    private void showAllMovie() {
        for (Movie movie : movies) {
            System.out.println(movie.getName()+" "+movie.getActor()+" "+movie.getPrice()+" "+movie.getScore());
        }
    }

    private void deleteStar() {
        System.out.println("请输入要封杀的明星名称");
        String name = sc.next();
        for(int i = 0; i < movies.size(); i++){
            //注意:contains方法,判断字符串中是否包含某个字符,返回true或者false
            //     equals方法,判断字符串是否与某个字符完全相等,返回true或者false
            if(movies.get(i).getActor().contains(name)){
                movies.remove(i);
                System.out.println("封杀成功");
                i--;//删除一个元素,索引要往前移一位
            }
        }
    }

    private void deleteMovie() {
        System.out.println("请输入电影名称");
        String name = sc.next();
        Movie m = queryMovieByName(name);
        if(m != null){
            movies.remove(m);
            System.out.println("删除成功");return;
        }
        System.out.println("没有找到");
    }

    private void queryMovie() {
        System.out.println("请输入电影名称");
        String name = sc.next();
        Movie m = queryMovieByName(name);
        if(m != null){
            System.out.println(m.getName()+" "+m.getActor()+" "+m.getPrice()+" "+m.getScore());return;
        }
        System.out.println("没有找到");
    }

    public Movie queryMovieByName(String name){
        for (Movie movie : movies) {
            if(movie.getName().equals(name)){
                return movie;
            }
        }
        return null;
    }

    private void addMovie() {
        Movie m = new Movie();
        System.out.println("请输入电影名称");
        m.setName(sc.next());
        System.out.println("请输入电影演员");
        m.setActor(sc.next());
        System.out.println("请输入电影价格");
        m.setPrice(sc.nextDouble());
        System.out.println("请输入电影评分");
        m.setScore(sc.nextDouble());
        movies.add(m);
        System.out.println("添加成功");
    }
}

Test.java

public class Test {
    public static void main(String[] args) {
        //目标:完成电影案例
        //1、创建电影对象:定义电影类。
        //2、创建一个电影操作对象:专门负责对象电影数据进行业务处理(上架,下架,查询,封杀某个电影明星的电影)
        MovieService ms = new MovieService();
        ms.start();
    }
}

 

Set

SetDemo1.java

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

public class SetDemo1 {
    public static void main(String[] args) {
        /**
         * Set系列集合特点:无序:添加数据的顺序和获取出的数据顺序不一致; 不重复;无索引;
         *         HashSet:无序、不重复、无索引。
         *         LinkedHashset:有序、不重复、无索引。
         *         TreeSet:默认升序排序、不重复、无索引。
         *         Set要用到的常用方法,基本上就是Collection提供的
         *         自己几乎没有额外新增一些常用功能!
         */

        Set<String> set = new HashSet<>();//无序、不重复、无索引。
        set.add("Java");set.add("Java");set.add("C");set.add("C++");set.add("C#");
        System.out.println(set);//[C#, Java, C++, C]
        System.out.println("--------------------");

        Set<Integer> set2 = new LinkedHashSet<>();//有序、不重复、无索引。
        set2.add(9);set2.add(1);set2.add(1);set2.add(4);set2.add(5);set2.add(1);set2.add(4);
        System.out.println(set2);//按添加的顺序输出  //[9, 1, 4, 5]
        System.out.println("--------------------");

        Set<Double> set3 = new TreeSet<>();//默认升序排序、不重复、无索引。
        set3.add(1.0);set3.add(9.0);set3.add(1.0);set3.add(9.0);set3.add(8.0);set3.add(1.0);set3.add(0.0);
        System.out.println(set3);//0.0, 1.0, 8.0, 9.0]
        System.out.println("--------------------");

        System.out.println("123".hashCode());//48690
    }
}

 

HashSet去重   重写对象hashCode方法和equals方法

SetDemo2.java

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

public class SetDemo2 {
    public static void main(String[] args) {
        //目标:掌握HashSet集合去重操作。
        Student s1 = new Student("张三", 18, "北京", "123456");
        Student s2 = new Student("李四", 19, "上海", "654321");
        Student s3 = new Student("张三", 18, "北京", "123456");
        Student s4 = new Student("李四", 19, "上海", "654321");

        //结论:如果希望Set集合认为2个内容一样的对象是重复的
        //必须重写对象的hashCode()和equals()方法
        //默认的是拿对象(地址不同)生成hash。重写之后是拿属性值(属性相同)生成hash
        Set<Student> set = new HashSet<>();
        set.add(s1);set.add(s2);set.add(s3);set.add(s4);
        System.out.println(set);

    }
}

class Student{
    private String name;
    private int age;
    private String address;
    private String phone;

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

    @Override
    public boolean equals(Object o) {
        //判断对象是否是同一个对象,如果是同一个对象,则返回true
        if (this == o) return true;
        //如果对象为null,则返回false。判断对象是否是同一个类型,如果不是同一个类型,则返回false。
        if (o == null || this.getClass() != o.getClass()) return false;
        Student student = (Student) o;
        return age == student.age && Objects.equals(name, student.name) && Objects.equals(address, student.address) && Objects.equals(phone, student.phone);
    }

    /**
     * 这段代码的功能是:
     * 1. 重写Object类的hashCode()方法,为Student对象生成哈希值
     * 2. 使用Objects.hash()方法,将对象的四个属性(name, age, address, phone)组合计算哈希值
     * 3. 当这些属性值相同时,会返回相同的哈希码,用于哈希表等数据结构中快速比较对象
     * @return
     */
    @Override
    public int hashCode() { return Objects.hash(name, age, address, phone); }

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

    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 getAddress() { return address; }
    public void setAddress(String address) { this.address = address; }
    public String getPhone() { return phone; }
    public void setPhone(String phone) { this.phone = phone; }
}

res

[Student{name='张三', age=18, address='北京', phone='123456'}
, Student{name='李四', age=19, address='上海', phone='654321'}
]

 

SetDemo3.java   TreeSet

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

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

public class SetDemo3 {
    public static void main(String[] args) {
        /**
         * TreeSet集合特点:不重复、无索引、可排序(默认升序排序,按照元素的大小,由小到大排序)。底层是基于红黑树实现的排序,
         *  对于数值类型:Integer,Double,默认按照数值本身的大小进行升序排序。对于字符串类型:默认按照首字符的编号升序排序。
         *  对于自定义类型如Student对象,TreeSet默认是无法直接排序的
         *  目标:搞清楚TreeSet集合对于自定义对象的排序
         */
        Set<Teacher> t = new TreeSet<>();
        t.add(new Teacher("小王", 20, 6324));
        t.add(new Teacher("小叶", 18, 1145));
        t.add(new Teacher("小李", 22, 1419));
        t.add(new Teacher("小江", 20, 1981));
        System.out.println(t);

        //结论:TreeSet集合默认不能 给自定义对象排序啊,因为不知道大小规则。一定要能解决怎么办?两种方案。
        //1.对象类实现一个Comparable比较接口,重写compareTo方法,指定大小比较规则
        //2.public TreeSet(Comparator c)集合自带比较器Comparator对象,指定比较规则
        Set<Teacher> t2 = new TreeSet<>(new Comparator<Teacher>() {
            @Override
            public int compare(Teacher o1, Teacher o2) {
                /*
                //按年龄降序排序
                if(o2.getAge() > o1.getAge())  return 1;
                else if(o2.getAge() < o1.getAge())  return -1;
                return 1;*/
                return Double.compare(o1.getSalary(), o2.getSalary());//按工资升序排序
            }
        });
        Set<Teacher> t3 = new TreeSet<>((o1, o2) -> Double.compare(o1.getSalary(), o2.getSalary()));
        t2.add(new Teacher("小王", 20, 6324));
        t2.add(new Teacher("小叶", 18, 1145));
        t2.add(new Teacher("小李", 22, 1419));
        t2.add(new Teacher("小江", 20, 1981));
        System.out.println(t2);

    }
}

@Data
@NoArgsConstructor
@AllArgsConstructor
class Teacher implements Comparable<Teacher> {
    private String name;
    private int age;
    private double salary;

    @Override
    public String toString() {
        return "Teacher{" +
                "name='" + name + '\'' +
                ", age=" + age +
                ", salary=" + salary +
                '}' + "\n";
    }

    //t2.compareTo(t1)
    //t2 == this 比较者
    //t1 ==  o   被比较者
    //如果返回值小于0,则认为t2小于t1,t2在t1之前。
    //如果返回值大于0,则认为t2大于t1,t2在t1之后。
    //如果返回值等于0,则认为t2等于t1,t2和t1在同一位置。
    @Override
    public int compareTo(Teacher o) {
        //按年龄升序排序
        if (this.getAge() > o.getAge()) return 1;
        else if (this.getAge() < o.getAge()) return -1;
        return 1;//保证年龄相同的值不会被剔除
    }
}

res

[Teacher{name='小叶', age=18, salary=1145.0}
, Teacher{name='小王', age=20, salary=6324.0}
, Teacher{name='小江', age=20, salary=1981.0}
, Teacher{name='小李', age=22, salary=1419.0}
]
[Teacher{name='小叶', age=18, salary=1145.0}
, Teacher{name='小李', age=22, salary=1419.0}
, Teacher{name='小江', age=20, salary=1981.0}
, Teacher{name='小王', age=20, salary=6324.0}
]

 

Map

HashMap特点:无序,不重复,无索引,键值对都可以是null,值不做要求(可以重复)

LinkedMap特点:有序,不重复,无索引,键值对都可以是null,值不做要求(可以重复)

TreeMap:按照键可排序,不重复,无索引

 

MapDemo1.java

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

public class MapDemo1 {
    public static void main(String[] args) {
        //HashMap特点:无序,不重复,无索引,键值对都可以是null,值不做要求(可以重复)
        //LinkedMap特点:有序,不重复,无索引,键值对都可以是null,值不做要求(可以重复)
        //TreeMap:按照键可排序,不重复,无索引
        Map<String,Integer> map = new HashMap<>();
        map.put("小王",18);
        map.put("小李",19);
        map.put("小张",20);
        map.put(null,null);
        System.out.println(map);//{null=null, 小李=19, 小王=18, 小张=20}
    }
}

 

MapDemo2.java    Map遍历

import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
import java.util.function.BiConsumer;

public class MapDemo2 {
    public static void main(String[] args) {
        Map<String,Integer> map = new HashMap<>();
        map.put("张三",18);map.put("李四",19);map.put("王五",20);map.put("赵六",21);map.put("田七",22);map.put("王八",23);map.put(null,null);

        //map的常用方法
        System.out.println(map.size());//7
        System.out.println(map.isEmpty());//false
        System.out.println(map.containsKey("张三"));//true
        System.out.println(map.containsValue(18));//true
        System.out.println(map.get("张三"));//获取键对应的值 //18
        System.out.println(map.remove("张三"));//根据键删除键值对对象,并返回删除的value //18
        System.out.println("--------------1--------------");

        Set<String> keyS = map.keySet();//获取所有的键,保存到set集合中
        for (String key : keyS) {
            System.out.println(key + "-->" + map.get(key));
        }
        System.out.println("--------------2--------------");

        /**
         * Map.Entry 是 Java 中 Map 接口定义的静态嵌套接口(static nested interface),用于表示 Map 中的一个键值对(Key-Value Pair)。以下是关键点解析:
         * 本质  是 Map 接口的内部接口:Map.Entry<K,V>
         *      每个 Entry 对象代表 Map 中的一个键值对(如 {"张三": 18})
         * 核心方法
         *      K getKey():返回键(如 "张三")
         *      V getValue():返回值(如 18)
         *      V setValue(V value):修改当前键值对的值(注意:直接修改会同步到原 Map)
         * 使用场景
         *      通过 map.entrySet() 获取所有 Entry 的集合(如示例中的遍历)
         *      适合需要同时访问键和值的场景(比先取 keySet 再 get(key) 更高效)
         * 其他特性
         *      支持泛型(如 Map.Entry<String,Integer>)
         *      是遍历 Map 的标准方式之一(尤其 JDK8 之前)
         * 补充:在 JDK8+ 中,Map.forEach 和 Lambda 表达式(如 map.forEach((k,v) -> ...))可以更简洁地替代 Entry 遍历。
         */
        //把Map集合转换成Set集合,里面的元素类型都是键值对类型(Map.Entry<String,Integer>)
        Set<Map.Entry<String, Integer>> entrySet = map.entrySet();//获取所有的键值对对象,保存到set集合中
        for (Map.Entry<String, Integer> entry : entrySet) {
            System.out.println(entry.getKey() + "-->" + entry.getValue());
        }
        System.out.println("--------------3--------------");

        //获取所有的值放到一个Collection集合中
        Collection<Integer> values = map.values();
        for (Integer value : values) {
            System.out.println(value);
        }
        System.out.println("--------------4--------------");

        map.forEach(new BiConsumer<String, Integer>() {
            @Override
            public void accept(String s, Integer integer) {
                System.out.println(s + "-->" + integer);
            }
        });
        System.out.println("--------------5--------------");

        map.forEach((s, integer) -> System.out.println(s + "-->" + integer));
    }
}

res

7
false
true
true
18
18
--------------1--------------
null-->null
李四-->19
王五-->20
赵六-->21
田七-->22
王八-->23
--------------2--------------
null-->null
李四-->19
王五-->20
赵六-->21
田七-->22
王八-->23
--------------3--------------
null
19
20
21
22
23
--------------4--------------
null-->null
李四-->19
王五-->20
赵六-->21
田七-->22
王八-->23
--------------5--------------
null-->null
李四-->19
王五-->20
赵六-->21
田七-->22
王八-->23

 

MapDemo7.java    TreeMap

import java.util.Comparator;
import java.util.Map;
import java.util.TreeMap;

public class MapDemo7 {
    public static void main(String[] args) {
        //目标:TreeMap集合(原理和用法于TreeSet一样)
        //Map<Teacher3,String> map = new TreeMap<>((o1, o2) -> Double.compare(o1.getSalary(),o2.getSalary()));
        Map<Teacher3,String> map = new TreeMap<>(Comparator.comparingDouble(Teacher3::getSalary));
        map.put(new Teacher3("小王",18,9000),"北京");
        map.put(new Teacher3("小张",19,6000),"上海");
        map.put(new Teacher3("小李",20,7000),"广州");
        map.put(new Teacher3("小王",18,5000),"深圳");
        System.out.println(map);
    }
}

class Teacher3 {
    private String name;
    private int age;
    private double salary;

    public Teacher3(String name, int age, double salary) {
        this.name = name;this.age = age;this.salary = salary;
    }

    public String getName() { return name; }
    public int getAge() { return age; }
    public double getSalary() { return salary; }

    @Override
    public String toString() {
        return "Teacher3{" +
                "name='" + name + '\'' +
                ", age=" + age +
                ", salary=" + salary +
                '}' + "\n";
    }
}

res

{Teacher3{name='小王', age=18, salary=5000.0}
=深圳, Teacher3{name='小张', age=19, salary=6000.0}
=上海, Teacher3{name='小李', age=20, salary=7000.0}
=广州, Teacher3{name='小王', age=18, salary=9000.0}
=北京}

 

MapTest6.java

import java.util.*;

public class MapTest6 {
    public static void main(String[] args) {
        //完成Map集合相关案例:投票统计程序
        calc();
    }

    public static void calc(){
        List<String> locations = new ArrayList<>();
        String[] names = {"北京", "上海", "广州", "深圳"};
        Random r = new Random();
        for (int i = 0; i < 100; i++) {
            int index = r.nextInt(names.length);
            locations.add(names[index]);
        }

        Map<String, Integer> map = new HashMap<>();
        for (String location : locations) {
            if(map.containsKey(location)){
                Integer count = map.get(location);
                map.put(location, count + 1);
            }else{
                map.put(location, 1);
            }
        }
        map.forEach((k,v)-> System.out.println(k + ":" + v));
    }
}

res

上海:28
广州:27
深圳:20
北京:25

 

Stream

StreamDemo1.java

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

public class StreamDemo1 {
    public static void main(String[] args) {
        //目标:认识Stream流,掌握其基本使用步骤。体会它的优势和特点。
        List<String> list = new ArrayList<>();
        list.add("张无忌");list.add("周芷若");list.add("赵敏");list.add("张强");list.add("张三丰");list.add("张翠山");

        //1、先用传统方案:找出姓张的人,名字为3个字的,存入到一个新集合中去。
        List<String> newList = new ArrayList<>();
        for(String name : list){
            if(name.startsWith("张") && name.length() == 3){
                newList.add(name);
            }
        }
        System.out.println(newList);
        System.out.println("--------------------");

        //2、用Stream流实现
        List<String> newList2 = list.stream().filter(name -> name.startsWith("张")).
                filter(name -> name.length() == 3).collect(Collectors.toList());
        System.out.println(newList2);
        System.out.println("--------------------");

        list.stream()
                .filter(name -> name.startsWith("张"))
                .filter(name -> name.length() == 3)
                .forEach(name -> System.out.println(name));
    }
}

res

[张无忌, 张三丰, 张翠山]
--------------------
[张无忌, 张三丰, 张翠山]
--------------------
张无忌
张三丰
张翠山

 

 

StreamDemo2.java

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

public class StreamDemo2 {
    public static void main(String[] args) {
        //目标:获取Stream流的方式,
        //1、获取集合的stream流:调用集合提供的stream()方法
        Collection<String> list = new ArrayList<>();
        Stream<String> s1 = list.stream();

        //2、Map集合,怎么拿Stream流。
        Map<String,Integer> map = new HashMap<>();
        Stream<String> s2 = map.keySet().stream();//获取所有的键的stream流
        Stream<Integer> s3 = map.values().stream();//获取所有的值的stream流
        Stream<Map.Entry<String,Integer>> s4 = map.entrySet().stream();//获取所有的键值对的stream流

        //3、数组,怎么拿Stream流。
        String[] names = {"张三丰", "张无忌", "赵敏", "周芷若","张伟"};
        Stream<String> s5 = Arrays.stream(names);
        System.out.println(s5.count());//5
        
        Stream<String> s6 = Stream.of("张三丰", "张无忌", "赵敏", "周芷若","张伟");
    }
}

 

StreamDemo3.java

import java.util.ArrayList;
import java.util.List;
import java.util.function.Consumer;
import java.util.stream.Stream;

public class StreamDemo3 {
    public static void main(String[] args) {
        //目标:掌握Stream提供的常用的中间方法,对流上的数据进行处理(返回新流:支持链式编程)
        List<String> list = new ArrayList<>();
        list.add("张无忌");list.add("周芷若");list.add("赵敏");list.add("张强");list.add("张三丰");
        list.add("张翠山");list.add("张良");list.add("王二麻子");list.add("谢广坤");list.add("冬雪莲");

        //1.过滤方法
        /*
        list.stream().filter(name -> name.startsWith("张")).forEach(new Consumer<String>() {
            @Override
            public void accept(String s) {
                System.out.println(s);
            }
        });*/
        //list.stream().filter(name -> name.startsWith("张")).forEach(name -> System.out.println(name));
        list.stream().filter(name -> name.startsWith("张")).forEach(System.out::println);

        System.out.println("----------------------------------------------------------");

        //2.排序方法
        List<Double> list1 = new ArrayList<>();
        list1.add(99.6);list1.add(35.8);list1.add(66.6);list1.add(77.7);list1.add(55.5);list1.add(88.8);list1.add(77.7);
        list1.stream().sorted().forEach(num -> System.out.println(num));//默认升序
        System.out.println("----------1----------");
list1.stream().sorted((o1, o2)
-> Double.compare(o2, o1)).forEach(num -> System.out.println(num));//降序 System.out.println("----------2----------");
list1.stream().sorted((o1, o2)
-> Double.compare(o2, o1)).limit(3).forEach(num -> System.out.println(num));//取前三个 System.out.println("----------3----------");
list1.stream().sorted((o1, o2)
-> Double.compare(o2, o1)).skip(3).forEach(num -> System.out.println(num));//跳过前三个 System.out.println("----------4----------");
list1.stream().sorted((o1, o2)
-> Double.compare(o2, o1)).distinct().forEach(num -> System.out.println(num));//去重 System.out.println("----------5----------"); //映射/加工方法:把流上原来的数据拿出来变成新数据又放到流上去,原本的数据不变 list1.stream().map(s -> "加10分后:" + (s + 10)).forEach(num -> System.out.println(num)); System.out.println("----------6----------"); //合并流 Stream<String> stream1 = list.stream(); Stream<Double> stream2 = list1.stream(); Stream<Object> stream3 = Stream.concat(stream1, stream2); System.out.println(stream3.count());//17 } }

res

张无忌
张强
张三丰
张翠山
张良
----------------------------------------------------------
35.8
55.5
66.6
77.7
77.7
88.8
99.6
----------1----------
99.6
88.8
77.7
77.7
66.6
55.5
35.8
----------2----------
99.6
88.8
77.7
----------3----------
77.7
66.6
55.5
35.8
----------4----------
99.6
88.8
77.7
66.6
55.5
35.8
----------5----------
加10分后:109.6
加10分后:45.8
加10分后:76.6
加10分后:87.7
加10分后:65.5
加10分后:98.8
加10分后:87.7
----------6----------
17

 

StreamDemo4.java

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

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

public class StreamDemo4 {
    public static void main(String[] args) {
        //目标:掌握Stream流的统计,收集操作(终结方法)
        List<Teacher> teachers = new ArrayList<>();
        teachers.add(new Teacher("张三丰", 100, 10000));
        teachers.add(new Teacher("张无忌", 20, 8000));
        teachers.add(new Teacher("赵敏", 18, 6000));
        teachers.add(new Teacher("周芷若", 17, 5000));
        teachers.add(new Teacher("张强", 19, 4000));
        teachers.add(new Teacher("张三", 20, 30000));
        teachers.add(new Teacher("冬雪莲", 20, 8000));
        teachers.add(new Teacher("梁志斌", 19, 4000));

        teachers.stream().filter(t -> t.getSalary() > 7000).forEach(System.out::println);
        System.out.println("--------------------1--------------------");

        System.out.println(teachers.stream().filter(t -> t.getSalary() > 7000).count());
        System.out.println("--------------------2--------------------");

        //Optional<T> 是 Java 8 引入的容器类,用于优雅地处理可能为 null 的值
        //防 NullPointerException:明确表示"值可能不存在",避免显式的 null 检查
        //Optional<Teacher> max = teachers.stream().max((t1, t2) -> Double.compare(t1.getSalary(), t2.getSalary()));
        Optional<Teacher> max = teachers.stream().max(Comparator.comparingDouble(Teacher::getSalary));
        Teacher maxTeacher = max.get();
        System.out.println(maxTeacher);
        System.out.println("--------------------3--------------------");

        //收集Stream流:就是把Stream流操作后的结果转回到集合或者数组中去返回
        //Stream流:方便操作集合/数组的手段;集合/数组:才是开发中的目的
        List<String> list = new ArrayList<>();
        list.add("张无忌");list.add("周芷若");list.add("赵敏");list.add("张强");list.add("张三丰");
        list.add("张翠山");list.add("张良");list.add("王二麻子");list.add("谢广坤");list.add("冬雪莲");
Stream
<String> s1 = list.stream().filter(name -> name.startsWith("张")); List<String> list1 = s1.collect(Collectors.toList()); System.out.println(list1); System.out.println("--------------------4--------------------"); s1 = list.stream().filter(name -> name.startsWith("张")); Set<String> set1 = s1.collect(Collectors.toSet()); System.out.println(set1); System.out.println("--------------------5--------------------"); s1 = list.stream().filter(name -> name.startsWith("张")); Object[] array1 = s1.toArray(); System.out.println(Arrays.toString(array1)); System.out.println("--------------------6--------------------"); //Stream<Teacher> s4 = teachers.stream().sorted((t1, t2) -> Double.compare(t1.getSalary(), t2.getSalary())); Stream<Teacher> s4 = teachers.stream().sorted(Comparator.comparingDouble(Teacher::getSalary)); //收集到Map集合:键是老师名称,值是老师薪水 /* Map<String, Double> map2 = s4.collect(Collectors.toMap(new Function<Teacher3, String>() { @Override public String apply(Teacher3 teacher) { return teacher.getName(); } }, new Function<Teacher3, Double>() { @Override public Double apply(Teacher3 teacher) { return teacher.getSalary(); } }));*/ Map<String, Double> map1 = s4.collect(Collectors.toMap(Teacher::getName, Teacher::getSalary)); System.out.println(map1); } } @Data @NoArgsConstructor @AllArgsConstructor class Teacher implements Comparable<Teacher> { private String name; private int age; private double salary; @Override public String toString() { return "Teacher{" + "name='" + name + '\'' + ", age=" + age + ", salary=" + salary + '}' + "\n"; } //t2.compareTo(t1) //t2 == this 比较者 //t1 == o 被比较者 //如果返回值小于0,则认为t2小于t1,t2在t1之前。 //如果返回值大于0,则认为t2大于t1,t2在t1之后。 //如果返回值等于0,则认为t2等于t1,t2和t1在同一位置。 @Override public int compareTo(Teacher o) { //按年龄升序排序 if (this.getAge() > o.getAge()) return 1; else if (this.getAge() < o.getAge()) return -1; return 1;//保证年龄相同的值不会被剔除 } }

res

Teacher{name='张三丰', age=100, salary=10000.0}

Teacher{name='张无忌', age=20, salary=8000.0}

Teacher{name='张三', age=20, salary=30000.0}

Teacher{name='冬雪莲', age=20, salary=8000.0}

--------------------1--------------------
4
--------------------2--------------------
Teacher{name='张三', age=20, salary=30000.0}

--------------------3--------------------
[张无忌, 张强, 张三丰, 张翠山, 张良]
--------------------4--------------------
[张强, 张良, 张翠山, 张三丰, 张无忌]
--------------------5--------------------
[张无忌, 张强, 张三丰, 张翠山, 张良]
--------------------6--------------------
{张强=4000.0, 冬雪莲=8000.0, 梁志斌=4000.0, 张三=30000.0, 张三丰=10000.0, 周芷若=5000.0, 赵敏=6000.0, 张无忌=8000.0}

 

 

Collection工具   批量添加、打乱

CollectionDemo2.java

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

public class CollectionDemo2 {
    public static void main(String[] args) {
        //认识Collections工具类
        List<String> list = List.of("hello", "world", "java");
        List<String> list2 = new ArrayList<>();
        /*这样加很慢
        list2.add("hello");list2.add("world");list2.add("java");*/

//1.Collections的方法批量加 Collections.addAll(list2 , "hello","world","c","java","python","c++"); System.out.println(list2);//[hello, world, c, java, python, c++] //2.打乱顺序 Collections.shuffle(list2); System.out.println(list2);//[world, python, hello, c, java, c++] } }

 

Game.java   斗地主发牌模拟

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

import java.util.*;

public class Game {
    public static void main(String[] args) {
        //目标:开发斗地主游戏。
        //1、每张牌都是一个对象,定义牌类。
        //2、游戏房间也是一个对象:定义房间类(54张牌,开始启动)
        Room r = new Room();
        r.start();

    }
}

class Room{
    //1、准备好54张牌,给房间使用:定义一个集合容器装54张牌。
    private List<Card> allCards = new ArrayList<>();
    {
        //2、初始化54张牌,给房间使用:遍历四种花色,四种牌型。
        String[] colors = {"♦","♣","♥","♠"};//花色
        String[] sizes = {"3","4","5","6","7","8","9","10","J","Q","K","A","2"};//点数
        for (String color : colors) {
            for (String size : sizes) {
                allCards.add(new Card(size,color));
            }
        }
        //3、将大小王添加到牌集中。
        /*allCards.add(new Card("小王",""));
        allCards.add(new Card("大王",""));*/
        Collections.addAll(allCards,new Card("小王",""),new Card("大王",""));

        System.out.println(allCards);
    }

    public void start(){
        //4、洗牌,打乱牌的顺序。
        Collections.shuffle(allCards);
        //5、发牌,给三个玩家,17张牌,3个玩家,17张牌,底牌3张。
        Map<String, List<Card>> plays = new HashMap<>();
        List<Card> cards1 = new ArrayList<>();
        plays.put("player1",cards1);
        List<Card> cards2 = new ArrayList<>();
        plays.put("player2",cards2);
        List<Card> cards3 = new ArrayList<>();
        plays.put("player3",cards3);
        List<Card> dipai = new ArrayList<>();
        for (int i = 0; i < allCards.size(); i += 3) {
            if(i >= allCards.size() - 3){
                dipai.add(allCards.get(i));
                dipai.add(allCards.get(i + 1));
                dipai.add(allCards.get(i + 2));
            }
            cards1.add(allCards.get(i));
            cards2.add(allCards.get(i + 1));
            cards3.add(allCards.get(i + 2));
        }
        /*用List
        //定义三个集合,分别存储三个玩家的牌。
        List<Card> player1 = new ArrayList<>();
        List<Card> player2 = new ArrayList<>();
        List<Card> player3 = new ArrayList<>();
        List<Card> dipai = new ArrayList<>();
        //遍历牌集合,获取每一张牌。
        for (int i = 0; i < allCards.size(); i++) {
            Card card = allCards.get(i);
            if(i >= allCards.size() - 3){
                dipai.add(card);
            }else if(i % 3 == 0){
                player1.add(card);
            }else if(i % 3 == 1){
                player2.add(card);
            }else if(i % 3 == 2){
                player3.add(card);
            }
        }
        System.out.println("底牌:" + dipai);
        System.out.println("玩家1:" + player1);
        System.out.println("玩家2:" + player2);
        System.out.println("玩家3:" + player3);*/

        //6、排序,按照牌的大小进行排序。
        for(List<Card> cards : plays.values()){
            //cards.sort((o1, o2) -> o1.compareTo(o2));
            cards.sort(Card::compareTo);
        }
        dipai.sort((o1, o2) -> o1.compareTo(o2));

        //7、看牌,看牌 everyone: everyone.forEach(card -> System.out.println(card));
        for (Map.Entry<String, List<Card>> entry : plays.entrySet()) {
            String name = entry.getKey();
            List<Card> cards = entry.getValue();
            System.out.println(name + ":" + cards);
        }
        System.out.println("底牌:" + dipai);
    }
}

@Data
@NoArgsConstructor
@AllArgsConstructor
class Card{
    private String size;
    private String color;

    // 将点数映射为数值
    private int getSizeValue(){
        switch(size){
            case "J": return 11;
            case "Q": return 12;
            case "K": return 13;
            case "A": return 14;
            case "2": return 15;
            case "小王": return 16;
            case "大王": return 17;
            default: return Integer.parseInt(size);//其他点数直接转换为整数
        }
    }

    public int compareTo(Card o) {
        // 先比较点数
        int sizeCompare = Integer.compare(this.getSizeValue(), o.getSizeValue());
        if (sizeCompare != 0) { return sizeCompare; }

        // 点数相同,比较花色
        return this.color.compareTo(o.color);
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        Card card = (Card) o;
        return Objects.equals(size, card.size) && Objects.equals(color, card.color);
    }

    @Override
    public String toString() { return size + color; }
}

res

[3♦, 4♦, 5♦, 6♦, 7♦, 8♦, 9♦, 10♦, J♦, Q♦, K♦, A♦, 2♦, 3♣, 4♣, 5♣, 6♣, 7♣, 8♣, 9♣, 10♣, J♣, Q♣, K♣, A♣, 2♣, 3♥, 4♥, 5♥, 6♥, 7♥, 8♥, 9♥, 10♥, J♥, Q♥, K♥, A♥, 2♥, 3♠, 4♠, 5♠, 6♠, 7♠, 8♠, 9♠, 10♠, J♠, Q♠, K♠, A♠, 2♠, 小王, 大王]
player1:[3♥, 4♣, 5♣, 6♣, 6♥, 7♥, 7♦, 8♦, 9♣, 9♥, 9♦, J♠, J♣, Q♣, K♦, A♣, 2♠, 2♦]
player2:[3♠, 4♦, 5♠, 5♥, 6♠, 6♦, 7♠, 7♣, 8♠, 8♥, 10♣, 10♦, J♦, K♠, K♣, A♠, 2♥, 小王]
player3:[3♣, 3♦, 4♠, 4♥, 5♦, 8♣, 9♠, 10♠, 10♥, J♥, Q♠, Q♥, Q♦, K♥, A♥, A♦, 2♣, 大王]
底牌:[4♣, 5♦, 8♥]

 

 

Param可变参数

ParamDemo1.java

import java.util.Arrays;

public class ParamDemo1 {
    public static void main(String[] args) {
        //目标:认识可变参数
        //方法中可变参数 就是一种特殊形参,定义在方法、构造器的形参列表里,格式是:数据类型...参数名称;
        //特点:可以不传数据给它;可以传一个或者同时传多个数据给它;也可以传一个数组给它。好处:常常用来灵活的接收数据
        sum();
        sum(10);
        sum(10,20,30,40);
        sum(new int[]{10,20,30,40});
    }

    //注意事项:可变参数在形参列表中只能有一个,可变参数必须放在形参列表的最后面
    public static void sum(int... nums) {
        //可变参数对内实际上就是一个数组。nums就是数组.
        System.out.println(nums.length);
        System.out.println(Arrays.toString(nums));
        System.out.println("------------------------");
    }
}

res

0
[]
------------------------
1
[10]
------------------------
4
[10, 20, 30, 40]
------------------------
4
[10, 20, 30, 40]
------------------------

 

posted on 2025-05-24 21:56  ᶜʸᵃⁿ  阅读(9)  评论(0)    收藏  举报