常用类,集合框架,IO流,注解和反射

文章目录

常用类

1.StringBuilder

package basics.useClass.stringBuilder;

public class Test01 {
    public static void main(String[] args) {
        StringBuilder sb = new StringBuilder();
        //StringBuilder中的append方法为字符串的添加,用append添加的字符串会保存在StringBuilder容器中,所以第一次append之后,后边再append时为字符串的拼接
        StringBuilder s1 = sb.append("hello");
        System.out.println("s1:"+s1);
        StringBuilder s2 = sb.append("world");
        System.out.println("s2:"+s2);
        StringBuilder s3 = sb.append("java");
        System.out.println("s3:"+s3);

        //StringBuilder转String方法为:toString
        String ss1 = s1.toString();
        String str = ss1;
        System.out.println(str);

        //StringBuilder反转方法:reverse()
        StringBuilder reverse = s3.reverse();
        System.out.println(reverse);

        //String转StringBuilder方法为:创建StringBuilder的有参构造方法
        String str1 = "你好";
        StringBuilder stringBuilder = new StringBuilder(str1);
        System.out.println(stringBuilder);
    }
}
package basics.useClass.stringBuilder;


//定义一个方法,用于把 int 数组中的数据按照指定格式拼接成一个字符串返回
//{1,2,3}--->[1,2,3]
public class Test02 {
    public static void main(String[] args) {
        int[] a = {1,2,3};
        System.out.println(new Test02().arrayToString(a));
    }

    public String arrayToString(int[] arr){
        StringBuilder str = new StringBuilder();
        str.append("[");
        for (int i = 0; i < arr.length; i++) {
            if (i == arr.length-1){
                str.append(arr[i]);
            }else {
                str.append(arr[i]).append(",");

            }
        }
        str.append("]");
        return str.toString();
    }
}

2.Math类

package basics.useClass.math;

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

        //Math.abs()   绝对值
        System.out.println(Math.abs(-88));   //88
        System.out.println(Math.abs(88));    //88

        //Math.ceil()   向上取整
        System.out.println(Math.ceil(1.14));   //2.0
        System.out.println(Math.ceil(1.74));   //2.0
        System.out.println(Math.ceil(-1.14));  //-1.0
        System.out.println(Math.ceil(-1.74));  //-1.0

        //Math.floor()   向下取整
        System.out.println(Math.floor(1.14));  //1.0
        System.out.println(Math.floor(1.74));  //1.0
        System.out.println(Math.floor(-1.14)); //-2.0
        System.out.println(Math.floor(-1.74)); //-2.0

        //Math.round()   四舍五入
        System.out.println(Math.round(1.14));  //1
        System.out.println(Math.round(1.74));  //2
        System.out.println(Math.round(-1.14)); //-1
        System.out.println(Math.round(-1.74)); //-2

        //Math.max()  最大值
        //Math.min()  最小值
        System.out.println(Math.max(2, 3));  //3
        System.out.println(Math.min(2, 3));  //2

        //Math.pow(double a,double b)    返回a的b次幂
        System.out.println(Math.pow(2,3));  //8。0

        //Math.random()  [0,1)的随机数的double数
        System.out.println(Math.random());
        //[0,1)的随机整数,因为取不到1,所以只能为0  =  [0,0]
        System.out.println((int)Math.random());
        //[1,2)的随机整数,因为取不到2,所以只能为1  =  [1,1]
        System.out.println((int)Math.random()+1);
        //[0,100)的随机整数  =  [0,99]的随机整数
        System.out.println((int)(Math.random()*100));
        //[1,101)的随机整数  =  [1,100]
        System.out.println((int)(Math.random()*100+1));
    }
}
package basics.useClass.math;

import java.util.Random;

public class TestRandom {
    public static void main(String[] args) {
        Random random = new Random();
        System.out.println(random.nextDouble());

        //random.nextInt(n)   该方法的作用是生成一个随机的int值,该值介于[0,n)的区间
        //随机生成[0,1]
        System.out.println(random.nextInt(2));

        //随机生成[0,100]
        System.out.println(random.nextInt(101));

        //随机生成[5,10]
        System.out.println(random.nextInt(6) + 5);

        //随机两位整数  [10,100)
        System.out.println(random.nextInt(90) + 10);

        //生成随机三位数的代码为:[100,1000)
        System.out.println(random.nextInt(900) + 100);

        //生成区间 [64,128] 中随机值的代码为:
        System.out.println(random.nextInt(65) + 64);

        //[4,16)  = [4,15]
        System.out.println(random.nextInt(12) + 4);

        //(7,19]  =  [8,19]
        System.out.println(random.nextInt(12) + 8);

        //最终公式如下: [min,max]
        //  random.nextInt(max - min + 1) + min;

    }
}

3.System类

package basics.useClass.system;

//public static long currentTimeMillis()
//返回当前时间(以毫秒为单位)
//在1970年1月1日UTC之间的当前时间和午夜之间的差异,以毫秒为单位
public class CurrentTimeMillisTest02 {
    public static void main(String[] args) {

        //long l = System.currentTimeMillis();
        //System.out.println(l);

        //运行前接收一下距离1970年1月1日的时间
        long l1 = System.currentTimeMillis();
        for (int i = 0; i <= 10000; i++) {
            System.out.println(i);
        }
        //运行后接收一下距离1970年1月1日的时间
        long l2 = System.currentTimeMillis();
        //两次时间的时间差为中间代码的运行时间
        System.out.println(l2-l1+"毫秒");
    }
}
package basics.useClass.system;

//public static void exit(int status)
//终止当前运行的虚拟机,参数为状态代码(非0表示异常终止)
public class ExitTest01 {
    public static void main(String[] args) {
        System.out.println("开始!");
        System.exit(0);
        System.out.println("结束!");
    }
}

4.Object类

Student类

package basics.useClass.object;

//学生类
public class Student {
    private String name;
    private int age;

    public Student() {
    }

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

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

    //快捷键生成tostring方法
    @Override
    public String toString() {
        return "Student{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }

    // 快捷键生成equals和hashcode,然后删掉hashcode
    @Override
    public boolean equals(Object o) {   //s2做参数    o=s2
        //this=s1 ,比较地址是否相同,相同返回真
        if (this == o) return true;
        //如果参数s2是否为空 或者
        //两个对象的是否来自同一个类
        if (o == null || getClass() != o.getClass()) return false;

        //向下转型
        Student student = (Student) o;

        //比较年龄是否相同
        if (age != student.age) return false;
        //比较姓名内容是否相同
        return name != null ? name.equals(student.name) : student.name == null;
    }

}
package basics.useClass.object;

public class TestEquals01 {
    public static void main(String[] args) {
        Student s1 = new Student("张三", 18);
        Student s2 = new Student("张三", 18);

        //学生类中没有equals方法
        //s1做对象调用equals方法,s2做参数
        //他们比的是对象的地址,所以返回假
        System.out.println(s1.equals(s2));   //false
    }
}
package basics.useClass.object;

public class TestEquals02 {
    public static void main(String[] args) {
        Student s1 = new Student("张三", 18);

        Student s2 = new Student();
        s2.setName(" 张三");
        s2.setAge(18);

        //学生类中重写equals方法

    }
}
package basics.useClass.object;

public class TestToString01 {
    public static void main(String[] args) {
        Student student1 = new Student("张三", 18);

        Student student2 = new Student();
        student2.setName("李四");
        student2.setAge(19);

        /*
            public void println(Object x) {
            String s = String.valueOf(x);
            synchronized (this) {
                print(s);
                newLine();
              }
            }
         */

        /*
        public static String valueOf(Object obj) {
        return (obj == null) ? "null" : obj.toString();
    }
         */

        /*
        public String toString() {
        return getClass().getName() + "@" + Integer.toHexString(hashCode());
    }
         */

        //学生类中没有toString方法
        //调用println方法,然后一层一层的掉用。
        System.out.println(student1);   //basics.classTest.object.Student@1b6d3586
        System.out.println(student2);   //basics.classTest.object.Student@4554617c
    }
}
package basics.useClass.object;

public class TestToString02 {
    public static void main(String[] args) {
        Student student1 = new Student("张三", 18);

        Student student2 = new Student();
        student2.setName("李四");
        student2.setAge(19);

        //学生类中重写toString方法
        System.out.println(student1);    //Student{name='张三', age=18}
        System.out.println(student2);    //Student{name='李四', age=19}
    }
}

5.Arrays类

package basics.useClass.arrays;

import java.util.Arrays;

public class Demo06 {
    public static void main(String[] args) {
        int[] a = {1,5,55,62,12,41};

        System.out.println(a);

        //Arrays.toString  打印数组元素
        System.out.println(Arrays.toString(a));

        //Arrays.binarySearch  二分法查找某值 返回下标
        System.out.println(Arrays.binarySearch(a,55));

        //Arrays.fill  填充
        Arrays.fill(a,2,4,0);  //数组[a[2]~a[4])之间填充0
        System.out.println(Arrays.toString(a));

        //Arrays.sort  升序排序
        Arrays.sort(a);
        System.out.println(Arrays.toString(a));
    }
}

6.基本类型包装类

package basics.useClass.Integer;

//创建Integer
public class createInteger {
    public static void main(String[] args) {
        //该方法已过时
        Integer integer = new Integer(10);
        Integer integer1 = new Integer("100");
        System.out.println(integer);
        System.out.println(integer1);

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

        //使用该方法创建
        Integer integer2 = Integer.valueOf(20);
        Integer integer3 = Integer.valueOf("200");
        System.out.println(integer2);
        System.out.println(integer3);
    }
}
package basics.useClass.Integer;

/*
自动装箱和拆箱
装箱:把基本数据类型转换为对应的包装类类型
拆箱:把包装类类型转换为对应的基本数据类型

在使用包装类类型的时候,如果要做操作,先判断是否为null
只要是对象,在使用前必须进行是否为null判断
 */
public class IntAndInteger {
    public static void main(String[] args) {
        Integer integer1 = Integer.valueOf(10); //传统装箱
        Integer integer = 10;  //自动装箱:有隐藏的 Integer.valueOf(10)
        //把基本数据类型赋给对应的包装类类型,就是把基本数据类型转换为对应的包装类类型 即为 自动装箱
        System.out.println(integer);

        int i = integer + 30;  //int i = Integer.valueOf(10) + 30
        //integer为Integer类型,但是可以和int类型的30进行运算,是因为Integer类型的integer自动拆箱为int类型,然后进行计算
        System.out.println(i);

        Integer integer2 = integer + 40;  // Integer integer2 = Integer.valueOf(10) + 40  然后自动装箱
        // 40为int类型但是可以,但是可以和Integer类型的10进行计算,是因为因为Integer类型的integer自动拆箱为int类型,然后进行计算为int类型的数据,最后再进行自动装箱把int类型的转换为Integer类型
        System.out.println(integer2);

        Integer iii = null;
        //当为null的包装类类型和基本数据类型进行操作时会出现空指针异常
        //int i2 = iii + 10;
        //System.out.println(i2);//NullPointerException
        //Integer integer4 = iii + 10;
        //System.out.println(integer4);//NullPointerException

        //所以使用包装类类型进行操作的时候要进行不为空判断
        //只要是对象,在使用前就必须进行不为空判断
        if (iii != null){
            int i2 = iii + 10;
            System.out.println(i2);
            Integer integer4 = iii + 10;
            System.out.println(integer4);
        }
    }
}
package basics.useClass.Integer;

//int类型 和 String类型的相互转换
//int--->String   用String类中的String.valueOf(int i);    返回值为String
//String--->int   用Integer类中的Integer.parseInt(String s);   返回值为int类型
public class IntAndString {
    public static void main(String[] args) {
        //int--->String
        int a =10;
        System.out.println("int类型:" + a);
        //方法一:字符串拼接
        String str1 = "" + 10;
        System.out.println("方法一int类型转成String类型:" + str1);

        //方法二:
        String str2 = String.valueOf(a);
        System.out.println("方法二int类型转成String类型:" + str2);

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

        //String--->int
        String s = "10000";
        System.out.println("String类型:" + s);
        //方法一:String-->Ingeter-->int
        //String-->Ingeter
        Integer integer = Integer.valueOf(s);
        //Integer-->int    用对象名.intValue();
        int i = integer.intValue();
        System.out.println("方法一String类型转成int类型" + i);

        //方法二:String-->int
        //利用  Integer.parseInt(String s);   返回值为int类型
        int i1 = Integer.parseInt(s);
        System.out.println("方法二String类型转成int类型:" + s);
    }
}
package basics.useClass.Integer;

import java.util.Arrays;

//数字字符串排序
//有一个字符串:"91 27 46 38 50"    控制台输出:"27 38 46 50 91"
/*
思路:
1.定义一个字符串

2.把字符串中的数字数据存储到一个int类型的数组中
      得到字符串中每一个数字数据
      public StringO split(Stringregex)

      定义一个int数组,把String[]数组中的每一个元素存储到int数组中
       public static int parselnt(String s)
3。对int数组进行排序
4.把排序后的int数组中的元素进行拼接得到一个字符串,这里拼接采用StringBuilder来实现⑤输出结果i
5.输出结果
 */
public class StringSort {
    public static void main(String[] args) {
        String str = "91 27 46 38 50";
        //利用   String对象名.split(String str)   返回一个String类型的数组
        String[] split = str.split(" ");   //将字符串数据存到字符串数组中   参数表示用空格隔开
        int[] arr = new int[split.length];
        for (int i = 0; i < split.length; i++) {
            arr[i] = Integer.parseInt(split[i]);
        }

//        for (int i = 0; i < split.length; i++) {
//            System.out.println(split[i]);
//        }

        Arrays.sort(arr);

        StringBuilder stringBuilder = new StringBuilder();
        for (int i = 0; i < arr.length; i++) {
            if (i == arr.length-1){
                stringBuilder.append(arr[i]);
            }else {
                stringBuilder.append(arr[i]).append(" ");
            }
        }
        System.out.println(stringBuilder.toString());
    }
}

7.日期类

package basics.useClass.date;

import java.util.Date;

/*
public Data()   分配一个Data对象,并初始化,代表他被分配的时间,精确到毫秒
public Data(long date)  分配一个Data对象,并将其初始化为从标准基准时间起指定的毫秒数
 */
public class TestData01 {
    public static void main(String[] args) {
        Date date = new Date();
        System.out.println(date);

        Date date2 = new Date(1000 * 60 * 60);
        System.out.println(date2);
        Date date1 = new Date(System.currentTimeMillis());
        System.out.println(date1);
    }
}
package basics.useClass.date;

import java.util.Date;

public class TestData02 {
    public static void main(String[] args) {
        Date date = new Date();
        System.out.println(date.getTime());  获取的是日期对象从1970年1月1日00:00:00到现在的毫秒值

        date.setTime(1000);   //设置时间,参数为毫秒值
        System.out.println(date);
    }
}
package basics.useClass.date;

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

/*
创建方法:
         无参构造,使用默认模式和日期格式
         有参构造,使用给定的模式和默认的日期格式
             y M d H m s   年 月 日 时 分 秒
 */
//日期格式化和解析
public class TestSimpleDateFormat {
    public static void main(String[] args) {
        //1.日期格式化   Data--->String
        Date date = new Date();

        //无参构造创建,使用默认格式
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat();
        String s = simpleDateFormat.format(date);
        System.out.println(s);

        //有参构造创建,使用给定模式
        SimpleDateFormat simpleDateFormat1 = new SimpleDateFormat("yyyyMMddHHmmss");
        String s1 = simpleDateFormat1.format(date);
        System.out.println(s1);

        SimpleDateFormat simpleDateFormat2 = new SimpleDateFormat("yyyy年MM月dd日 HH:mm:ss");
        String s2 = simpleDateFormat2.format(date);
        System.out.println(s2);


        //日期解析   String--->Data
        String str = "2001-01-18 13:14:00";
        //SimpleDateFormat simpleDateFormat3 = new SimpleDateFormat();
        //SimpleDateFormat simpleDateFormat3 = new SimpleDateFormat("yyyy年MM月dd日 HH:mm:ss");
        SimpleDateFormat simpleDateFormat3 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");  //日期格式要与字符串格式一样
        try {
            Date date1 = simpleDateFormat3.parse(str);
            System.out.println(date1);  //ParseException    解析异常
        } catch (ParseException e) {
            e.printStackTrace();
        }
    }
}
package basics.useClass.date;

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

/*

定义把日期转化为指定的字符串的方法  dateToString
定义把字符串解析为指定的日期格式的方法   stringToDate
 */

//日期工具类
public class DateUtils {

    //定义把日期转化为指定的字符串的方法
    public  String dateToString(Date date,String format){
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat(format);
        String str = simpleDateFormat.format(date);
        return str;
    }

    //定义把字符串解析为指定的日期格式的方法
    public  Date stringToDare(String str,String format) throws ParseException {
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat(format);
        Date date = simpleDateFormat.parse(str);
        return date;
    }
}
package basics.useClass.date;

/*
定义一个日期工具类(DateUtils),包含两个方法,把日期转化为指定的字符串;把字符串解析为指定的日期格式,定义测试类进行测试

1.定义日期工具类  DateUtils
2.定义把日期转化为指定的字符串的方法  dataToString
3.定义把字符串解析为指定的日期格式的方法   stringToDate
4.定义测试类测试   DateDemo
 */

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

//测试类
public class DateDemo {
    public static void main(String[] args) {
        Date date = new Date();
        String s = new DateUtils().dateToString(date, "yyyy年MM月dd HH:mm:ss");
        System.out.println(s);

        System.out.println(new DateUtils().dateToString(date, "yyyy年MM月dd"));

        System.out.println(new DateUtils().dateToString(date, "HH:mm:ss"));


        try {
            Date date1 = new DateUtils().stringToDare("2001.01.18 13:14:00", "yyyy.MM.dd HH:mm:ss");
            System.out.println(date1);
        } catch (ParseException e) {
            e.printStackTrace();
        }
    }
}
package basics.useClass.date;

import java.util.Calendar;

// Calendar为某一时刻和一组日历字段之间的转换提供了一些方法,并未操作日历字段提供了一些方法
//Calendar提供了一个Calendar.getInstance()方法,用于获取Calendar对象,其日历字段已使用当前日期和时间初始化
//  Calendar rightNow = Calendar.getInstance();
public class TestCalendar1 {
    public static void main(String[] args) {
        //获取对象
        Calendar calendar = Calendar.getInstance();

        //获取日历字段的值
        int i = calendar.get(Calendar.YEAR);
        int i1 = calendar.get(Calendar.MONTH);
        int i2 = calendar.get(Calendar.DATE);

        System.out.println(i + "年" + i1 + "月" + i2);
    }
}
package basics.useClass.date;

import java.util.Calendar;

//Calendar 常用方法
public class TestCalendar2 {
    public static void main(String[] args) {
        Calendar instance = Calendar.getInstance();
        //返回给定日历字段的值
        int i = instance.get(Calendar.YEAR);
        System.out.println(i);
        System.out.println(instance.get(Calendar.MONTH));   //获取月份字段是从0开始所以要加一
        System.out.println(instance.get(Calendar.MONTH)+1);

        //根据日历的规则,将指定的时间量添加或者减去给定的日历字段
        instance.add(Calendar.DATE,1);
        System.out.println(instance.get(Calendar.DATE));

        instance.add(Calendar.YEAR,-2);
        System.out.println(instance.get(Calendar.YEAR));

        //设置当前日历的年月日
        instance.set(Calendar.YEAR,2000);
        int i3 = instance.get(Calendar.YEAR);
        instance.set(Calendar.MONTH,01);
        int i1 = instance.get(Calendar.MONTH);
        instance.set(Calendar.DATE,18);
        int i2 = instance.get(Calendar.DATE);
        System.out.println(i3 + "年" + i1 + "月" + i2);
    }
}
package basics.useClass.date;

import java.util.Calendar;

public class TestCalendar3 {
    public static void main(String[] args) {
        Calendar instance = Calendar.getInstance();

        //获取三年前的今天
        instance.add(Calendar.YEAR,-3);
        int year = instance.get(Calendar.YEAR);
        int month = instance.get(Calendar.MONTH)+1;
        int date = instance.get(Calendar.DATE);
        System.out.println(year + "." + month + "." + date);

        //获取10年后的5天前
        instance.add(Calendar.YEAR,10);
        instance.add(Calendar.DATE,-5);
        System.out.println(instance.get(Calendar.YEAR) + "." + (instance.get(Calendar.MONTH)+1) + "." + instance.get(Calendar.DATE));

        //获取1年后2月前3天后
        instance.add(Calendar.YEAR,1);
        instance.add(Calendar.MONTH,-2);
        instance.add(Calendar.DATE,3);
        System.out.println(instance.get(Calendar.YEAR) + "." + (instance.get(Calendar.MONTH)+1) + "." + instance.get(Calendar.DATE));
    }
}
package basics.useClass.date;

import java.util.Calendar;
import java.util.Scanner;

/*
二月天:获取任意一年的二月有多少天

1.键盘录入任意年份
2.设置日历对象的年,月,日
    年:键盘录入
    月:设置为3月,因为要加一,所以值为2
    日:设置为1日
3.三月一日往前一天几位二月的最后一天
4.输出
 */
public class TestCalendar4 {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        System.out.print("请输入年份:");
        int i = scanner.nextInt();

        Calendar instance = Calendar.getInstance();

        instance.set(Calendar.YEAR,i);
        instance.set(Calendar.MONTH,2);
        instance.set(Calendar.DATE,1);

        instance.add(Calendar.DATE,-1);

        System.out.println(i + "年的二月有" + instance.get(Calendar.DATE) + "天");
    }
}

集合框架

集合之间的的关系:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-YxUksuch-1651821374353)(F:\image\截屏\Screenshot_20220420-005111.jpg)]

  • ArrayList 和 LinkedList 是 List 接口的实现类——> List 接口继承 Collection 接口
  • HashSet 和 TreeSet 是 Set 接口的实现类——> Set 接口继承 Collection 接口
  • HashMap 是Map 接口的实现类
源码:
============================================================
    
Collection-List:
//迭代器接口
public interface Iterable<T>{}  

//Collection接口继承迭代器接口
public interface Collection<E> extends Iterable<E> {}

//List接口继承Collection接口
public interface List<E> extends Collection<E> {}

//ArrayList类实现了List接口
public class ArrayList<E> extends AbstractList<E> implements List<E>, RandomAccess, Cloneable, java.io.Serializable {}

//LinkedList类实现了List接口
public class LinkedList<E> extends AbstractSequentialList<E> implements List<E>, Deque<E>, Cloneable,
java.io.Serializable {}  

============================================================
Collection-Set:
//迭代器接口
public interface Iterable<T>{}  

//Collection接口继承迭代器接口
public interface Collection<E> extends Iterable<E> {}

//Set接口继承Collection接口
public interface Set<E> extends Collection<E>

//HashSet类实现了Set接口
public class HashSet<E> extends AbstractSet<E> implements Set<E>, Cloneable, java.io.Serializable {}

//TreeSet类实现了NavigableSet接口
public class TreeSet<E> extends AbstractSet<E> implements NavigableSet<E>, Cloneable, java.io.Serializable {}

//NavigableSet接口继承SortedSet接口
public interface NavigableSet<E> extends SortedSet<E> {}

//SortedSet接口继承Set接口
public interface SortedSet<E> extends Set<E> {}

所以TreeSet类也实现了Set接口


Map:
//Map接口
public interface Map<K,V> {}

//HashMap类实现了Map接口
public class HashMap<K,V> extends AbstractMap<K,V> implements Map<K,V>, Cloneable, Serializable {}

1.Collection

Collection集合的概述和使用

  • Collection集合的概述:
    1. 是单列集合的顶层接口,它表示一组对象,这些对象也成为Collection的元素
    2. JDK不提供此接口的任何直接实现,它提供更具体的子接口(如List和Set)实现
  • 创建Collection集合的对象:
    1. 多态的方式
    2. 具体的实现类ArrayList
package basics.list.collection;

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

//创建Collection集合的对象
//多态的方式
//具体的实现类ArrayList
public class TestCollection1 {
    public static void main(String[] args) {
        //创建Collection集合的对象
        Collection<String> list = new ArrayList<>();  //多态的形式

        //Collection集合的常用方法

        //添加元素,向集合中添加元素,返回值为Boolean,因为一定能添加成功,所以恒为真
        list.add("Hello");
        list.add("World");
        list.add("Java");
        list.add("JavaEE");

        System.out.println(list);   //内部重写了toString方法

        //删除元素,从集合删除指定的元素,返回值为boolean
        list.remove("JavaEE");
        System.out.println(list);

        //清除集合中的元素
        list.clear();

        //判断集合中是否存在指定的元素,返回值为boolean
        boolean contains = list.contains("JavaEE");
        System.out.println(contains);

        //判断集合是否为空,返回值为Boolean
        System.out.println(list.isEmpty());

        //获取集合的长度,也就是集合中元素的个数,返回值为int
        System.out.println(list.size());

    }
}
package basics.list.collection;

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

/*
Collection集合的遍历:
     Iterator<E> iterator  返回此集合的迭代器,通过iterator()方法
常用方法:
     E next():返回迭代中的下一个元素
     boolean hasNext():如果迭代器中有更多的元素,返回true;
 */
public class TestCollection2 {
    public static void main(String[] args) {
        Collection<String> list = new ArrayList<>();
        list.add("Hello");
        list.add("World");
        list.add("Java");

        Iterator<String> iterator = list.iterator();  //集合的迭代器

        /*
        //返回迭代中的下一个元素
        String list1 = iterator.next();
        System.out.println(list1);
        System.out.println(iterator.next());
        System.out.println(iterator.next());
        //iterator.next();  //NoSuchElementException   :表示被请求的元素不存在。    总共三个,返回第四个时就会报错
        boolean b = iterator.hasNext();
        System.out.println(b); //false  因为迭代器中没有元素了
        */

        /*
        if (iterator.hasNext()){
            System.out.println(iterator.next());
        }
        if (iterator.hasNext()){
            System.out.println(iterator.next());
        }
        if (iterator.hasNext()){
            System.out.println(iterator.next());
        }
        if (iterator.hasNext()){
            System.out.println(iterator.next());
        }
*/

        while (iterator.hasNext()){
            String s = iterator.next();
            System.out.println(s);
        }

    }
}
package basics.list.collection;


/*
创建一个存储学生对象的集合,存储三个学生对象,使用程序实现在控制台遍历该集合

 */

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

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

        Collection<Student> list = new ArrayList<Student>();

        Student student1 = new Student();
        student1.setName("张三");
        student1.setSex("男");
        student1.setAge(16);

        Student student2 = new Student();
        student2.setName("李四");
        student2.setSex("男");
        student2.setAge(18);

        Student student3 = new Student("小红", "女", 18);

        list.add(student1);
        list.add(student2);
        list.add(student3);

        Iterator<Student> iterator = list.iterator();
        while (iterator.hasNext()){
            System.out.println(iterator.next());
        }
    }
}




/*
package basics.list.collection;

//学生类
public class Student {
    private String name;
    private String sex;
    private int age;

    public Student() {
    }

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

    public String getName() {
        return name;
    }

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

    public String getSex() {
        return sex;
    }

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

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    @Override
    public String toString() {
        return
//                "name='" + name + '\'' +
//                ", sex='" + sex + '\'' +
//                ", age=" + age
//                ;
        "姓名:" + name + "  性别:" + sex + "  年龄:" + age;
    }
}
 */

2.List

List集合的概述和特点

  • List集合的概述:
    1. 有序集合(也称为序列),用户可以精确控制列表中的每个元素的插入位置。用户可以通过整数索引访问元素,并搜索列表中的元素
    2. 与Set集合不同,列表通常允许重复的元素
  • List集合的特点:
    1. 有序:存储和取出的元素顺序一致
    2. 可重复:存储的元素可以重复
package basics.listFrame.list;

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

//List集合特有方法
public class ListMethod {
    public static void main(String[] args) {
        List<String> list = new ArrayList<String>();

        list.add("Hello");
        list.add("World");
        list.add("Java");

        //在集合的指定位置插入元素
        list.add(1,"sw");
        list.add(3,"hhh");
        //list.add(10,"索引越界异常");    //IndexOutOfBoundsException

        //删除指定索引的元素,返回被删除的元素
        String remove = list.remove(3);
        System.out.println(remove);
        //list.remove(10);   //IndexOutOfBoundsException

        //修改指定索引的元素,返回被修改的元素
        String str = list.set(1, "你好");
        System.out.println(str);
        //list.set(10,"索引越界异常");   //IndexOutOfBoundsException

        //返回指定索引处的元素
        String s = list.get(1);
        System.out.println(s);
        //list.get(10);  //IndexOutOfBoundsException

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

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

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

        //2.迭代器遍历
        Iterator<String> iterator = list.iterator();
        while (iterator.hasNext()){
            String next = iterator.next();
            System.out.println(next);
        }
    }
}
package basics.listFrame.list;

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

创建一个存储学生对象的集合,存储三个学生对象,使用程序实现在控制台遍历该集合
public class StudentList {
    public static void main(String[] args) {
        List<Student> list = new ArrayList<Student>();

        Student student1 = new Student();
        student1.setName("张三");
        student1.setSex("男");
        student1.setAge(16);

        Student student2 = new Student();
        student2.setName("李四");
        student2.setSex("男");
        student2.setAge(18);

        Student student3 = new Student("小红", "女", 18);

        list.add(student1);
        list.add(student2);
        list.add(student3);

        //for循环按照输出语句格式遍历
        for (int i = 0; i < list.size(); i++) {
            System.out.println("姓名:" + list.get(i).getName() + ",性别:" + list.get(i).getSex() + ",年龄:" + list.get(i).getAge());
        }

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

        //for循环按照toString方法格式遍历
        for (int i = 0; i < list.size(); i++) {
            System.out.println(list.get(i));
        }

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

        //迭代器按照toString方法格式遍历
        Iterator<Student> iterator = list.iterator();
        while (iterator.hasNext()){
            Student next = iterator.next();
            System.out.println(next);
        }
    }
}





/*
package basics.listFrame.list;

//学生类
public class Student {
    private String name;
    private String sex;
    private int age;

    public Student() {
    }

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

    public String getName() {
        return name;
    }

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

    public String getSex() {
        return sex;
    }

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

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    @Override
    public String toString() {
        return
//                "name='" + name + '\'' +
//                ", sex='" + sex + '\'' +
//                ", age=" + age
//                ;
        "姓名:" + name + "  性别:" + sex + "  年龄:" + age;
    }
}

 */

并发修改异常:

package basics.listFrame.collection.list;

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

public class ConcurrentModififcationException {
    public static void main(String[] args) {
        List<String> list = new ArrayList<String>();

        list.add("Hello");
        list.add("World");
        list.add("Java");

       /*
        //这样做会出现并发修改异常
        Iterator<String> iterator = list.iterator();

        while(iterator.hasNext()){
            String s = iterator.next();  //ConcurrentModificationException   并发修改异常
            if (s.equals("World")){
                list.add("SW");
            }

        }
        */



        //解决办法:用for循环遍历,操作
        for (int i = 0; i < list.size(); i++) {
            String s = list.get(i);
            if (s.equals("World")){
                list.add("SW");
            }
            System.out.println(s);
        }

    }
}
    public static void main(String[]args){
        List<String> list=new ArrayList<String>();

        list.add("Hello");
        list.add("World");
        list.add("Java");

        Iterator<String> iterator=list.iterator();

        while(iterator.hasNext()){
        String s=iterator.next();  //ConcurrentModificationException   并发修改异常
        if(s.equals("World")){
           list.add("SW");
        }
    }
}


public class ArrayList<E> extends AbstractList<E> implements List<E>, RandomAccess, Cloneable, java.io.Serializable {
    public boolean add(E e) {
        ensureCapacityInternal(size + 1);  // Increments modCount!!
        elementData[size++] = e;
        return true;
    }

    private void ensureCapacityInternal(int minCapacity) {
        ensureExplicitCapacity(calculateCapacity(elementData, minCapacity));
    }

    private void ensureExplicitCapacity(int minCapacity) {
        modCount++;

        // overflow-conscious code
        if (minCapacity - elementData.length > 0)
            grow(minCapacity);
    }
}


private class Itr implements Iterator<E> {

    int expectedModCount = modCount;

    public boolean hasNext() {
        return cursor != size;
    }

    @SuppressWarnings("unchecked")
    public E next() {
        checkForComodification();
        int i = cursor;
        if (i >= size)
            throw new NoSuchElementException();
        Object[] elementData = ArrayList.this.elementData;
        if (i >= elementData.length)
            throw new ConcurrentModificationException();
        cursor = i + 1;
        return (E) elementData[lastRet = i];
    }

    final void checkForComodification() {
                if (modCount != expectedModCount)
                    throw new ConcurrentModificationException();
    }
}




在调用ArrayList中的add方法时,会对modCount++;

然后调用迭代器Iterator,进行 int expectedModCount = modCount; 此时他们还是相等的,在调用checkForComodification()方法的时候,进行 if (modCount != expectedModCount) 判断,因为int expectedModCount = modCount;所以判断为假,所以不会抛出异常,
当在while循环中进行if判断之后,又进行添加,所以modCount++,modCount++的值变大,而只有在调用迭代器时才会int expectedModCount = modCount; 但是在while循环中进行if判断之后进行的添加没有调用迭代器,所以modCount++,modCount的值变大,而expectedModCount的值没有变化,
所以在调用checkForComodification()时,进行 if (modCount != expectedModCount) 判断,又因为modCount的值变大,而expectedModCount的值没有变化,所以modCount != expectedModCount,所以为真,所以throw new ConcurrentModificationException();  就会抛出并发修改异常

产生原因总结:迭代器遍历的过程中,通过集合对象修改了集合中元素的长度,造成了迭代器获取元素中判断预期修改值和实际修改值不一致
解决方案:用for循环遍历,然后用集合对象做对应的操作即可

ListIterator

package basics.listFrame.collection.list;

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

/*
TestListIterator:列表迭代器
通过List集合的listIterator方法得到,是List集合特有的迭代器
 */
public class TestListIterator {
    public static void main(String[] args) {
        List<String> list = new ArrayList<>();

        list.add("Hello");
        list.add("World");
        list.add("Java");

        ListIterator<String> str = list.listIterator();
        //顺序遍历
        while (str.hasNext()){
            String next = str.next();
            if (next.equals("World")){
                //list.add("SW");  //用集合对象调用add方法也会抛出并发修改异常
                //listIterator中的add()方法:
                str.add("SW");   //需要用ListIterator对象去调用add方法添加
            }
        }

        //倒序遍历
        while (str.hasPrevious()){
            String previous = str.previous();
//            if (previous.equals("SW")){
//                str.add("HH");
//            }
            System.out.println(previous);
        }

        System.out.println(list);
    }
}

增强for循环

package basics.listFrame.collection.list;

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

/*
增强for循环:简化数组和Collection集合的遍历
  for (数据类型 变量名: 集合名){             //数据类型要和集合数据类型一致,变量名即为集合中元素名
            ...
        }
 */

public class SuperFor {
    public static void main(String[] args) {
        List<String> list = new ArrayList<>();

        list.add("Hello");
        list.add("World");
        list.add("Java");

        for (String s:list){
            if (s.equals("World")){
                list.add("SW");
            }
            System.out.println(s);
        }

        /*
        //其内部原理为迭代器
        for (String s:list){
            if (s.equals("World")){
                list.add("SW");   //ConcurrentModificationException
            }
            System.out.println(s);
        }
         */
    }
}
package basics.listFrame.collection.list;

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

//创建一个存储学生对象的集合,存储三个学生对象,使用程序实现在控制台遍历该集合
public class StudentList2 {
    public static void main(String[] args) {
        List<Student> list = new ArrayList<>();

        Student student1 = new Student("张三", "男", 18);
        Student student2 = new Student("李四", "男", 20);

        Student student3 = new Student();
        student3.setName("小红");
        student3.setSex("女");
        student3.setAge(18);

        list.add(student1);
        list.add(student2);
        list.add(student3);

        //遍历
        //1.普通for循环
        for (int i = 0; i < list.size(); i++) {
            Student student = list.get(i);
            System.out.println(student.getName()+student.getSex()+student.getAge());
        }

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

        //2.迭代器遍历
        ListIterator<Student> slt = list.listIterator();
        while (slt.hasNext()){
            Student next = slt.next();
            System.out.println(next.getName() + next.getSex() + next.getAge());
        }

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

        //3.增强for循环遍历
        for (Student s : list){
            System.out.println(s.getName()+s.getSex()+s.getAge());
        }
    }
}

数据结构之数组:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-7RoForLg-1651821374354)(C:\Users\86177\AppData\Roaming\Typora\typora-user-images\image-20220424204652918.png)]

数据结构之链表

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-zcTjzE4Q-1651821374355)(C:\Users\86177\AppData\Roaming\Typora\typora-user-images\image-20220424204722044.png)]

LinkedList和ArrayList

package basics.listFrame.collection.list;

import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import java.util.ListIterator;

/*
ArrayList:底层数据结构为数组,查询快,增删慢
LinkedList:底层数据结构为链表,增删快,查询慢
 */
public class TestList {
    public static void main(String[] args) {
        List<String> list1 = new ArrayList<>();

        list1.add("Hello");
        list1.add("World");
        list1.add("Java");

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

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

        ListIterator<String> slt = list1.listIterator();
        while (slt.hasNext()){
            System.out.println(slt.next());
        }

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

        for (String s : list1){
            System.out.println(s);
        }

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

        List<String> list2 = new LinkedList<>();

        list2.add("Hello2");
        list2.add("World2");
        list2.add("Java2");

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

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

        ListIterator<String> str = list2.listIterator();
        while (str.hasNext()){
            System.out.println(str.next());
        }

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

        for (String s : list2){
            System.out.println(s);
        }
    }
}
package basics.listFrame.collection.list;

import java.util.ArrayList;
import java.util.ListIterator;

//创建一个存储学生对象的集合,存储三个学生对象,使用程序实现在控制台遍历该集合
public class StudentArrayList {
    public static void main(String[] args) {
        ArrayList<Student> students = new ArrayList<>();

        Student student1 = new Student("张三", "男", 18);
        Student student2 = new Student("李四", "男", 20);

        Student student3 = new Student();
        student3.setName("小红");
        student3.setSex("女");
        student3.setAge(18);

        students.add(student1);
        students.add(student2);
        students.add(student3);

        //遍历
        for (int i = 0; i < students.size(); i++) {
            Student student = students.get(i);
            System.out.println(student);
        }

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

        ListIterator<Student> slt = students.listIterator();
        while (slt.hasNext()){
            System.out.println(slt.next());
        }

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

        for (Student s : students){
            System.out.println(s);
        }

    }
}




/*
package basics.listFrame.collection.list;

//学生类
public class Student {
    private String name;
    private String sex;
    private int age;

    public Student() {
    }

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

    public String getName() {
        return name;
    }

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

    public String getSex() {
        return sex;
    }

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

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    @Override
    public String toString() {
        return
//                "name='" + name + '\'' +
//                ", sex='" + sex + '\'' +
//                ", age=" + age
//                ;
        "姓名:" + name + "  性别:" + sex + "  年龄:" + age;
    }
}

 */

LinkedList

package basics.listFrame.collection.list;

import java.util.LinkedList;

//LinkedList集合的特有功能
public class LinkedListMethod {
    public static void main(String[] args) {
        LinkedList<String> list = new LinkedList<>();

        list.add("Hello");
        list.add("World");
        list.add("Java");

        //在该列表开头插入指定元素
        list.addFirst("First");

        //将指定的元素追加到此列表末尾
        list.addLast("Last");

        //返回此列表中的第一个元素
        System.out.println(list.getFirst());

        //返回此列表中的最后一个元素
        String last = list.getLast();
        System.out.println(last);

        //从此列表中删除并返回第一个元素
        String s1 = list.removeFirst();
        System.out.println(s1);

        //从此列表中删除并返回最后一个元素
        System.out.println(list.removeLast());


        System.out.println("===============");
        for (String s : list){
            System.out.println(s);
        }
    }
}

3.Set

Set集合的概述和特点

  • Set集合的特点
    1. 不包含重复元素的集合
    2. 没有带索引的方法,所以不能用普通的for循环遍历
package basics.listFrame.collection.set;

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

/*
Set集合:
不包含重复元素
没有带索引的方法,不能用普通for循环遍历,
HashSet对集合的迭代次序不作任何保证;
 */
public class TestSet {
    public static void main(String[] args) {
        Set<String> set = new HashSet<>();

        set.add("Hello");
        set.add("World");
        set.add("Java");

        set.add("Java");

        Iterator<String> iterator = set.iterator();
        while (iterator.hasNext()){
            System.out.println(iterator.next());
        }

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

        for (String s : set){
            System.out.println(s);
        }
    }
}

哈希值

package basics.listFrame.collection.set;

/*
哈希值:jdk根据对象的地址或者字符串或者数字算出来的interesting类型的值

Object类中的hashCode()方法可以获取对象的哈希值
 */
public class GetHashCode {
    public static void main(String[] args) {
        Student student1 = new Student("张三", "男", 18);
        Student student2 = new Student("李四", "男", 20);
        Student student3 = new Student("小红", "女", 18);

        //默认情况下,不同对象的哈希值是不同的,但是如果重写了hashCode方法,可以让不同对象的哈希值相同
        //重写前
        int i = student1.hashCode();
        System.out.println(i);   //460141958
        System.out.println(student2.hashCode());  //1163157884
        System.out.println(student2.hashCode());  //1163157884   同一个对象多次调用hashCode返回的哈希值是相同的
        System.out.println(student3.hashCode());  //1956725890

        //重写后
        System.out.println(i);   //0
        System.out.println(student2.hashCode());  //0
        System.out.println(student2.hashCode());  //0
        System.out.println(student3.hashCode());  //0


        System.out.println("=========================");
        String s1 = "Hello";
        String s2 = "World";
        String s3 = "Java";

        System.out.println(s1.hashCode());
        System.out.println(s2.hashCode());
        System.out.println(s2.hashCode());
        System.out.println(s3.hashCode());

        String str1 = "重地";   //1179395
        String str2 = "通话";   //1179395

        System.out.println(str1.hashCode());
        System.out.println(str2.hashCode());
    }
}





/*
package basics.listFrame.collection.set;

//学生类
public class Student implements Comparable<Student>{
    private String name;
    private String sex;
    private int age;

    public Student() {
    }

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

    public String getName() {
        return name;
    }

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

    public String getSex() {
        return sex;
    }

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

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    @Override
    public String toString() {
        return
//                "name='" + name + '\'' +
//                ", sex='" + sex + '\'' +
//                ", age=" + age
//                ;
        "姓名:" + name + "  性别:" + sex + "  年龄:" + age;
    }

    @Override
    public int hashCode() {
        int result = name != null ? name.hashCode() : 0;
        result = 31 * result + (sex != null ? sex.hashCode() : 0);
        result = 31 * result + age;
        //重写前
        return result;

        //重写后
        //return 0;
    }
 */

HashSet集合保证元素唯一性的分析:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-o895vhpD-1651821374355)(F:\image\截屏\Snipaste_2022-04-24_21-04-02.png)]

HashSet集合的概述和特点

package basics.listFrame.collection.set;

import java.util.HashSet;
import java.util.Iterator;

/*
HashSet:
  底层数据结构为哈希表(数组+链表)
  对集合的迭代顺序不做保证(不保证存储和取出的顺序一致)
  没有带索引的方法,不能用普通for循环遍历
  由于是Set集合,所以不包含重复的元素(要保证元素唯一性,需要重写hashCode()和equals()方法)
 */
public class TestHashSet {
    public static void main(String[] args) {
        HashSet<String> set = new HashSet<>();

        set.add("Hello");
        set.add("World");
        set.add("Java");

        set.add("World");

        for (String s : set){
            System.out.println(s);
        }

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

        Iterator<String> iterator = set.iterator();
        while (iterator.hasNext()){
            System.out.println(iterator.next());
        }
    }
}

哈希表

jdk8之前,底层采用数组+链表实现,可以说是一个元素为链表的数组

jdk8以后,在长度较长的时候,底层实现了优化

package basics.listFrame.collection.set;

import java.util.HashSet;

/*
创建一个存储学生对象的集合,存储多个学生对象,在控制台遍历,当学生对象的成员变量值相同,就认为是一个对象

1.定义学生类
2.创建HashSet集合对象
3.创建学生对象
4.把学生添加到集合
5.遍历集合(增强for循环)
6.在学生类中重写hashCode和equals方法,自动生成即可(为了判断是同一个学生对象)
 */
public class StudentHashSet {
    public static void main(String[] args) {
        HashSet<Student> set = new HashSet<>();

        Student student1 = new Student("张三", "男", 18);
        Student student2 = new Student("李四", "男", 20);
        Student student3 = new Student("小红", "女", 18);

        Student student4 = new Student("小红", "女", 18);

        set.add(student1);
        set.add(student2);
        set.add(student3);
        set.add(student4);

        for (Student s : set){
            System.out.println(s);
        }
    }
}




/*
package basics.listFrame.collection.set;

//学生类
public class Student implements Comparable<Student>{
    private String name;
    private String sex;
    private int age;

    public Student() {
    }

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

    public String getName() {
        return name;
    }

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

    public String getSex() {
        return sex;
    }

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

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    @Override
    public String toString() {
        return
//                "name='" + name + '\'' +
//                ", sex='" + sex + '\'' +
//                ", age=" + age
//                ;
        "姓名:" + name + "  性别:" + sex + "  年龄:" + age;
    }

    @Override
    public int hashCode() {
        int result = name != null ? name.hashCode() : 0;
        result = 31 * result + (sex != null ? sex.hashCode() : 0);
        result = 31 * result + age;
        //重写前
        return result;

        //重写后
        //return 0;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;

        Student student = (Student) o;

        if (age != student.age) return false;
        if (name != null ? !name.equals(student.name) : student.name != null) return false;
        return sex != null ? sex.equals(student.sex) : student.sex == null;
    }

    @Override
    public int compareTo(Student o) {
        //return 0;     //返回值为0,只添加一个对象到集合
        //return 1;     //返回值为正数,把集合中的对象按添加的顺序取出
       // return -1;      //返回值为负数,把集合中的对象按添加的顺序的反序取出
        //int num = this.age - o.age;  //年龄从小到大
        //int num = o.age - this.age;   //年龄从大到小

        //三元运算符:   如果num==0,说明其年龄相同,如果为真(也就是相同),this.name.compareTo(o.name)  就让他们进行自然排序,如果为假(说明不相同),就依然让他们按照年龄进行排序
        //int num = this.age - o.age;
        //int num2 = num == 0 ? this.name.compareTo(o.name):num;
        //return num2;

        //上面三句话简化为一句
        return this.age - o.age == 0 ? this.name.compareTo(o.name):this.age - o.age;

    }
}

 */

LinkedHashSet

package basics.listFrame.collection.set;

/*
LinkedHashSet集合的特点:
  哈希表和链表实现的Set接口,具有可预测的迭代次序
  由链表保证元素有序,元素的存储和取出顺序一致
  由哈希表保证元素唯一,没有重复的元素
 */

import java.util.LinkedHashSet;

public class TestLinkedHashSet {
    public static void main(String[] args) {
        LinkedHashSet<String> s = new LinkedHashSet<>();

        s.add("Hello");
        s.add("World");
        s.add("Java");

        s.add("Java");

        for (String ss : s){
            System.out.println(ss);
        }
    }
}

TreeSet

package basics.listFrame.collection.set;

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

/*
TreeSet集合的特点:
   元素有序,不是存储和取出的顺序,而是按照一定的规则进行排序,具体的排序方法取决于构造方法
        TreeSet():根据其元素的自然排序进行排序
        TreeSet(Comparator comparator):根据指定的比较器进行排序
    没有带索引的方法,不能用普通for循环遍历
    由于是Set集合,所以不包含重复元素
 */
public class TestTreeSet {
    public static void main(String[] args) {
        TreeSet<Integer> s = new TreeSet<>();

        s.add(10);
        s.add(30);
        s.add(50);
        s.add(20);
        s.add(40);

        s.add(50);

        for (int ss : s){
            System.out.println(ss);
        }
    }
}

自然排序Comparable

package basics.listFrame.collection.set;

import java.util.TreeSet;

/*
自然排序Comparable的使用
    存储学生对象并遍历,创建TreeSet集合使用无参构造方法
    按照年龄从小到大排序,如果年龄相同按照名字字母顺序排序

    结论:用TreeSet集合存储自定义对象,无参构造方法使用的是自然排序对元素进行排序的
         自然排序就是   让元素所属的类实现Comparable接口  ,重写compareTo(T o)方法
         重写方法时,一定要注意排序规则按照要求的主要条件和次要条件来写
 */
public class TestComparable {
    public static void main(String[] args) {
        TreeSet<Student> set = new TreeSet<>();

        Student student1 = new Student("张三", "男", 19);
        Student student2 = new Student("李四", "男", 18);
        Student student3 = new Student("wangwu", "男", 23);
        Student student4 = new Student("小红", "女", 20);
        Student student5 = new Student("xiaoming", "男", 23);

        /*
        @Override
         public int compareTo(Student o) {
            int num = this.age - o.age;  //年龄从小到大
            return num;
        }


        1.o.age = 19                                                                           19
        2.this.age = 18   o.age = 19    this.age-o.age = -1(负数)       按照存储的反序排序         18,19
        3.this.age = 23   o.age = 19    this.age-o.age = 4(正数)        按照存储的顺序排序         18,19,23
        4.this.age = 20   o.age = 23    this.age-o.age = -1(负数)       按照存储的反序排序         18,19,20,23
        5.this.age = 23   o.age = 23    this.age-o.age = 0              只存储一个               18,19,20,23,23
         */

        set.add(student1);
        set.add(student2);
        set.add(student3);
        set.add(student4);
        set.add(student5);

        for (Student s : set){
            System.out.println(s);
        }
    }
}





/*
package basics.listFrame.collection.set;

//学生类
public class Student implements Comparable<Student>{
    private String name;
    private String sex;
    private int age;

    public Student() {
    }

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

    public String getName() {
        return name;
    }

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

    public String getSex() {
        return sex;
    }

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

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    @Override
    public String toString() {
        return
//                "name='" + name + '\'' +
//                ", sex='" + sex + '\'' +
//                ", age=" + age
//                ;
        "姓名:" + name + "  性别:" + sex + "  年龄:" + age;
    }

    @Override
    public int hashCode() {
        int result = name != null ? name.hashCode() : 0;
        result = 31 * result + (sex != null ? sex.hashCode() : 0);
        result = 31 * result + age;
        //重写前
        return result;

        //重写后
        //return 0;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;

        Student student = (Student) o;

        if (age != student.age) return false;
        if (name != null ? !name.equals(student.name) : student.name != null) return false;
        return sex != null ? sex.equals(student.sex) : student.sex == null;
    }

    @Override
    public int compareTo(Student o) {
        //return 0;     //返回值为0,只添加一个对象到集合
        //return 1;     //返回值为正数,把集合中的对象按添加的顺序取出
       // return -1;      //返回值为负数,把集合中的对象按添加的顺序的反序取出
        //int num = this.age - o.age;  //年龄从小到大
        //int num = o.age - this.age;   //年龄从大到小

        //三元运算符:   如果num==0,说明其年龄相同,如果为真(也就是相同),this.name.compareTo(o.name)  就让他们进行自然排序,如果为假(说明不相同),就依然让他们按照年龄进行排序
        //int num = this.age - o.age;
        //int num2 = num == 0 ? this.name.compareTo(o.name):num;
        //return num2;

        //上面三句话简化为一句
        return this.age - o.age == 0 ? this.name.compareTo(o.name):this.age - o.age;

    }
}

 */

比较器Conparator

package basics.listFrame.collection.set;

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

/*
比较器Comparator的使用
    存储学生对象并遍历,创建TreeSet集合使用有参构造方法
    按照年龄从小到大排序,如果年龄相同按照名字字母顺序排序

    结论:用TreeSet集合存储自定义对象,有参构造方法使用的是比较器排序对元素进行排序的
         比较器排序,就是让集合构造方法接收Comparator的实现类对象,重写Compare(T o1,T o2)方法
         重写方法时,一定要注意排序规则按照要求的主要条件和次要条件来写
 */
public class TestComparator {
    public static void main(String[] args) {
        TreeSet<Student2> students = new TreeSet<>(new Comparator<Student2>() {
            @Override
            public int compare(Student2 o1, Student2 o2) {
                return o1.getAge() - o2.getAge() == 0 ? o1.getName().compareTo(o2.getName()) : o1.getAge() - o2.getAge();
            }
        });


        Student2 student1 = new Student2("张三", "男",19);
        Student2 student2 = new Student2("李四", "男", 18);
        Student2 student3 = new Student2("wangwu", "男", 23);
        Student2 student4 = new Student2("小红", "女", 20);
        Student2 student5 = new Student2("xiaoming", "男",23 );

        students.add(student1);
        students.add(student2);
        students.add(student3);
        students.add(student4);
        students.add(student5);

        for (Student2 s : students){
            System.out.println(s);
        }
    }
}

成绩排序

package basics.listFrame.collection.set;

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

/*
用TreeSet集合存储多个学生信息(姓名,语文成绩,数学成绩),并遍历该集合,要求分数从高到低
 */
public class GradesSort {
    public static void main(String[] args) {
        TreeSet<Student3> set = new TreeSet<>(new Comparator<Student3>() {
            @Override
            public int compare(Student3 o1, Student3 o2) {
                //首先按照总成绩由高到低,如果分数相同,则按照语文成绩由高到低,如果语文成绩相同,则按照数学成绩由高到低
                int num = (o2.getLanguage() + o2.getMath()) - (o1.getLanguage() + o1.getMath());//按照总成绩由高到低
                if (num == 0) {
                    int num2 = o2.getLanguage() - o1.getLanguage(); //按照语文成绩由高到低
                    if (num2 == 0) {
                        int num3 = o2.getMath() - o1.getMath(); //按照数学成绩由高到低
                        return num3;
                    }
                    return num2;
                }
                return num;
            }
        });

        Student3 student1 = new Student3();
        student1.setName("张三");
        student1.setLanguage(82);
        student1.setMath(92);

        Student3 student2 = new Student3();
        student2.setName("李四");
        student2.setLanguage(75);
        student2.setMath(82);

        Student3 student3 = new Student3();
        student3.setName("王五");
        student3.setLanguage(64);
        student3.setMath(58);

        Student3 student4 = new Student3();
        student4.setName("小红");
        student4.setLanguage(90);
        student4.setMath(80);

        Student3 student5 = new Student3();
        student5.setName("小明");
        student5.setLanguage(92);
        student5.setMath(82);

        set.add(student1);
        set.add(student2);
        set.add(student3);
        set.add(student4);
        set.add(student5);

        for (Student3 s : set){
            System.out.println("姓名:" + s.getName() + " 语文:" + s.getLanguage() + "  数学:" + s.getMath());
        }
    }
}

不重复的随机数

package basics.listFrame.collection.set;

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

/*
编写一个程序,获取10个1-20之间的随机数,要求随机数不能重复,并在控制台输出
 */
public class Number {
    public static void main(String[] args) {
        //利用Set集合的特点,元素不重复
        Set<Integer> set = new HashSet<>();

        //用while循环进行循环获取并添加
        while (true){
            Random random = new Random();
            int i = random.nextInt(20) + 1;

            set.add(i);   //如果获取到相同的随机数,添加不到集合,只有获取到不同的才能添加到集合


            //当集合的长度为10时break;退出循环
            if (set.size() == 10){
                break;
            }
        }

        //遍历
        for (int i : set){
            System.out.println(i);
        }
    }
}

泛型

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-8OqTi9LR-1651821374356)(D:\数据\QQ数据\MobileFile\Screenshot_20220424-234601.jpg)]

泛型类:
package basics.listFrame.genericity;

/*
泛型类
public class 类名<T>{}
 */
public class Genericity <T>{
    private T t;

    public T getT() {
        return t;
    }

    public void setT(T t) {
        this.t = t;
    }
}




package basics.listFrame.genericity;

//测试类
public class Application {
    public static void main(String[] args) {
        //测试泛型类
        Genericity<String> sg = new Genericity<>();
        sg.setT("张三");
        //sg.setT(100);    把运行时的错误提前到编译时
        System.out.println(sg.getT());

        Genericity<Integer> ig = new Genericity<>();
        ig.setT(100);
        System.out.println(ig.getT());

        Genericity<Boolean> bg = new Genericity<>();
        bg.setT(true);
        System.out.println(bg.getT());
    }
}
泛型方法:
package basics.listFrame.genericity;

/*
泛型方法
public <T> 返回值类型 方法名(T t){}
 */
public class GenericityMethod {
    public <T> void show(T t){
        System.out.println(t);
    }
}



package basics.listFrame.genericity;

import org.omg.CORBA.StringHolder;

//测试类
public class Application {
    public static void main(String[] args) {
        //测试泛型方法
        GenericityMethod gm = new GenericityMethod();
        gm.show("张三");
        gm.show(100);
        gm.show(true);
        gm.show(23.344);
        gm.show('a');

    }
}
泛型接口:
package basics.listFrame.genericity;

/*
泛型接口
public interface 接口名 <T>{
    返回值类型 方法名(T t);
}
 */
public interface GenericityInterface <T>{
    void show(T t);
}


package basics.listFrame.genericity;

/*
泛型接口实现类
public class 泛型实现类名 <T> implements 被实现的泛型接口 <T>{
    //泛型接口的方法重写
    @Override
    public 泛型接口的返回值类型 泛型接口的方法名(T t) {

    }
}
 */
public class GenericityInterfaceImpl <T> implements GenericityInterface <T>{
    @Override
    public void show(T t) {
        System.out.println(t);
    }
}



package basics.listFrame.genericity;

import org.omg.CORBA.StringHolder;

//测试类
public class Application {
    public static void main(String[] args) {
        //测试泛型接口
        GenericityInterface<String> sgi = new GenericityInterfaceImpl<>();//多态
        sgi.show("张三");
        //sgi.show(100);
        GenericityInterface<Integer> sgi1 = new GenericityInterfaceImpl<>();
        sgi1.show(100);


    }
}
类型通配符

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-PDLrtFQH-1651821374356)(D:\数据\QQ数据\MobileFile\Screenshot_20220425-001411.jpg)]

package basics.listFrame.genericity;

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

/*
    类型通配符:  <?>
        List<?> :表示元素类型未知的List,它的元素可以匹配任何的类型
        这种通配符的List仅表示他是各种泛型List的父类,并不能把元素添加到其中
     类型通配符上限: <? extends 类型>
        List<? extends Number>  表示的类型是Number或者其子类型
     类型通配符下限: <? super 类型>
        List<? super Number>  表示的类型是Number或者其父类型
 */
public class Application1 {
    public static void main(String[] args) {
        //类型通配符:  <?>
        List<?> list1 = new ArrayList<Object>();
        List<?> list2 = new ArrayList<String>();
        List<?> list3 = new ArrayList<Number>();

        //类型通配符上限  <? extends 类型>
        List<? extends Number> list4 = new ArrayList<Number>();
        //List<? extends Number> list5 = new ArrayList<Object>();   //因为Object类不是 Number的子类
        List<? extends Number> list5 = new ArrayList<Integer>();
        //List<? extends Number> list6 = new ArrayList<Boolean>();  因为Boolean类不是 Number的子类
        List<? extends Number> list7 = new ArrayList<Double>();

        //类型通配符下限  <? super 类型>
        List<? super Number> list8 = new ArrayList<Number>();
        List<? super Number> list9 = new ArrayList<Object>();
        //List<? super Number> list10 = new ArrayList<Integer>();   因为Integer类不是Number的父类
    }
}
可变参数

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-8IjZohA6-1651821374357)(D:\数据\QQ数据\MobileFile\Screenshot_20220425-002442.jpg)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-OzzcRAWt-1651821374357)(D:\数据\QQ数据\MobileFile\Screenshot_20220425-003321.jpg)]

package basics.listFrame.genericity;

//可变参数(本质是数组)
public class ChangeParameter {
    //n个数的加法
    public int sum(int... a){
        int sum = 0;
        for (int i : a){
            sum = sum + i;   //sum += i
        }
        System.out.println("可变参数");
        return sum;
    }

    public int sum(int a){
        System.out.println("不可变参数");
        return a;
    }

    //当有多个参数时,可变参数只能有一个并且要放到最后面
    public int sum1(int b,int...a){
        int sum = 0;
        for (int i : a){
            sum = sum + i;   //sum += i
        }
        return sum;
    }
}



package basics.listFrame.genericity;
//测试类
public class Application3 {
    public static void main(String[] args) {
        ChangeParameter c = new ChangeParameter();
        System.out.println(c.sum(1));  //优先调用不可变参数
        System.out.println(c.sum(1,2));
        System.out.println(c.sum(1,2,3));
        System.out.println(c.sum(1,2,3,4));
        System.out.println(c.sum(1,2,3,4,5));

        System.out.println(c.sum1(1, 2));
        System.out.println(c.sum1(1, 2,3));
        System.out.println(c.sum1(1, 2,3,4));
        System.out.println(c.sum1(1, 2,3,4,5));
    }
}
package basics.listFrame.genericity;

import java.util.Arrays;
import java.util.List;

/*
可变参数的使用
    Arrays类中有一个静态方法:
        public static <T> asList(T... a),返回由指定数组支持的固定大小的列表

    List接口中有一个静态方法:(JDK8和JDK8以下的没有)
        public static <E> List<E> of (E... elements),返回包含任意数量元素的不可变列表

    Set接口中有一个静态方法:(JDK8和JDK8以下的没有)
        public static <E> Set<E> of (E... elements),返回一个包含任意数量元素的不可变列集合
 */
public class TestChangeParameter {
    public static void main(String[] args) {
        //public static <T> asList(T... a),返回由指定数组支持的固定大小的列表
        //可以修改,不能增删
        List<String> list = Arrays.asList("Hello", "World", "Java");
        list.add(1, "SW");    //UnsupportedOperationException    表示不支持请求的操作。
        list.remove(1);      //UnsupportedOperationException
        list.set(1, "Sw");
        System.out.println(list.get(1));
        System.out.println(list);
    }
}

Map

1.Map集合的概述和使用

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-cs3VXgWG-1651821374357)(F:\image\图片\Screenshot_20220425-232140.jpg)]

package basics.listFrame.map;

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

//Map集合的使用
public class TestMap {
    public static void main(String[] args) {
        //创建Map集合对象
        Map<Integer,String> map = new HashMap<>();

        //添加元素,Map集合里面没有这个元素就返回null,有这个元素就返回这个元素的值
        map.put(1,"张三");
        map.put(2,"李四");
        map.put(3,"王五");
        map.put(4,"李六");

        map.put(4,"小明");  //当键相同进行添加元素的时候为修改,即键对应的第二个值覆盖掉第一个

        //Map集合中重写的tiString方法拼接
        System.out.println(map);
    }
}

2.Map集合的基本功能

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-85hyCmre-1651821374358)(F:\image\图片\Screenshot_20220425-232717.jpg)]

package basics.listFrame.map;

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

//Map集合的基本功能
public class MapMethod {
    public static void main(String[] args) {
        Map<String,String> map = new HashMap<>();

        //添加元素
        map.put("张", "张三");
        map.put("李","李四");
        map.put("王","王五");
        map.put("马","马六");

        //根据键删除元素,删除成功,返回删除键对应的值;删除失败,返回null
//        System.out.println(map.remove("马"));
//        System.out.println(map.remove("杨"));

        //移除所有键值对元素,慎重使用
//        map.clear();

        //判断集合中是否包含指定的键,包含返回真;不包含返回假
//        System.out.println(map.containsKey("马"));
//        System.out.println(map.containsKey("杨"));

        //判断集合中是否包含指定的值,包含返回真;不包含返回假
//        System.out.println(map.containsValue("王五"));
//        System.out.println(map.containsValue("小明"));

        //判断集合是否为空,为空返回真;不为空返回假
        //System.out.println(map.isEmpty());

        //集合的长度,也就是集合中键值对的个数
        System.out.println(map.size());

        System.out.println(map);
    }
}

3.Map集合的获取功能

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-YE34EfjC-1651821374359)(F:\image\图片\Screenshot_20220425-233513.jpg)]

package basics.listFrame.map;

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

//Map集合的获取功能
public class GetMapElement {
    public static void main(String[] args) {
        Map<Integer,String> map = new HashMap<>();

        System.out.println(map.put(1, "张三"));
        map.put(2,"李四");
        map.put(3,"王五");
        System.out.println(map.put(4, "马六"));
        System.out.println(map.put(4, "马六"));


        //根据键获取值
        String s = map.get(3);
        System.out.println(s);
        String s1 = map.get(2);
        System.out.println(s1);

        //获取所有键的集合
        Set<Integer> keys = map.keySet();
        System.out.println(keys);

        //获取所有值的集合
        Collection<String> values = map.values();
        System.out.println(values);


    }
}

4.Map集合的遍历

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-DKe87UGU-1651821374359)(F:\image\图片\Screenshot_20220425-234443.jpg)]

package basics.listFrame.map;

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

/*
遍历Map集合方法一:
        1.先获取Map集合的所有键     Set<Integer> integers = map.keySet();
        2.用增强for循环遍历所有键的集合
        3.在for循环里面用  map.get();  方法获取键对应的元素
        5.拼接输出
         */
public class MapTraverse1 {
    public static void main(String[] args) {
        Map<Integer,String> map = new HashMap<>();

        map.put(1,"一");
        map.put(2,"二");
        map.put(3,"三");
        map.put(4,"四");
        map.put(5,"五");

        Set<Integer> integers = map.keySet();

        for (int i : integers){
            String s = map.get(i);
            System.out.println(i + "," + s);
        }
    }
}

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-9VBD4Szl-1651821374359)(F:\image\图片\Screenshot_20220425-234836.jpg)]

package basics.listFrame.map;

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

/*
遍历Map集合方法二:
    1.首先获取Map集合的键值对对象的集合   Set<Map.Entry<Integer, TraverseString>> entries = map.entrySet();
    2.用增强for遍历键值对对象的集合
    3.在for循环内部用  对象名.getKey(); (获取键值对的键)    对象名.getValue(); (获取键值对的值)
    4.拼接输出
         */
public class MapTraverse2 {
    public static void main(String[] args) {
        Map<Integer,String> map = new HashMap<>();

        map.put(1,"一");
        map.put(2,"二");
        map.put(3,"三");
        map.put(4,"四");
        map.put(5,"五");

        Set<Map.Entry<Integer, String>> entries = map.entrySet();

        for (Map.Entry<Integer, String> map1 : entries){
            Integer key = map1.getKey();
            String value = map1.getValue();

            System.out.println(key + "," + value);
        }
    }
}

5.HashMap集合存储学生对象并遍历

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-qSM7J445-1651821374360)(F:\image\图片\Screenshot_20220425-235336.jpg)]

package basics.listFrame.map;

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

//HashMap集合存储学生对象并遍历
//创建一个HashMap集合,键是学号,值是学生对象,存储三个键值对元素,并遍历
public class StudentExample {
    public static void main(String[] args) {
        HashMap<Integer,Student> map = new HashMap<>();

        Student student1 = new Student();
        student1.setName("张三");
        student1.setSex("男");
        student1.setAge(18);


        Student student2 = new Student();
        student2.setName("李四");
        student2.setSex("男");
        student2.setAge(20);

        Student student3 = new Student();
        student3.setName("王五");
        student3.setSex("男");
        student3.setAge(16);

        Student student4 = new Student();
        student4.setName("小红");
        student4.setSex("女");
        student4.setAge(20);

        map.put(1001,student1);
        map.put(1002,student2);
        map.put(1003,student3);

        map.put(1003,student4);//student4覆盖了student3

        //方法一遍历
        Set<Integer> integers = map.keySet();

        for (int i : integers){
            Student student = map.get(i);
//            TraverseString name = student.getName();
//            TraverseString sex = student.getSex();
//            int age = student.getAge();
//
//            System.out.println(i + ":" + name + " " + sex + " " + age + "岁");

            System.out.println(i + ":" + student);  //用toString输出的stuent
        }

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

        //方法二遍历
        Set<Map.Entry<Integer, Student>> entries = map.entrySet();

        for (Map.Entry<Integer, Student> s : entries){
            Integer key = s.getKey();
            Student value = s.getValue();
            System.out.println(key + ":" +value);
        }
    }
}






/*
package basics.listFrame.map;

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

    public Student() {
    }

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

    public String getName() {
        return name;
    }

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

    public String getSex() {
        return sex;
    }

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

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        if (age < 0 || age > 120){
            System.out.println("数据有误");
        }else {
            this.age = age;
        }
    }

    @Override
    public String toString() {
        return name + " " + sex + " " + age;

    }
}

 */

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-tQo4HgcH-1651821374360)(F:\image\图片\Screenshot_20220425-235500.jpg)]

package basics.listFrame.map;

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

HashMap集合存储学生对象并遍历
//创建一个HashMap集合,键是学生对象,值是居住地,存储多个键值对元素,并遍历,
// 要求保证键的唯一性,如果学生对象成员变量值相同,我们就认为是同一个对象(要保证键Student的唯一性,学生类Student里面必须重写hashCode方法和equals方法)
public class Student2Example {
    public static void main(String[] args) {
        HashMap<Student2, String> map = new HashMap<>();

        Student2 student1 = new Student2(1001,"张三",18);
        Student2 student2 = new Student2(1002,"李四",19);
        Student2 student3 = new Student2(1003,"王五",20);
        Student2 student4 = new Student2(1003,"王五",20);

        map.put(student1,"平凉");
        map.put(student2,"天水");
        map.put(student3,"庆阳");
        map.put(student4,"西安");

        //方法一遍历
        Set<Student2> student2s = map.keySet();

        for (Student2 s : student2s){
            String s1 = map.get(s);
            System.out.println(s + ": " + s1);
        }

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

        //方法二遍历
        Set<Map.Entry<Student2, String>> entries = map.entrySet();

        for (Map.Entry<Student2, String> s : entries){
            Student2 key = s.getKey();
            String value = s.getValue();
            System.out.println(key + ": " + value);
        }
    }
}


/*
package basics.listFrame.map;

public class Student2 {
    private int id;
    private String name;
    private int age;

    public Student2() {
    }

    public Student2(int id, String name, int age) {
        this.id = id;
        this.name = name;
        this.age = age;
    }

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

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

    @Override
    public String toString() {
        return id + ", " + name + ", " + age;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;

        Student2 student2 = (Student2) o;

        if (id != student2.id) return false;
        if (age != student2.age) return false;
        return name != null ? name.equals(student2.name) : student2.name == null;
    }

    @Override
    public int hashCode() {
        int result = id;
        result = 31 * result + (name != null ? name.hashCode() : 0);
        result = 31 * result + age;
        return result;
    }
}

 */

6.HashMap集合存储ArrayList元素并遍历

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-sSbJL1hK-1651821374361)(F:\image\图片\Screenshot_20220425-235742.jpg)]

package basics.listFrame.map;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;

//HashMap集合存储ArraysList元素并遍历
//要求:创建一个HashMap集合,存储三个键值对元素,每一个键值对元素的键是String,值是ArrayList,每一个ArrayList的元素是String,并遍历
public class SavaArrayListExample {
    public static void main(String[] args) {
        HashMap<String, ArrayList<String>> map = new HashMap<String, ArrayList<String>>();

        ArrayList<String> list1 = new ArrayList<>();
        list1.add("张三");
        list1.add("张四");
        list1.add("张五");

        ArrayList<String> list2 = new ArrayList<>();
        list2.add("李三");
        list2.add("李四");
        list2.add("李五");

        ArrayList<String> list3 = new ArrayList<>();
        list3.add("王三");
        list3.add("王四");
        list3.add("王五");

        //System.out.println(list);

        map.put("张家",list1);
        map.put("李家",list2);
        map.put("王家",list3);

        //方法一遍历
        Set<String> set = map.keySet();

        for (String s : set){
            ArrayList<String> list = map.get(s);
            System.out.print(s + ": ");
            for (String s1 : list){
                System.out.print(s1 + " ");
            }
            System.out.println();
        }

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

        //方法二遍历
        Set<Map.Entry<String, ArrayList<String>>> entries = map.entrySet();

        for (Map.Entry<String, ArrayList<String>> mm : entries){
            String key = mm.getKey();
            ArrayList<String> value = mm.getValue();

            System.out.print(key + ": ");

            for (String s : value){
                System.out.print(s + " ");
            }

            System.out.println();
        }
    }
}

7.统计字符串中每个字符出现的次数

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-La8OJQ10-1651821374361)(F:\image\图片\Screenshot_20220425-235917.jpg)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-d4euydvR-1651821374361)(F:\image\图片\Screenshot_20220426-000042.jpg)]

package basics.listFrame.map;

import java.util.HashMap;
import java.util.Scanner;
import java.util.Set;

//统计字符串中每个字符出现的次数
//需求:键盘录入一个字符串,要求统计字符串中每个字符出现的次数
//举例:键盘录入 "aababcabcdabcde"     控制台输出:  "a(5)b(4)c(3)d(2)e(1)"
public class CharExample {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        System.out.print("请输入一个字符串:");
        String s = sc.nextLine();

        HashMap<Character,Integer> map = new HashMap<>();

        //存储
        for (int i = 0; i < s.length(); i++) {
            char c = s.charAt(i);

            //*** 把字符当作键去Map集合中寻找对应的值
            Integer value = map.get(c);

            if (value == null){   //如果键为null,说明集合中没有这个元素,就进行添加
                map.put(c,1);
            }else {               //如果不为null,说明集合中有这个元素,就对这个键对应的值进行+1,然后进行添加
                value++;
                map.put(c,value);
            }
        }

        //遍历
        Set<Character> characters = map.keySet();

        for (char c : characters){
            Integer integer = map.get(c);
            System.out.print(c + "(" + integer + ")");
        }

        System.out.println();

        sc.close();
    }
}

8.Collections概述和使用

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-hqVXJmBy-1651821374362)(F:\image\图片\Screenshot_20220426-000402.jpg)]

package basics.listFrame.map;

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

//Collections针对集合操作的工具类
public class TestCollections {
    public static void main(String[] args) {
        List<Integer> list = new ArrayList<>();

        list.add(30);
        list.add(20);
        list.add(40);
        list.add(50);
        list.add(10);

        System.out.println(list);

        //将指定的列表按升序进行排序
//        Collections.sort(list);
//        System.out.println(list);

        //将指定的列表按比较器进行排序
        Collections.sort(list, new Comparator<Integer>() {
            @Override
            public int compare(Integer o1, Integer o2) {
                //return o1 - o2;   //从小到大
                return o2 - o1;     //从大到小
            }
        });

        System.out.println(list);

        //反转指定列表中元素的顺序
//        Collections.reverse(list);
//        System.out.println(list);

        //使用默认的随机源随机排列指定的列表
//        Collections.shuffle(list);
//        System.out.println(list);
    }
}

9.ArrayList存储学生对象并排序

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-9RobqLh3-1651821374362)(F:\image\图片\Screenshot_20220426-001003.jpg)]

package basics.listFrame.map;

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

//ArrayList存储学生对象,使用Collections对ArrayList进行排序
//要求:按照年龄从小到大排序,年龄相同时,按照姓名的字母顺序排序
public class CollectionsExample {
    public static void main(String[] args) {
        ArrayList<Student> students = new ArrayList<Student>();

        Student student1 = new Student("zhangsan","男",20);
        Student student2 = new Student("lisi","男",18);
        Student student3 = new Student("wangwu","男",21);
        Student student4 = new Student("xiaohong","女",20);
        Student student5 = new Student("xiaoming","男",20);

        students.add(student1);
        students.add(student2);
        students.add(student3);
        students.add(student4);
        students.add(student5);

        //System.out.println(list);

        /*
        使用public static <T> void sort(List<T> list, Comparator<? super T> c) {}       (使用比较器)
         */
        Collections.sort(students, new Comparator<Student>() {
            @Override
            public int compare(Student o1, Student o2) {
                return o1.getAge() - o2.getAge() == 0 ? o1.getName().compareTo(o2.getName()) : o1.getAge() - o2.getAge();
            }
        });

        //遍历
        for (Student s : students){
            System.out.println(s);
        }

        /*
        lisi 男 18
        xiaohong 女 20
        xiaoming 男 20
        zhangsan 男 20
        wangwu 男 21
         */
    }
}








/*
package basics.listFrame.map;

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

    public Student() {
    }

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

    public String getName() {
        return name;
    }

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

    public String getSex() {
        return sex;
    }

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

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        if (age < 0 || age > 120){
            System.out.println("数据有误");
        }else {
            this.age = age;
        }
    }

    @Override
    public String toString() {
        return name + " " + sex + " " + age;

    }
}

 */

10.模拟斗地主

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-jnuCQw6e-1651821374363)(F:\image\图片\Screenshot_20220426-001119.jpg)]

package basics.listFrame.map;

import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;

/*
模拟斗地主
    通过程序实现斗地主过程中的洗牌,发牌和看牌

    1.创建一个牌盒,也就是定义一个集合对象,用ArrayList集合实现
    2.往牌盒里装牌
    3.洗牌,也就是把牌打散,用Collection得到shuffle()方法实现
    4.发牌,也就是遍历集合,给三个玩家发牌
    5.看牌,也就是三个玩家分别遍历自己的牌
 */
public class LandlordsExample {
    public static void main(String[] args) {
        //定义牌盒
        ArrayList<String> list = new ArrayList<>();

        //装牌
        String[] poker = {"♥","♠","♣","♦"};
        String[] num = {"A","2","3","4","5","6","7","8","9","10","J","Q","K"};
        String[] monkey = {"🐵","🙊"};

//        for (String s : poker){
//            for (String s1 : num){
//                list.add(s + s1);
//            }
//        }

        for (String s : num){
            for (String s1 : poker){
                list.add(s1 + s);
            }
        }

        for (String s : monkey){
            list.add(s);
        }

        //洗牌
        Collections.shuffle(list);

        //发牌
        ArrayList<String> list1 = new ArrayList<>();  //底牌
        ArrayList<String> player1 = new ArrayList<>();  //玩家1
        ArrayList<String> player2 = new ArrayList<>();  //玩家2
        ArrayList<String> player3 = new ArrayList<>();  //玩家3

        //用普通for循环,拿到索引去找对应的牌
        for (int i = 0; i < list.size(); i++) {
            if (i >= list.size()-3){
                list1.add(list.get(i));
            }else {
                if (i % 3 == 0){
                    player1.add(list.get(i));
                }
                if (i % 3 == 1){
                    player2.add(list.get(i));
                }
                if (i % 3 == 2){
                    player3.add(list.get(i));
                }
            }
        }

        //洗牌

        //底牌
        System.out.print("底牌:");
        for (String s : list1){
            System.out.print(s + "  ");
        }

        System.out.println();

        //玩家1
        System.out.print("玩家1:");
        for (String s : player1){
            System.out.print(s + "  ");
        }

        System.out.println();

        //玩家2
        System.out.print("玩家2:");
        for (String s : player2){
            System.out.print(s + "  ");
        }

        System.out.println();

        //玩家3
        System.out.print("玩家3:");
        for (String s : player3){
            System.out.print(s + "  ");
        }
    }
}

11.模拟斗地主升级版

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-kJeyfyeA-1651821374363)(F:\image\图片\Screenshot_20220426-002831.jpg)]

package basics.listFrame.map;

import java.util.*;

/*
模拟斗地主
    通过程序实现斗地主过程中的洗牌,发牌和看牌,要求对牌进行排序

    1.创建HashMap集合,键是编号,值是牌
    2.创建ArrayList,存储编号
    3.创建花色数组和点数数组
    4.从0开始往HashMap里面存储编号,并存储对应的牌,同时往ArrayList里面存储编号
    5.洗牌,洗的是编号,用Collections的shuffle()实现
    6.发牌,发的是编号,为保证编号是排序的,用TreeSet接收
    7.定义方法看牌(遍历TreeSet集合,获取编号,到HashMap找对应的牌)
    8.调用看牌方法
 */
public class SuperLandlordsExample {
    public static void main(String[] args) {
        HashMap<Integer, String> map = new HashMap<>();

        ArrayList<Integer> list = new ArrayList<>();

        String[] poker = {"♥", "♠", "♣", "♦"};
        String[] num = {"3", "4", "5", "6", "7", "8", "9", "10", "J", "Q", "K","A", "2"};
        String[] monkey = {"🐵", "🙊"};

        //这里装牌只能一个数字一组牌装,不能一个花色一组牌去装;但是普通版的斗地主就无所谓,因为不需要从小到大排序
        //一个数字一组牌去装,按照排好序的编号去找到的对应的牌也是排好序的
        //但是一个花色一组牌去装,只会按照在一组花色牌里面排序,并且牌是一组一组分好的
        int i = 0;
        //按花色分组,分四组,在一组花色牌里面排序
//        for (String s : poker) {
//            for (String ss : num) {
//                map.put(i, s + ss);
//                list.add(i);
//                i++;
//            }
//        }

        //所有牌按数字大小排序
        for (String s : num){
            for (String ss : poker){
                map.put(i,ss + s);
                list.add(i);
                i++;
            }
        }

        for (String s : monkey) {
            map.put(i, s);
            list.add(i);
            i++;
        }

        System.out.println(map);
        Collections.shuffle(list);

        TreeSet<Integer> dp = new TreeSet<>();
        TreeSet<Integer> player1 = new TreeSet<>();
        TreeSet<Integer> player2 = new TreeSet<>();
        TreeSet<Integer> player3 = new TreeSet<>();

        //用增强for拿到的是集合里面的元素,进行判断的时候是对元素进行判断,和排好序判断没有区别
        //这里需要用普通for循环,拿索引去判断,然后用索引拿对应的编号
        for (int j = 0; j < list.size(); j++) {
            if (j >= list.size() - 3){
                dp.add(list.get(j));
            }else {
                if (j % 3 == 0){
                    player1.add(list.get(j));
                }
                if (j % 3 == 1){
                    player2.add(list.get(j));
                }
                if (j % 3 == 2){
                    player3.add(list.get(j));
                }
            }
        }

        System.out.println(dp);
        System.out.println(player1);
        System.out.println(player2);
        System.out.println(player3);

        System.out.print("底牌:");
        seePoker(dp, map);
        System.out.print("玩家1:");
        seePoker(player1,map);
        System.out.print("玩家2:");
        seePoker(player2,map);
        System.out.print("玩家3:");
        seePoker(player3,map);

    }

    public static void seePoker(TreeSet<Integer> set, HashMap<Integer, String> map) {

        for (Integer i : set) {
            String s = map.get(i);
            System.out.print(s + " ");
        }
        System.out.println();
    }
}

总结:

  • ArrayList:底层数据结构为数据,查询快,增删慢
  • LinkedList:底层数据结构为链表,增删快,查询慢
  • Set集合,不包含重复的元素
  • HashSet,不包含重复元素,对迭代顺序不保证
  • LinkedHashSet,不包含重复元素,存储和取出顺序一致
  • TreeSet,元素有序,不是存储和取出的顺序,而是按照一定的规则进行排序,具体的排序方法取决于构造方法,不包含重复元素

IO流

File

1.File类概述和构造方法

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-25oTL0Lm-1651821374363)(D:\数据\QQ数据\MobileFile\Screenshot_20220426-233844.jpg)]

package basics.io.file;

import java.io.File;

/*
File类概述和构造方法
    文件和目录是可以通过File封装成对象的
    对于File而言,其封装的不是一个真正存在的文件,仅仅是一个路径名而已。他们可以是存在的也可以是不存在的,需要通过具体的操作把这个路径的内容转换为具体存在的
 */
public class Test01 {
    public static void main(String[] args) {

        //File(String pathname)    通过将给定的路径名字符串转换为抽象路径名来创建新的File实例(路径用双反斜杠隔开)
        File file = new File("F:\\test\\test.txt");

        //File(String parent,String child)     从父路径名字符串和子路径名字符串创建新的File实例(父路径名为目录名,子路径名为文件名)
        File file1 = new File("F:\\test","test.txt");

        //File(File parent,String child)        从父抽象路径名和子路径名字符串创建的新的File实例(父抽象路径名为目录名,子路径名字符串为文件名)
        File file2 = new File("F:\\test");
        File file3 = new File(file2, "test.txt");
    }
}

2.File类创建功能

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-lEMdujfu-1651821374364)(D:\数据\QQ数据\MobileFile\Screenshot_20220426-234317.jpg)]

package basics.io.file;

import java.io.File;
import java.io.IOException;

//File类创建功能
public class Test02 {
    public static void main(String[] args) throws IOException {
        //当具有该名称的文件不存在时,创建一个由该抽象路径名命名的新空文件,如果没有给父路径就在项目文件夹下面创建该文件
        //如果不存在在该文件就创建该文件返回true,如果存在该文件就不创建文件返回false
//        File file1 = new File("F:\\test\\test.txt");
//        boolean newFile = file1.createNewFile();
//        System.out.println(newFile);

        //创建由此抽象路径名命名的目录,如果没有给父路径就在项目文件夹下面创建该目录
        //如果不存在在该目录就创建该目录返回true,如果存在该目录就不创建目录返回false,
        //用该方法创建多级目录返回false
//        File file = new File("F:\\test");
//        //File file = new File("F:\\test2.txt");  //如果使用创建目录的方法去创建文件,则创建的是以这个文件名命名的目录
//        boolean mkdir = file.mkdir();
//        System.out.println(mkdir);

        //创建由此抽象路径名命名的目录,包括任何必需但不存在的父目录,(多级目录),也可以用来创建一级目录
        // 如果没有给父路径就在项目文件夹下面创建该目录
        //如果不存在在该目录就创建该目录返回true,如果存在该目录就不创建目录返回false
        //File file2 = new File("F:\\test1\\javaSE\\test");
//        File file2 = new File("F:\\test1.txt\\test1.txt");   //如果使用创建目录的方法去创建文件,则创建的是以这个文件名命名的目录
//        boolean mkdirs = file2.mkdirs();
//        System.out.println(mkdirs);

        //可以用同一个对象名来创建目录和目录下的文件
        File file = new File("F:\\test1");
        System.out.println(file.mkdirs());
        file = new File("F:\\test\\Demo1.java");
        System.out.println(file.createNewFile());
    }
}

3.File类删除功能

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-CmjQcA6H-1651821374364)(D:\数据\QQ数据\MobileFile\Screenshot_20220427-001054.jpg)]

package basics.io.file;

import java.io.File;
import java.io.IOException;

//File删除功能
//对象调用delete()方法,删除的是绝对路径中的最后一项(无论是目录还是文件,只是删除最后一项)
public class Test03 {
    public static void main(String[] args) throws IOException {
        File file = new File("F:\\test");
        //System.out.println(file.mkdir());

        File file1 = new File("F:\\test\\test.txt");
        //System.out.println(file1.createNewFile());

        //可以使用一个对象名去创建多级目录和目录下的文件
        File file2 = new File("F:\\test\\javaSE");
        System.out.println(file2.mkdirs());
        File file3 = new File("F:\\test\\javaSE\\Demo.java");
        System.out.println(file3.createNewFile());

        //删除一个目录时,当该目录中有内容时,返回false;也就是不能直接删除,应该先删除目录中的内容,然后去删除目录
        //存在则删除返回true,不存在则返回false
//        System.out.println(file1.delete());
//        System.out.println(file.delete());

        //用同一个对象名创建的目录和文件,使用这个对象删除是只删除文件
        System.out.println(file2.delete());//false  因为目录下有内容
        System.out.println(file3.delete());//true   删除最后一项Demo.java
        System.out.println(file2.delete());//true   删除最后一项javaSE

        File file4 = new File("F:\\test");
        System.out.println(file4.delete());//true   删除最后一项test

    }
}

4.File类判断和获取功能

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-W9gR6JJo-1651821374365)(D:\数据\QQ数据\MobileFile\Screenshot_20220426-235454.jpg)]

package basics.io.file;

import java.io.File;

//File类判断和获取功能
public class Test04 {
    public static void main(String[] args) {
        //测试此抽象路径名表示的File是否为目录
        File file = new File("F:\\Java\\");
        System.out.println(file.isDirectory());

        System.out.println(new File("F:\\python\\main.py").isDirectory());  //匿名内部类调用方法

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

        //测试此抽象路径名表示的File是否为文件
        System.out.println(new File("F:\\python\\main.py").isFile());
        System.out.println(new File("F:\\python\\").isFile());

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

        //测试此抽象路径名表示的File是否存在
        System.out.println(new File("F:\\Java").exists());
        System.out.println(new File("H:").exists());
        System.out.println(new File("F:\\haha").exists());
        System.out.println(new File("F:\\python\\main.py").exists());

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

        //返回此抽象路径名的绝对路径名字符串
        String h = new File("JavaSE").getAbsolutePath();
        System.out.println(h);
        System.out.println(new File("F:\\python").getAbsolutePath());
        System.out.println(new File("F:\\python\\main.py").getAbsolutePath());

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

        //将此抽象路径名转换为路径名字符串
        String h1 = new File("JavaSE").getPath();
        System.out.println(h1);
        System.out.println(new File("F").getPath());
        System.out.println(new File("F:\\python\\main.py").getPath());

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

        //返回由此抽象路径名表示的文件或目录的名称
        String javaSE = new File("JavaSE").getName();
        System.out.println(javaSE);
        System.out.println(new File("F:\\haha").getName());
        System.out.println(new File("haha").getName());
        System.out.println(new File("F:\\").getName());
        System.out.println(new File("F:\\python").getName());
        System.out.println(new File("F:\\python\\main.py").getName());

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

        //返回此抽象路径名表示对目录中的文件和目录的名称字符串数组
        String[] list = new File("F:\\").list();
        System.out.println(list);

        for (String s: list){
            System.out.println(s);
        }

        String[] list1 = new File("F:\\python").list();

        for (String s : list1){
            System.out.println(s);
        }

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

        //返回此抽象路径名表示的目录中的文件和目录的File对象数组
        File[] files = new File("F:\\python").listFiles();
        for (File f : files){
            //System.out.println(f);
            //System.out.println(f.getName());
            if (f.isDirectory()){
                System.out.println(f.getName());
            }
            if (f.isFile()){
                System.out.println(f.getName() + "666");
            }
        }

    }
}

案例:遍历目录

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-pC0PbOLh-1651821374365)(D:\数据\QQ数据\MobileFile\Screenshot_20220427-001815.jpg)]

package basics.io.file;

import java.io.File;

//给定一个路径(F:\\数学建模),通过递归完成遍历该目录下的所有内容,并把所有文件的绝对路径输出在控制台
public class Example {
    public static void main(String[] args) {
        File file = new File("F:\\数学建模");

        test(file);
    }

    public static void test(File file){
        //获得对象的文件和目录的File对象数组
        File[] files = file.listFiles();

        //遍历对象数组
        for (File file1 : files){
            if (file1.isFile()){   //如果是文件直接输出绝对路径
                System.out.println(file1.getAbsolutePath());
            }else {    //如果不是文件,则继续调用方法
                test(file1);
            }
        }
    }
}

字节流

1. IO流概述和分类

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-0oP7orxo-1651821374365)(D:\数据\QQ数据\MobileFile\Screenshot_20220427-002457.jpg)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-mvZOxWsx-1651821374366)(D:\数据\QQ数据\MobileFile\Screenshot_20220427-003111.jpg)]

把CPU当作大脑,把程序当作纸

  • 读数据,就相当于我们读纸上的字,就要先把纸上的字输入到我们的大脑才能读,所以就是输入流
  • 写数据,就相当于我们在纸上写字,就要把我们大脑中的字输出到纸上,相当于输出流

2.字节流写数据

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-mqELeJM8-1651821374366)(D:\数据\QQ数据\MobileFile\Screenshot_20220427-004316.jpg)]

package basics.io.byte_stream;

import java.io.FileOutputStream;
import java.io.IOException;

//字节流写数据
public class Test02 {
    public static void main(String[] args) throws IOException {
        //1.创建字节输出流对象(a.调用系统功能创建文件 b.创建字节输出流对象 c.让字节输出流对象指向文件)
        FileOutputStream fos = new FileOutputStream("JavaSE\\src\\basics\\io\\byte_stream\\fos.txt");

        //2.调用字节输出流对象的写数据方法
        fos.write(97);
        fos.write(57);
        fos.write(55);

        //3.释放资源(a.关闭此文件输出流 b.释放与此流相关联的任何系统资源)
        fos.close();
    }
}

3.字节流写数据的三种方式

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-XQiHhTAF-1651821374367)(D:\数据\QQ数据\MobileFile\Screenshot_20220427-233446.jpg)]

package basics.io.byte_stream;

import java.io.*;

//字节流写数据的三种方式
public class Test02 {
    public static void main(String[] args) throws IOException {
        //将指定的字节写入此文件输出流,一次写一个字节数据
        //下面三种创建字节输出流对象的方法本质是一样的
        FileOutputStream fos = new FileOutputStream("JavaSE\\src\\basics\\io\\byte_stream\\fos.txt");

        //FileOutputStream fos = new FileOutputStream(new File("JavaSE\\src\\basics\\io\\byte_stream\\fos.txt"));

//        File file = new File("JavaSE\\src\\basics\\io\\byte_stream\\fos.txt");
//        FileOutputStream fileOutputStream = new FileOutputStream(file);

//        fos.write(97);
//        fos.write(98);
//        fos.write(99);

        //将b.length字节从指定的字节数组写入此文件输出流,一次写入一个字节组数据
//        byte[] arr = {97,98,99,100,101};
//
//        byte[] bytes = "abcde".getBytes();
//
//        fos.write(arr);
//        fos.write(bytes);

        //将len字节从指定的字节数组开始,从偏移量off开始写入此文件输出流,一次写一个字节数组的部分数据
        byte[] bytes = "abcde".getBytes();

        fos.write(bytes,1,3);
        
        fos.close();
    }
}

4.字节流写数据换行和追加写入

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-N2Pz738f-1651821374367)(D:\数据\QQ数据\MobileFile\Screenshot_20220427-235153.jpg)]

package basics.io.byte_stream;

import java.io.FileOutputStream;
import java.io.IOException;

//换行和追加写入
public class Test04 {
    public static void main(String[] args) throws IOException {
        //字节流写数据换行(用换行符)
        /*
        不同操作系统的换行符不同
        windows:\r\n
        linux:\n
        mac:\r
         */
//        FileOutputStream fos = new FileOutputStream("JavaSE\\src\\basics\\io\\byte_stream\\fos.txt");
//
//        byte[] bytes = "hello".getBytes();
//        byte[] bytes1 = "\r\n".getBytes();    //换行符转换成字节数组
//        byte[] bytes2 = "world".getBytes();
//
//        fos.write(bytes);
//        fos.write(bytes1);
//        fos.write(bytes2);

        
        //普通写入,运行一次写一次,并不能追加
        //追加写入,append参数为真就是追加写入,为假就不是追加写入
        /*
         public FileOutputStream(String name, boolean append) throws FileNotFoundException {
            this(name != null ? new File(name) : null, append);
         }
         */
        FileOutputStream fos = new FileOutputStream("JavaSE\\\\src\\\\basics\\\\io\\\\byte_stream\\\\fos.txt", true);

        byte[] b1 = "Hello".getBytes();
        byte[] b2 = "\n".getBytes();
        byte[] b3 = "World".getBytes();

        fos.write(b1);
        fos.write(b2);
        fos.write(b3);
        fos.write(b2);

        fos.close();
    }
}

5.字节流写数据加异常处理

package basics.io.byte_stream;

import java.io.FileOutputStream;
import java.io.IOException;

//字节流写数据加异常处理
public class Test05 {
    public static void main(String[] args) {
        FileOutputStream fos = null;
        try {
            fos = new FileOutputStream("JavaSE\\src\\basics\\io\\byte_stream\\");

            fos.write(97);
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (fos != null) {
                try {
                    //NullPointerException
                    // 当字节输出流对象创建失败,然后关闭资源就是null调用close方法,就会出现空指针异常
                    // 解决办法就是在finally中对字节输出流对象进行不为空判断再调用close方法

                    fos.close();

                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}

6.字节流读数据

一次读一个字节数据

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-uYfLdfhh-1651821374368)(D:\数据\QQ数据\MobileFile\Screenshot_20220428-000232.jpg)]

package basics.io.byte_stream;

import java.io.FileInputStream;
import java.io.IOException;

//字节流读数据(一次读一个字节数据)
public class Test06 {
    public static void main(String[] args) throws IOException {
        //创建字节输入流对象
        FileInputStream fls = new FileInputStream("JavaSE\\src\\basics\\io\\byte_stream\\fls.txt");

        /*
        //调用字节输入流对象的读数据方法
        //第一次读数据
        int read = fls.read();

        //得到的是ACII码,需要强制转换为字符(char比int小)
        System.out.println(read);
        System.out.println((char) read);

        //第二次读数据
        read = fls.read();
        System.out.println(read);
        System.out.println((char) read);

        //第三次读数据
        read = fls.read();
        System.out.println(read);
        System.out.println((char) read);

        //第四次读数据
        read = fls.read();
        System.out.println(read);
        System.out.println((char) read);

        //当文件中没有数据时,进行读数据得到的ACIIma为 -1
         */

        //循环改进读取所有数据
        /*
        int read = fls.read();  //进行一次读数据
        while (read != -1) {    //得到的ACII码不为-1则循环
            System.out.print((char) read);    //输出
            read = fls.read();  //再次读数据
        }
         */
        int read;   //定义一个变量用来接收读到的数据的ACII码
        while ((read = fls.read()) != -1){   //读到的数据的ACII码赋值给变量进行判断循环
            System.out.print((char) read);    //输出
        }
        
        //释放资源
        fls.close();
    }
}
一次读一个字节数组数据

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-5iiif7g2-1651821374368)(D:\数据\QQ数据\MobileFile\Screenshot_20220428-001945.jpg)]

package basics.io.byte_stream;

import opp.demo05.B;

import java.io.FileInputStream;
import java.io.IOException;

//字节流读数据(一次读一个字节数组数据)
public class Test06_2 {
    public static void main(String[] args) throws IOException {
        FileInputStream fls = new FileInputStream("JavaSE\\src\\basics\\io\\byte_stream\\fls.txt");

        /*
        byte[] bytes = new byte[5];

        //第一次读取数据
        int i = fls.read(bytes);
        System.out.println(i);
        System.out.println(new String(bytes,0,i));  //把一个字节数组转换为字符串
        //5
        //hello

        //第二次读取数据
        i = fls.read(bytes);
        System.out.println(i);
        System.out.println(new String(bytes,0,i));
        //5
        //
        //wor

        //第三次读取数据
        i = fls.read(bytes);
        System.out.println(i);
        System.out.println(new String(bytes,0,i));
        //5
        //ldwor

        i = fls.read(bytes);
        System.out.println(i);
        i = fls.read(bytes);
        System.out.println(i);

        //当文件中没有数据时,读数据得到的纸为-1


        /*
        第一次:hello
        第二次:\r\nwor
        第三次:ld\r\nr

 */
        byte[] bytes = new byte[1024];   //1024或者1024的倍数
        int i;
        while ((i = fls.read(bytes)) != -1){
            System.out.print(new String(bytes,0,i));
        }

        fls.close();
    }

}

案例1:复制文本文件

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-6KBQF9Uf-1651821374368)(D:\数据\QQ数据\MobileFile\Screenshot_20220428-001648.jpg)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-S3Xob8tE-1651821374369)(D:\数据\QQ数据\MobileFile\Screenshot_20220428-001717.jpg)]

package basics.io.byte_stream;

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;

//复制文本文件:  将F:\\python\\呐喊.txt复制到本目录byte_stream下
public class Example1 {
    public static void main(String[] args) throws IOException {
        //输入数据流对象
        FileInputStream fls = new FileInputStream("F:\\python\\呐喊.txt");
        //输出数据流对象
        FileOutputStream fos = new FileOutputStream("JavaSE\\src\\basics\\io\\byte_stream\\呐喊.txt");

        //必须边读边写
        //读一个字节数组,写一个字节数组
//        byte[] bytes = new byte[1024];
//        int i;
//        while ((i = fls.read(bytes)) != -1){
//            fos.write(bytes,0,i);
//        }

        //读一个字节写一个字节
        int i;
        while ((i = fls.read()) != -1){
            fos.write(i);
        }

        //读数据读的是数据的ACII码,写数据也是写的ACII码,然后系统将写进去的ACII码自动转换为字符串

        fls.close();
        fos.close();
    }
}

案例2:复制图片

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-0wyA2vpN-1651821374369)(D:\数据\QQ数据\MobileFile\Screenshot_20220428-003659.jpg)]

package basics.io.byte_stream;

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;

//复制图片: 把 F:\\python\\iotest\\test.jpg 复制到本目录下test.jpg
public class Example2 {
    public static void main(String[] args) throws IOException {
        FileInputStream fls = new FileInputStream("F:\\python\\iotest\\test.jpg");
        FileOutputStream fos = new FileOutputStream("JavaSE\\src\\basics\\io\\byte_stream\\test.jpg");

        //一次读一个字节和一次写一个字节完成
//        int i;
//        while ((i = fls.read()) != -1){
//            fos.write(i);
//        }

        //一次读一个字节数组和一次写一个字节数组完成
        byte[] b = new byte[1024];
        int i;
        while ((i = fls.read(b)) != -1){
            fos.write(b);
        }

        fls.close();
        fos.close();
    }
}

7.字节缓冲流

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-27AIAahs-1651821374370)(F:\image\图片\学习\Screenshot_20220428-232032.jpg)]

package basics.io.byte_stream;

/*
字节缓冲流(提高字节流的读写效率)
    字节输出缓冲流:BufferedOutputStream(OutputStream out)
    字节输入缓冲流:BufferedInputStream(InputStream in)
 */

import java.io.*;

public class Test07 {
    public static void main(String[] args) throws IOException {
/*
        //字符输出缓冲流:
//        FileOutputStream fos = new FileOutputStream("JavaSE\\src\\basics\\io\\byte_stream\\fls1.txt");
//        BufferedOutputStream bos = new BufferedOutputStream(fos);

        BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("JavaSE\\src\\basics\\io\\byte_stream\\fls1.txt",true));   //追加写入

        bos.write("hello\r\n".getBytes());
        bos.write("world\r\n".getBytes());

        bos.close();
*/

        //字符输入缓冲流
        BufferedInputStream bls = new BufferedInputStream(new FileInputStream("JavaSE\\\\src\\\\basics\\\\io\\\\byte_stream\\\\fls1.txt"));

        //一次读一个字节数据
        int i;
        while ((i = bls.read()) != -1){
            System.out.print((char) i);
        }

        //一次读一个字节数组数据
//        byte[] b = new byte[1024];
//        int len;
//        while ((len = bls.read(b)) != -1){
//            System.out.print(new String(b,0,len));
//        }
        
        bls.close();
    }
}

案例3:复制视频

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-3sisjFlV-1651821374370)(F:\image\图片\学习\Screenshot_20220428-232704.jpg)]

package basics.io.byte_stream;

import java.io.*;

//复制视频
// 把 F:\\image\\视频\\test.mp4  复制此目录下   test.mp4
public class Example3 {
    public static void main(String[] args) throws IOException {
//        FileInputStream fls = new FileInputStream("F:\\image\\视频\\test.mp4");
//        FileOutputStream fos = new FileOutputStream("JavaSE\\src\\basics\\io\\byte_stream\\test.mp4");

        //读一个字节写一个字节太慢,行不通
//        int i;
//        while ((i = fls.read()) != -1){
//            fos.write(i);
//        }

        //读一个字节数组写一个字节数组,行得通
//        byte[] bytes = new byte[1024];
//        int len;
//        while ((len = fls.read(bytes)) != -1){
//            fos.write(bytes);
//        }

//        fos.close();
//        fls.close();

        //利用字节缓冲流复制
        BufferedInputStream bis = new BufferedInputStream(new FileInputStream("F:\\\\image\\\\视频\\\\test.mp4"));
        BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("JavaSE\\src\\basics\\io\\byte_stream\\test.mp4"));

        //读一个字节写一个字节太慢,行得通
//        int i;
//        while ((i = bis.read()) != -1){
//            bos.write(i);
//        }

        //读一个字节数组写一个字节数组,行得通(推荐)
        byte[] b = new byte[1024];
        int len;
        while ((len = bis.read(b)) != -1){
            bos.write(b);
        }

        bis.close();
        bos.close();
    }
}

字符流

1.字符流概述

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-jCkMiNtr-1651821374371)(F:\image\图片\学习\Screenshot_20220428-233235.jpg)]

package basics.io.character_stream;

import java.io.UnsupportedEncodingException;
import java.util.Arrays;

//字符流
public class Test01 {
    public static void main(String[] args) throws UnsupportedEncodingException {
        String s = "中国";

        //UTF-8编码   一个汉字三个字节
//        byte[] bytes = s.getBytes("UTF-8"); //[-28, -72, -83, -27, -101, -67]
        
        //IDEA默认为UTF-8编码
        byte[] bytes = s.getBytes();    //[-28, -72, -83, -27, -101, -67]

        //GBK编码     一个汉字两个字节
//        byte[] bytes = s.getBytes("GBK");   //[-42, -48, -71, -6]

        System.out.println(Arrays.toString(bytes));
    }
}

2.编码表

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-OYoxD2YP-1651821374371)(F:\image\图片\学习\Screenshot_20220428-233601.jpg)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ZihE87eB-1651821374372)(F:\image\图片\学习\Screenshot_20220428-233606.jpg)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-LiLyytu5-1651821374372)(F:\image\图片\学习\Screenshot_20220428-233639.jpg)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-FukhlfdC-1651821374372)(F:\image\图片\学习\Screenshot_20220428-233800.jpg)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-D6lOhJW0-1651821374373)(F:\image\图片\学习\Screenshot_20220428-233935.jpg)]

3.字符串中的编码解码问题

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-EfTUZweX-1651821374373)(F:\image\图片\学习\Screenshot_20220428-234055.jpg)]

package basics.io.character_stream;

import java.io.UnsupportedEncodingException;
import java.util.Arrays;

//字符串中的编码解码问题:用哪种字符集编码进行编码就用哪种字符集编码进行解码,否则会乱码
public class Test03 {
    public static void main(String[] args) throws UnsupportedEncodingException {
        String s = "中国";

        //用默认编码编码
        byte[] bytes = s.getBytes();
        System.out.println(Arrays.toString(bytes)); //[-28, -72, -83, -27, -101, -67]
        //用默认编码解码
        System.out.println(new String(bytes));  //中国

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

        //用utf-8编码
        byte[] bytes1 = s.getBytes("utf-8");
        System.out.println(Arrays.toString(bytes1));    //[-28, -72, -83, -27, -101, -67]
        //用utf-8解码
        System.out.println(new String(bytes1,"utf-8"));     //中国

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

        //用gbk编码
        byte[] gbks = s.getBytes("gbk");
        System.out.println(Arrays.toString(gbks));  //[-42, -48, -71, -6]
        //用gbk解码
        System.out.println(new String(gbks,"gbk")); //中国
        //用utf-8解码
        System.out.println(new String(gbks,"utf-8"));   //�й�
        //用默认编码解码
        System.out.println(new String(gbks));   //�й�
    }
}

4.字符流中的编码解码问题

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-oOq1HSZ3-1651821374374)(C:\Users\86177\AppData\Roaming\Typora\typora-user-images\image-20220429102445368.png)]

package basics.io.character_stream;

/*
字符流中的编码解码问题
    字符输入流:
        InputStreamReader(InputStream in)
        InputStreamReader(InputStream in,String charsetName)
    字符输出流:
        OutputStreamWriter(OutputStream out)
        OutputStreamWriter(OutputStream outmString charsetName)
 */

import java.io.*;

public class Test04 {
    public static void main(String[] args) throws IOException {

        //字符输出流写数据
        //使用默认字符集编码写数据
        //OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("JavaSE\\src\\basics\\io\\character_stream\\test.txt"));

        //使用utf-8字符集编码写数据
        //OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("JavaSE\\src\\basics\\io\\character_stream\\test.txt",true),"utf-8");

        //使用gbk字符集编码写数据(乱码:因为Idea默认字符集utf-8进行解码)
        OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("JavaSE\\src\\basics\\io\\character_stream\\test.txt"),"gbk");

//        osw.write("你好");
//        osw.write("世界");
        osw.write("中国");

        osw.close();


        //字符输入流读数据
        //用默认字符集解码读数据
        //InputStreamReader isr = new InputStreamReader(new FileInputStream("JavaSE\\src\\basics\\io\\character_stream\\test.txt"));    //中国

        //用utf8字符集解码读数据
        //InputStreamReader isr = new InputStreamReader(new FileInputStream("JavaSE\\src\\basics\\io\\character_stream\\test.txt"),"utf8");   //中国

        //用gbk字符集解码读数据(只有用gbk字符集进行编码写数据,用gbk字符集解码读数据才不会乱码)
        InputStreamReader isr = new InputStreamReader(new FileInputStream("JavaSE\\src\\basics\\io\\character_stream\\test.txt"),"gbk");   //涓浗

        /*
        //第一次读数据
        int read = isr.read();
        System.out.print(read);

        //第二次读数据
        read = isr.read();
        System.out.print(read);

        //第三次读数据,当文件中没有数据时得到的ASCII码为-1
        read = isr.read();
        System.out.print(read);   //-1
         */

        //一次读一个字符数据
//        int i;
//        while ((i = isr.read()) != -1){
//            System.out.print((char) i);
//        }

        //一次读一个字符数组数据
        char[] b = new char[5];
        int len;
        while ((len = isr.read(b)) != -1){
            System.out.print(new String(b,0,len));
        }


        isr.close();
    }
}

5.字符流写数据的5种方式

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-uUJdqKiV-1651821374374)(F:\image\图片\学习\Screenshot_20220429-000354.jpg)]

package basics.io.character_stream;

import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;

//字符流写数据的五种方式
public class Test05 {
    public static void main(String[] args) throws IOException {
        OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("JavaSE\\src\\basics\\io\\character_stream\\test1.txt",true));

        //写一个字符
        osw.write('a');
        osw.write('b');
        osw.write('c');

        osw.write("\r\n");

        //写一个字符数组
        char[] c = {'a','b','c','d','e'};
        osw.write(c);

        osw.write("\r\n");

        //写入字符数组的一部分
        osw.write(c,1,3);

        osw.write("\r\n");

        //写一个字符串
        osw.write("hello");

        osw.write("\r\n");

        //写一个字符串的一部分
        String s = "hello";
        osw.write(s,2,3);

        osw.close();
    }
}

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ixCaBWw6-1651821374374)(F:\image\图片\学习\Screenshot_20220429-001237.jpg)]

package basics.io.character_stream;

import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;

//字符流写数据的五种方式
public class Test05 {
    public static void main(String[] args) throws IOException {
        OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("JavaSE\\src\\basics\\io\\character_stream\\test1.txt"));

        //写一个字符
        osw.write(97);
        osw.write(98);
//        osw.flush();  //刷新流
        osw.write(99);
        osw.write(100);
        osw.flush();    //刷新完还可以写数据

//        osw.write(99);

//        osw.write("\r\n");
//
//        //写一个字符数组
//        char[] c = {'a','b','c','d','e'};
//        osw.write(c);
//
//        osw.write("\r\n");
//
//        //写入字符数组的一部分
//        osw.write(c,1,3);
//
//        osw.write("\r\n");
//
//        //写一个字符串
//        osw.write("hello");
//
//        osw.write("\r\n");
//
//        //写一个字符串的一部分
//        String s = "hello";
//        osw.write(s,2,3);

        osw.close();    //关闭流,释放资源,但是关闭之前会先刷新流,一旦关闭不能再写数据
        //osw.write(101);   //java.io.IOException: Stream closed
    }
}

6.字符流读数据的两种方式

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-6BglStjh-1651821374375)(F:\image\图片\学习\Screenshot_20220429-001747.jpg)]

package basics.io.character_stream;

import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;

//字符流读数据的2种方式
public class Test06 {
    public static void main(String[] args) throws IOException {
        InputStreamReader isr = new InputStreamReader(new FileInputStream("JavaSE\\src\\basics\\io\\character_stream\\test1.txt"));

        /*
        //一次读一个字节数据
        //第一次读数据
        int read = isr.read();
        System.out.println(read);

        //第二次读数据
        read = isr.read();
        System.out.println(read);

        //第三次第四次读数据
        read = isr.read();
        System.out.println(read);
        read = isr.read();
        System.out.println(read);
         */

        //一次读一个字节数据
//        int len;
//        while ((len = isr.read()) != -1){
//            System.out.print((char) len);
//        }

        //一次读一个字节数组数据
        char[] c = new char[1024];
        int len;
        while ((len = isr.read(c)) != -1){
            System.out.println(new String(c,0,len));
        }
        
        isr.close();
    }
}

案例4:复制Java文件

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-XlB0G8SK-1651821374375)(F:\image\图片\学习\Screenshot_20220429-001821.jpg)]

package basics.io.character_stream;

import java.io.*;

//案例:复制Java文件   把JavaSE\\src\\basics\\io\\byte_stream\\Example1.java    复制到本目录下
//JavaSE\\src\\basics\\io\\character_stream\\Example1.java
public class Example4 {
    public static void main(String[] args) throws IOException {
        InputStreamReader isr = new InputStreamReader(new FileInputStream("JavaSE\\src\\basics\\io\\byte_stream\\Example1.java"));
        OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("JavaSE\\src\\basics\\io\\character_stream\\Example1.java"));


//        int len;
//        while ((len = isr.read()) != -1){
//            osw.write(len);
//        }

        char[] c = new char[1024];
        int len;
        while ((len = isr.read(c)) != -1){
            osw.write(c,0,len);
        }

        isr.close();
        osw.close();
    }
}

案例5:复制Java文件改进版

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-V6I3JwxK-1651821374376)(F:\image\图片\学习\Screenshot_20220429-002236.jpg)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Xmnl63ji-1651821374376)(F:\image\图片\学习\Screenshot_20220429-002243.jpg)]

package basics.io.character_stream;

import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;

//复制Java文件(改进版)
/*
转换流的名字太长,而我们常见的操作都是在默认的字符编码集下实现,所以为了简化书写,转换流提供了对应的子类
    FileReader:用于读取字符文件的便捷类
        FileReader(String FileName)
    FileWriter:用于写入字符文件的便捷类
        FileWriter(String FileName)
 */
public class Example5 {
    public static void main(String[] args) throws IOException {
        FileReader fr = new FileReader("JavaSE\\src\\basics\\io\\byte_stream\\Example2.java");
        FileWriter fw = new FileWriter("JavaSE\\src\\basics\\io\\character_stream\\Example2.java");

//        int i;
//        while ((i = fr.read()) != -1){
//            fw.write(i);
//        }

        char[] c = new char[1024];
        int len;
        while ((len = fr.read(c)) != -1){
            fw.write(c,0,len);
        }

        fr.close();
        fw.close();
    }
}

7.字符缓冲流

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-9DkMXBj8-1651821374377)(F:\image\图片\学习\Screenshot_20220429-002636.jpg)]

package basics.io.character_stream;

import java.io.*;

/*
字符缓冲流:
    字符输入缓冲流:BufferedReader(Reader in)
    字符输出缓冲流:BufferedWriter(Writer out)
 */
public class Test07 {
    public static void main(String[] args) throws IOException {
        //字符输出缓冲流
        //BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(new FileOutputStream("")));
//        BufferedWriter bw = new BufferedWriter(new FileWriter("JavaSE\\src\\basics\\io\\character_stream\\test2.txt"));
//
//        bw.write("中国");
//
//        bw.close();

        //字符输入缓冲流
//        BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream("")));
        BufferedReader br = new BufferedReader(new FileReader("JavaSE\\src\\basics\\io\\character_stream\\test2.txt"));

//        int i;
//        while ((i = br.read()) != -1){
//            System.out.print((char) i);
//        }

        char[] c = new char[1024];
        int len;
        while ((len = br.read(c)) != -1){
            System.out.print(new String(c,0,len));
        }

        br.close();
    }

}

案例6:复制Java文件,字符缓冲流改进版

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-QJOovmIq-1651821374377)(F:\image\图片\学习\Screenshot_20220429-003329.jpg)]

package basics.io.character_stream;

import java.io.*;

//字符缓冲流复制Java文件
public class Example6 {
    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new FileReader("JavaSE\\src\\basics\\io\\byte_stream\\Example3.java"));
        BufferedWriter bw = new BufferedWriter(new FileWriter("JavaSE\\src\\basics\\io\\character_stream\\Example3.java"));

//        int i;
//        while ((i = br.read()) != -1){
//            bw.write(i);
//        }

        char[] c = new char[1024];
        int len;
        while ((len = br.read(c)) != -1){
            bw.write(c,0,len);
        }

        br.close();
        bw.close();
    }
}

8.字符缓冲流特有功能

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-zqo0MHfP-1651821374378)(F:\image\图片\学习\Screenshot_20220429-003801.jpg)]

package basics.io.character_stream;

import java.io.*;

//字符缓冲流特有功能
//  void newLine(); 写一行行分隔符,行分隔符字符串由系统属性定义
//  public StringreadLine():读一行文字,结果包含行的内容的字符串,如果流的结尾已到达则为空
public class Test08 {
    public static void main(String[] args) throws IOException {
        /*
        BufferedWriter bw = new BufferedWriter(new FileWriter("JavaSE\\src\\basics\\io\\character_stream\\test3.txt"));

//        bw.write("中国");
//        bw.newLine();
//        bw.write("世界");

        for (int i = 0; i < 10; i++) {
            bw.write("hello");
            bw.newLine();
        }

        bw.close();
         */

        
        BufferedReader br = new BufferedReader(new FileReader("JavaSE\\src\\basics\\io\\character_stream\\test3.txt"));
        /*
        //第一次读
        String s = br.readLine();
        System.out.println(s);

        //第二次读
        s = br.readLine();
        System.out.println(s);

        //第三次第四次读
        s = br.readLine();
        System.out.println(s);
        s = br.readLine();
        System.out.println(s);
         */
        
        String s;
        while ((s = br.readLine()) != null){
            System.out.println(s);
        }

        br.close();
    }
}

案例7:复制Java文件,字符缓冲流特有功能改进版

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-NImOJHRI-1651821374378)(F:\image\图片\学习\Screenshot_20220429-004356.jpg)]

package basics.io.character_stream;

import java.io.*;

//复制Java文件:字符缓冲流特有功能改进版
public class Example7 {
    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new FileReader("JavaSE\\src\\basics\\io\\byte_stream\\Example1.java"));
        BufferedWriter bw = new BufferedWriter(new FileWriter("JavaSE\\src\\basics\\io\\character_stream\\Example11.java"));

        String s;
        while ((s = br.readLine()) != null){
            bw.write(s);
            bw.flush();
            bw.newLine();
        }

        br.close();
        bw.close();
    }
}

案例8:文件到集合

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-VC3s3xxP-1651821374380)(C:\Users\86177\AppData\Roaming\Typora\typora-user-images\image-20220502101428872.png)]

package basics.io.special_stream;

import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;

//把文本文件中的数据读取到集合中,并遍历集合,要求,文件中的每一行数据是一个集合元素
public class Example1 {
    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new FileReader("JavaSE\\src\\basics\\io\\special_stream\\test.txt"));

        ArrayList<String> list = new ArrayList<>();

        String s;
        while ((s = br.readLine()) != null){
            list.add(s);
        }

        br.close();

        System.out.println(list.size());

        for (String ss : list){
            System.out.println(ss);
        }
    }
}

案例9:集合到文件

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-pd7BtvFX-1651821374381)(C:\Users\86177\AppData\Roaming\Typora\typora-user-images\image-20220502101445299.png)]

package basics.io.character_stream;

import java.io.BufferedWriter;
import java.io.FileWriter;
import java.io.IOException;
import java.util.ArrayList;

//把ArrayList集合中的字符串数据写入到文本文件,要求,每一个字符串元素作为文件中的一行数据
public class Example9 {
    public static void main(String[] args) throws IOException {
        ArrayList<String> list = new ArrayList<>();

        list.add("你好");
        list.add("世界");
        list.add("Java");
        list.add("为中华之崛起而读书");

        BufferedWriter bw = new BufferedWriter(new FileWriter("JavaSE\\src\\basics\\io\\character_stream\\Example9.txt"));

        for (String s : list){
            bw.write(s);
            bw.newLine();
            bw.flush();
        }

        bw.close();
    }
}

案例10.点名器

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-YtJcUpCf-1651821374381)(C:\Users\86177\AppData\Roaming\Typora\typora-user-images\image-20220502101437067.png)]

package basics.io.character_stream;

import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.util.*;

//我有一个文件里面存储了班里同学姓名,每一个姓名占一行,要求通过程序实现随机点名器
public class Example10 {
    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new FileReader("JavaSE\\src\\basics\\io\\character_stream\\Example10.txt"));

        ArrayList<String> list = new ArrayList<>();

        String s;
        while ((s = br.readLine()) != null){
            list.add(s);
        }

        br.close();

        //(黑马视频方法)利用随机数索引到集合找值进行随机点名
//        Random random = new Random();
//        int i = random.nextInt(list.size());
//
//        String s1 = list.get(i);
//
//        System.out.println(s1);

        
        //(我的方法)利用Collections.shuffle()方法打乱集合内容进行随机点名
        Collections.shuffle(list);

        for (String ss : list){
            System.out.println(ss);
            break;
        }
    }
}

案例11.集合到文件改进版

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-692aL8gz-1651821374381)(F:\image\图片\学习\Screenshot_20220502-231340.jpg)]

package basics.io.character_stream;

import java.io.BufferedWriter;
import java.io.FileWriter;
import java.io.IOException;
import java.util.ArrayList;

/*
集合到文件改进版
    需求:把ArrayList集合中的学生数据写入到文本文件,
    要求:每一个学生对象的数据作为文件中的一行数据
    格式:学号,姓名,年龄,居住地         举例:ithongma001,张三,27,庆阳
 */
public class Example11 {
    public static void main(String[] args) throws IOException {
        ArrayList<Student> list = new ArrayList<>();

        Student student1 = new Student("ithongma001", "张三", 23, "庆阳");
        Student student2 = new Student("ithongma002", "李四", 21, "西安");
        Student student3 = new Student("ithongma003", "王五", 25, "上海");

        list.add(student1);
        list.add(student2);
        list.add(student3);

        BufferedWriter bw = new BufferedWriter(new FileWriter("JavaSE\\src\\basics\\io\\character_stream\\student.txt"));

        for (Student s : list){
            bw.write(s.getId() + "," + s.getName() + "," + s.getAge() + "," + s.getAddress());
            bw.newLine();
            bw.flush();
        }

        bw.close();
    }
}












/*
package basics.io.character_stream;

public class Student {
    private String id;
    private String name;
    private int age;
    private String address;

    public Student() {
    }

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

    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

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

 */

案例12.文件到集合改进版

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-bkW2wyub-1651821374382)(F:\image\图片\学习\Screenshot_20220502-231459.jpg)]

package basics.io.character_stream;

import java.io.*;
import java.util.ArrayList;

/*
文件到集合改进版
    需求:把文本文件中的数据读取到集合中,并遍历集合
    要求:文件中的每一行数据是一个学生对象的成员变量值   举例:ithongma001,张三,27,庆阳
 */
public class Example12 {
    public static void main(String[] args) throws IOException {
        //创建字符输如缓冲流对象
        BufferedReader br = new BufferedReader(new FileReader("JavaSE\\src\\basics\\io\\character_stream\\student.txt"));

        //创建存储Student的集合
        ArrayList<Student> list = new ArrayList<>();

        //按行读取数据,读一行在集合中添加一个学生对象
        String s;
        while ((s = br.readLine()) != null){
            //利用split方法将字符串分割为字符串数组
            String[] split = s.split(",");

            //创建学生对象,数组0下标的为id;数组1下标的为姓名;数组2下标的为年龄,需要用Integer的parseInt方法转换为Int类型;数组3下标的为居住地
            Student student = new Student(split[0], split[1], Integer.parseInt(split[2]), split[3]);

            //添加学生对象
            list.add(student);
        }
        
        //遍历集合
        for (Student student : list){
            System.out.println(student.getId() + "," + student.getName() + "," + student.getAge() + "," + student.getAddress());
        }

        //关闭流
        br.close();
    }
}

案例13.集合到文件(数据排序改进版)

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-LruQWNwI-1651821374382)(F:\image\图片\学习\Screenshot_20220502-231636.jpg)]

package basics.io.character_stream;

import java.io.BufferedWriter;
import java.io.FileWriter;
import java.io.IOException;
import java.util.Comparator;
import java.util.Scanner;
import java.util.TreeSet;

/*
集合到文件数据排序改进版
    键盘录入5个学生信息(姓名,语文成绩,数学成绩,英语成绩),要求按照成绩总分从高到低写入文本文件
    格式:姓名,语文成绩,数学成绩,英语成绩        举例:张三,98,99,100
 */
public class Example13 {
    public static void main(String[] args) throws IOException {
        //由于需要排序,所以用TreeSet接收
        TreeSet<Student2> student2s = new TreeSet<>(new Comparator<Student2>() {
            @Override
            //比较器
            public int compare(Student2 o1, Student2 o2) {
                //按总分排序
                int num = (o2.getChinese() + o2.getMath() + o2.getEnglish()) - (o1.getChinese() + o1.getMath() + o1.getEnglish());
                if (num == 0){
                    //总分相同,按语文成绩
                    int num1 = o2.getChinese() - o1.getChinese();
                    if (num1 == 0){
                        //语文成绩相同,按数学成绩
                        int num2 = o2.getMath() - o1.getMath();
                        if (num2 == 0){
                            //数学成绩相同,按英语成绩
                            int num3 = o2.getEnglish() - o1.getEnglish();
                            if (num3 == 0){
                                //英语成绩相同,按姓名
                                return o1.getName().compareTo(o2.getName());
                            }
                            return num3;
                        }
                        return num2;
                    }
                    return num1;
                }
                return num;
            }
        });

        //创建学生对象
        Student2 student2;

        //创建字符缓冲输出流对象
        BufferedWriter bw = new BufferedWriter(new FileWriter("JavaSE\\src\\basics\\io\\character_stream\\Student2.txt"));

        Scanner sc = new Scanner(System.in);

        for (int i = 0; i < 5; i++) {
            System.out.print("请输入第" + (i + 1) + "个人的姓名:");
            String s = sc.nextLine();

            System.out.print("请输入语文成绩:");
            int i1 = sc.nextInt();

            System.out.print("请输入数学成绩:");
            int i2 = sc.nextInt();

            System.out.print("请输入英语成绩:");
            int i3 = sc.nextInt();

            sc.nextLine(); //防止第二轮跳过nextLine

            int i4 = i1 + i2 + i3;

            //添加学生对象
            student2 = new Student2(s,i1,i2,i3,i4);
            student2s.add(student2);
        }

        //遍历TreeSet并写数据
        for (Student2 student22 : student2s){
            bw.write(student22.getName() + "," + student22.getChinese() + "," + student22.getMath() + "," + student22.getEnglish() + "," + student22.getSum());
            bw.newLine();
            bw.flush();
        }

        //关闭流
        bw.close();
    }
}



/*
小红,93,72,93,258
小明,90,95,70,255
张三,84,85,80,249
李四,82,85,79,246
王五,81,73,70,224
 */

案例14.复制单级文件夹

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-2YD7q28E-1651821374383)(F:\image\图片\学习\Screenshot_20220502-232011.jpg)]

package basics.io.character_stream;

import java.io.*;

/*
复制单级文件夹
    需求:把F:\python\test\io_test   复制到模块目录下JavaSE\\src\\basics\\io\\character_stream\\io_test
 */
public class Example14 {
    public static void main(String[] args) throws IOException {
        //创建数据源File对象
        File file = new File("F:\\python\\io_test");

        //获取数据源目录名字
        String name = file.getName();

        //获取数据源目录中的文件和目录File对象数组
        //File[] files = file.listFiles();

        //获取目的地目录中的文件和目录File对象数组
        File[] files1 = new File("JavaSE\\src\\basics\\io\\character_stream").listFiles();

        //遍历目的地目录中的文件和目录File对象数组
        for (File f : files1){
            //如果有和数据源目录相同的目录名字,则直接在此目录中复制即可
            if (f.getName() == name) {
//                //遍历数据源目录中的文件和目录File对象数组
//                for (File file2 : files){
//                    //创建输入输出字节缓冲流对象
//                    BufferedInputStream bis = new BufferedInputStream(new FileInputStream(file2));
//                    BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(f + "\\" + file2.getName()));
//
//                    //进行一个字节的读和写
//                    int i;
//                    while ((i = bis.read()) != -1){
//                        bos.write(i);
//                    }
//
//                    bis.close();
//                    bos.close();
//                    return;
//                }

                //调用复制的方法,然后用return终止
                copy(file,f);
                return;
            }
        }

        //如果循环走完,说明目的地没有和数据源目录名字相同的目录名,则需要在目的地创建一个和数据源目录名相同的目录
        File file1 = new File("JavaSE\\src\\basics\\io\\character_stream\\"+name);
        file1.mkdir();

//        //遍历数据源目录中的文件和目录File对象数组
//        for (File file2 : files){
//            //创建输入输出字节缓冲流对象
//            BufferedInputStream bis = new BufferedInputStream(new FileInputStream(file2));
//            BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(file1 + "\\" + file2.getName()));
//
//            //进行一个字节的读和写
//            int i;
//            while ((i = bis.read()) != -1){
//                bos.write(i);
//            }
//
//            //关闭流
//            bis.close();
//            bos.close();
//        }

        //调用复制的方法
        copy(file,file1);

    }

    //复制数据的方法
    public static void copy(File f1,File f2) throws IOException{
        File[] files = f1.listFiles();

        for (File f : files){
            BufferedInputStream bis = new BufferedInputStream(new FileInputStream(f));
            BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(f2 + "\\" + f.getName()));

            int i;
            while ((i = bis.read()) != -1){
                bos.write(i);
            }

            bis.close();
            bos.close();
        }
    }
}

案例15:复制多级文件夹

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-uuVv6bCz-1651821374383)(C:\Users\86177\AppData\Roaming\Typora\typora-user-images\image-20220504102724304.png)]

package basics.io.character_stream;

import java.io.*;

/*
复制多级文件夹
    把  F:\python\io_test2 复制到模块目录下 JavaSE\\src\\basics\\io\\io_test2
 */
public class Example15 {
    public static void main(String[] args) throws IOException {
        //创建数据源File对象
        File file = new File("F:\\python\\io_test2");
        //获取数据源对象目录的名字
        String name = file.getName();

        //创建目的地File对象
        File file1 = new File("JavaSE\\src\\basics\\io\\character_stream");
        //获取目的地目录下的文件或者目录集合
        File[] files = file1.listFiles();

        //遍历目的地目录下的文件或者目录集合
        for (File f : files){
            //如果有和数据源目录名相同的名字,则直接调用复制方法,并用return终止
            if (f.getName() == name){
                copy(file,f);
                return;
            }
        }

        //如果循环走完,说明没有和数据源目录名相同的名字,则创建该目录,然后调用复制方法
        File file2 = new File("JavaSE\\src\\basics\\io\\character_stream\\" + name);
        file2.mkdir();
        copy(file,file2);

    }

    //复制方法
    public static void copy(File f1,File f2) throws IOException {
        //获取数据源目录下的文件或目录集合
        File[] files = f1.listFiles();

        //遍历数据源目录下的文件或目录集合
        for (File f : files){
            //如果是文件,直接复制
            if (f.isFile()){
                //创建字节输入缓冲流对象
                BufferedInputStream bis = new BufferedInputStream(new FileInputStream(f));
                //创建字节输出缓冲流对象
                BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(f2 + "\\" + f.getName()));

                //一个字节的读和写
                int i;
                while ((i = bis.read()) != -1){
                    bos.write(i);
                }

                //关闭流
                bis.close();
                bos.close();
            }else {    //如果不是文件,即是目录
                //获取目的地目录下的文件或目录集合
                File[] files1 = f2.listFiles();

                //遍历目的地目录下的文件或目录集合
                for (File f3 : files1){
                    //如果有和数据源目录名相同的目录
                    if (f3.getName() == f.getName()){
                        //直接递归调用复制方法
                        copy(f,f3);
                    }
                }

                //如果循环走完,说明没有和数据源目录名相同的目录,所以创建该目录,然后递归调用复制方法
                File file = new File(f2 + "\\" + f.getName());
                file.mkdir();
                copy(f,file);
            }
        }
    }
}

10.复制文件的异常处理

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-yEwevVpS-1651821374384)(C:\Users\86177\AppData\Roaming\Typora\typora-user-images\image-20220504115615456.png)]

package basics.io.character_stream;

import java.io.*;

//复制文件的异常处理
public class Test10 {
    public static void main(String[] args) {

    }

    //抛出处理
    public static void method() throws IOException {
        BufferedReader br = new BufferedReader(new FileReader("F:\\python\\呐喊.txt"));
        BufferedWriter bw = new BufferedWriter(new FileWriter("JavaSE\\src\\basics\\io\\character_stream\\Example10.txt"));

        String s;
        while ((s = br.readLine()) != null) {
            bw.write(s);
            bw.newLine();
            bw.flush();
        }

        br.close();
        bw.close();
    }

    //try{}catch{}finally{}处理方法
    public static void method1() {
        BufferedReader br = null;
        BufferedWriter bw = null;
        try {
            br = new BufferedReader(new FileReader("F:\\python\\呐喊.txt"));
            bw = new BufferedWriter(new FileWriter("JavaSE\\src\\basics\\io\\character_stream\\Example10.txt"));

            String s;
            while ((s = br.readLine()) != null) {
                bw.write(s);
                bw.newLine();
                bw.flush();
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (br != null) {
                try {
                    br.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (bw != null) {
                try {
                    bw.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    //JDK7改进方案(推荐)
    public static void method2() {
        try (BufferedReader br = new BufferedReader(new FileReader("F:\\python\\呐喊.txt"));
             BufferedWriter bw = new BufferedWriter(new FileWriter("JavaSE\\src\\basics\\io\\character_stream\\Example10.txt"));
        ) {
            String s;
            while ((s = br.readLine()) != null) {
                bw.write(s);
                bw.newLine();
                bw.flush();
            }

        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /*
    //JDK9改进方案
    public static void method3() {
        BufferedReader br = new BufferedReader(new FileReader("F:\\python\\呐喊.txt"));
        BufferedWriter bw = new BufferedWriter(new FileWriter("JavaSE\\src\\basics\\io\\character_stream\\Example10.txt"));

        try (br;bw){
            String s;
            while ((s = br.readLine()) != null) {
                bw.write(s);
                bw.newLine();
                bw.flush();
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
     */
    
}

特殊操作流

1.标准输入输出流

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-gHB4kMmb-1651821374384)(C:\Users\86177\AppData\Roaming\Typora\typora-user-images\image-20220504193528566.png)]

package basics.io.special_stream;

import java.io.*;
import java.util.Scanner;

/*
标准输入流(本质是字节输入流)
    System类中有一个静态的成员变量
        public static final inputStream in     标准输入流
*/
public class Test01 {
    public static void main(String[] args) throws IOException {
        /*
        //public static final inputStream in     标准输入流
        InputStream in = System.in;

//        int i;
//        while ((i = in.read()) != -1){
//            System.out.print((char) i);
//        }

        //如何把字节流转换为字符流? 用转换流
        InputStreamReader isr = new InputStreamReader(in);

//        int i;
//        while ((i = isr.read()) != -1){
//            System.out.print((char) i);
//        }

        //字符流实现一次读取一行数据,但是这是字符缓冲流特有的方式,所以需要把字符流包装成字符缓冲流
        BufferedReader br = new BufferedReader(isr);

        String s;
        while ((s = br.readLine()) != null){
            System.out.println(s);
        }

        in.close();
         */

        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        System.out.print("请输入一个字符串:");
        String s = br.readLine();
        System.out.println("你输入的字符串是:" + s);

        System.out.print("请输入一个整数:");
        int i = Integer.parseInt(br.readLine());
        System.out.println("你输入的整数是:" + i);

        //自己录入太麻烦,所以Java提供了一个类供我们使用
        Scanner sc = new Scanner(System.in);
        System.out.print("请输入一个字符串:");
        String s1 = sc.nextLine();
        System.out.println("你输入的字符串是:" + s1);

        System.out.print("请输入一个整数:");
        int i1 = sc.nextInt();
        System.out.println("你输入的整数是:" + i1);
    }
}

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-6F6oS73y-1651821374385)(F:\image\图片\学习\Screenshot_20220504-001043.jpg)]

    package basics.io.special_stream;

    import java.io.IOException;
    import java.io.PrintStream;

    /*
    标准输出流(本质是字节输出流)
        System类中有一个静态的成员变量
            public static final inputStream out     标准输出流
    */
    public class Test01_2 {
        public static void main(String[] args) throws IOException {
            /*
            PrintStream ps = System.out;

    //        ps.write(97);
    //        ps.write("\n".getBytes());
    //        ps.write(98);
    //        ps.write("\n".getBytes());
    //        ps.write(99);

    //        ps.print(97);
    //        ps.print(98);
    //        ps.print(99);

            ps.println(97);
            ps.println(98);
            ps.println(99);


            ps.close();
             */

//            PrintStream类有的方法,System.out都可以使用
            System.out.write(98);
            System.out.write(99);

            System.out.println();

            System.out.println("hello");
            System.out.print("hello");
        }
    }

2.打印流

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-RyBcu80U-1651821374385)(F:\image\图片\学习\Screenshot_20220504-002609.jpg)]

package basics.io.special_stream;

import java.io.IOException;
import java.io.PrintStream;
import java.io.PrintWriter;

/*
打印流的特点:
    只负责输出数据(写数据),不负责读取数据
    有自己特有的方法
字节打印流:
    PrintStream(String fileName)     使用指定的文件名创建新的打印流
    使用继承父类的方法写数据,查看的时候会转码,使用自己特有的方法写数据,查看的时候原样输出
 */
public class Test02_1 {
    public static void main(String[] args) throws IOException {
        //字节打印流
        PrintStream ps = new PrintStream("JavaSE\\src\\basics\\io\\special_stream\\Test02_1.txt");

        //使用父类字节输出流的方法写数据,会转码
//        ps.write(97);//a
//        ps.write(98);//b
//        ps.write(99);//c

        //使用特有的方法写数据,原样输出
        ps.print(97);
        ps.print(98);
        ps.print(99);

        ps.println();

        ps.println("hello");

        ps.close();
    }
}

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-9lE9UIR4-1651821374385)(F:\image\图片\学习\Screenshot_20220504-002906.jpg)]

package basics.io.special_stream;

import java.io.*;

/*
字符PrintWriter打印流的构造方法
    PrintWriter(String fileName)    使用指定的文件名创建一个新的PrintWriter,而不需要自动执行刷新
    PrintWriter(Writer out,boolean autoFlush)   out:字符输出流   autoFlush:如果为真,则print,printf,format将刷新输出缓冲区
 */
public class Test02_2 {
    public static void main(String[] args) throws IOException {
        /*
//        PrintWriter(String fileName)    使用指定的文件名创建一个新的PrintWriter,而不需要自动执行刷新
        PrintWriter pw = new PrintWriter("JavaSE\\src\\basics\\io\\special_stream\\Test02_2.txt");

//        pw.write("hello");
//        pw.write("\n");
//        pw.write(97);

        pw.print("hello");
        pw.println();
        pw.print(97);
        pw.flush();//需要刷新流

        pw.close();
         */

        //PrintWriter(Writer out,boolean autoFlush)   out:字符输出流   autoFlush:如果为真,则print,printf,format将刷新输出缓冲区
//        OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("JavaSE\\src\\basics\\io\\special_stream\\Test02_2.txt"));
//        PrintWriter pw = new PrintWriter(osw, true);

//        PrintWriter pw = new PrintWriter(new OutputStreamWriter(new FileOutputStream("JavaSE\\src\\basics\\io\\special_stream\\Test02_2.txt")), true);
        PrintWriter pw = new PrintWriter(new FileWriter("JavaSE\\src\\basics\\io\\special_stream\\Test02_2.txt"),true);

//        pw.write("hello");
//        pw.write("\n");
//        pw.write(97);

//        pw.print("hello");

//        pw.println("hello");
//        pw.println(97);
//
        pw.print("hello");
        pw.println();
//        pw.println(97);
        pw.close();

        //print方法还是不能自动刷新
//        pw.print("hello");
        pw.print(97);

    }
}

案例1:复制Java文件(打印流改进版)

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-geu24rL3-1651821374386)(F:\image\图片\学习\Screenshot_20220504-003936.jpg)]

package basics.io.special_stream;

import java.io.*;

/*
复制Java文件,打印流改进版
    把模块目录JavaSE\\src\\basics\\io\\file\\Example.java  复制到  本目录下Example.java
 */
public class Example1 {
    public static void main(String[] args) throws IOException {
        //因为打印流只负责写数据,不负责读数据,所以创建字符输入缓冲流对象读数据
        BufferedReader br = new BufferedReader(new FileReader("JavaSE\\src\\basics\\io\\file\\Example.java"));

        //创建字符打印流对象写数据
        PrintWriter pw = new PrintWriter(new FileWriter("JavaSE\\src\\basics\\io\\special_stream\\Example.java"), true);

        //使用字符输入缓冲流的特有方法,一次读一行数据
        String s;
        while ((s = br.readLine()) != null){
            //使用字符打印流的特有方法写数据
            pw.println(s);
        }

        //关闭流
        br.close();
        pw.close();
    }
}

3.对象序列化流

对象序列化流

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Hj9qNnoQ-1651821374386)(F:\image\图片\学习\Screenshot_20220504-004128.jpg)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-61llpBZf-1651821374386)(F:\image\图片\学习\Screenshot_20220504-005339.jpg)]

package basics.io.special_stream;

import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectOutputStream;

/*
对象序列化流(输出流):
    构造方法:
        ObjectOutputStream(OutputStream out):创建一个写入指定的OutputStream的ObjectOutputStream
    序列化对象的方法:
        void writerObject(Object obj):将指定的对象写入对象序列化流ObjectOutputStream

    java.io.NotSerializableException    抛出一个实例需要一个Serializable接口。 序列化运行时或实例的类可能会抛出此异常。
    类的序列化由实现java.io.Serializable接口的类启用。 不实现此接口的类将不会使任何状态序列化或反序列化。
    Serializable接口是一个标记接口,实现该接口不需要重写任何方法
 */
public class Test03_1 {
    public static void main(String[] args) throws IOException {
        //ObjectOutputStream(OutputStream out):创建一个写入指定的OutputStream的ObjectOutputStream
        ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("JavaSE\\src\\basics\\io\\special_stream\\Test03_1.txt"));

        //创建学生对象
        Test03_Student s = new Test03_Student("张三", 18);

        //void writerObject(Object obj):将指定的对象写入对象序列化流ObjectOutputStream
        oos.writeObject(s);  //java.io.NotSerializableException

        //释放资源
        oos.close();
    }
}







/*
package basics.io.special_stream;

import java.io.Serializable;

//学生类
public class Test03_Student implements Serializable {
    private String name;
    private int age;

    public Test03_Student() {
    }

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

    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;
    }
}
 */
对象反序列化流

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-6tNfQ2yW-1651821374387)(F:\image\图片\学习\Screenshot_20220504-010213.jpg)]

package basics.io.special_stream;

import java.io.FileInputStream;
import java.io.IOException;
import java.io.ObjectInputStream;

/*
对象反序列化流(输入流,读取):ObjectInputStream   反序列化原先使用ObjectOutputStream编写的原始数据和对象
    构造方法:
        ObjectInputStream(InputStream in): 创建从指定的InputStream读取的ObjectInputStream
    反序列化对象的方法:
        Object readObject(); 从ObjectInputStream读取一个对象
 */
public class Test03_2 {
    public static void main(String[] args) throws IOException, ClassNotFoundException {
        //ObjectInputStream(InputStream in): 创建从指定的InputStream读取的ObjectInputStream
        ObjectInputStream ois = new ObjectInputStream(new FileInputStream("JavaSE\\src\\basics\\io\\special_stream\\Test03_1.txt"));

        //Object readObject(); 从ObjectInputStream读取一个对象
        Object o = ois.readObject();

        //向下转型为Student
        Test03_Student s = (Test03_Student) o;
        System.out.println(s.getName() + "," + s.getAge());

        //关闭资源
        ois.close();
    }
}
对象序列化流问题

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-9FBgUla3-1651821374387)(F:\image\图片\学习\Screenshot_20220504-012230.jpg)]

package basics.io.special_stream;

import java.io.*;

/*
1.用对象序列化流序列化一个对象后,假如我们修改了对象所属的类文件,读取数据会不会出问题?
    java.io.InvalidClassException
        当序列化运行时检测到类中的以下问题之一时抛出。
            类的串行版本与从流中读取的类描述符的类型不匹配
                stream classdesc serialVersionUID = 5930742638691495298
                local class serialVersionUID = 7838320422610157295
            该类包含未知的数据类型
            该类没有可访问的无参数构造函数

如果可序列化类没有显式声明serialVersionUID,则序列化运行时将根据Java(TM)对象序列化规范中所述的类的各个方面计算该类的默认serialVersionUID值。
但是, 强烈建议所有可序列化的类都明确声明serialVersionUID值,因为默认的serialVersionUID计算对类详细信息非常敏感,这可能会因编译器实现而异,
因此可能会在反InvalidClassException化期间导致InvalidClassException的InvalidClassException。
因此,为了保证不同Java编译器实现之间的一致的serialVersionUID值,一个可序列化的类必须声明一个显式的serialVersionUID值。
还强烈建议,显式的serialVersionUID声明在可能的情况下使用private修饰符,因为这种声明仅适用于立即声明的类 - serialVersionUID字段作为继承成员无效。
数组类不能声明一个显式的serialVersionUID,所以它们总是具有默认的计算值,但是对于数组类,放弃了匹配serialVersionUID值的要求

2.如果出了问题该如何解决
    在要序列化的对象所属类中显示的定义serialVersionUID
    private static final long serialVersionUID = 42L;

3.如果一个对象的某个成员变量的值不想被序列化,该如何实现
    把该成员变量用transient关键字修饰
 */
public class Test03_3 {
    public static void main(String[] args) throws IOException, ClassNotFoundException {
        read();
//        write();
    }

    //对象序列化方法
    public static void write() throws IOException{
        ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("JavaSE\\src\\basics\\io\\special_stream\\Test03_3.txt"));

        Test03_Student s = new Test03_Student("张三", 18);

        oos.writeObject(s);

        oos.close();
    }

    //对象反序列化方法
    public static void read() throws IOException, ClassNotFoundException {
        ObjectInputStream ois = new ObjectInputStream(new FileInputStream("JavaSE\\src\\basics\\io\\special_stream\\Test03_3.txt"));

//        Object o = ois.readObject();
//        Test03_Student s = (Test03_Student)o;

        Test03_Student s = (Test03_Student)ois.readObject();
        System.out.println(s.getName() + "," + s.getAge());

        ois.close();
    }
}



/*
package basics.io.special_stream;

import java.io.Serializable;

//学生类
public class Test03_Student implements Serializable {
    private static final long serialVersionUID = 42L;
    private String name;

    private transient int age;  //transient 修饰的成员变量表示该成员变量不想被序列化

    public Test03_Student() {
    }

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

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

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

 */

4.Properties

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-XlalTAFL-1651821374387)(F:\image\图片\学习\Screenshot_20220504-012335.jpg)]

package basics.io.special_stream;

import java.util.Map;
import java.util.Properties;
import java.util.Set;

//Propertis
//Propertis作为Map集合的使用
public class Test04 {
    public static void main(String[] args) {
        //创建Propertis对象
//        Properties<Integer,String> propwerties = new Properties();    错误
//        不能像Map集合一样写泛型,Propertis没有泛型
        Properties properties = new Properties();

        //存储元素
        properties.put(1,"张三");
        properties.put(2,"李四");
        properties.put(3,"王五");

        //遍历集合
//        Set<Object> objects = properties.keySet();
//
//        for (Object key : objects) {
//            Object value = properties.get(key);
//            System.out.println(key + "," + value);
//        }

        Set<Map.Entry<Object, Object>> entries = properties.entrySet();
        for (Map.Entry<Object, Object> entry : entries) {
            Object key = entry.getKey();
            Object value = entry.getValue();
            System.out.println(key + "," + value);
        }
    }
}

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-kWXidIeY-1651821374388)(F:\image\图片\学习\Screenshot_20220504-012619.jpg)]

package basics.io.special_stream;

import java.util.Properties;
import java.util.Set;

/*
Propertis作为集合的特有方法
    Object setProperty(String key,String value),设置集合的键和值,都是String类型,顶层调用Hashtable方法put
    String getProperty(String key)  使用此属性列表中指定的键搜索属性
    Set<String> stringPropertyName()  从该属性列表中返回一个不可修改的键集,其中键及其对应的值是字符串
 */
public class Test04_2 {
    public static void main(String[] args) {
        Properties properties = new Properties();

        //Object setProperty(String key,String value),设置集合的键和值,都是String类型,顶层调用Hashtable方法put
        properties.setProperty("001", "张三");
        properties.setProperty("003", "王五");
        properties.setProperty("002", "李四");

        //String getProperty(String key)  使用此属性列表中指定的键搜索属性
        String property = properties.getProperty("001");
        System.out.println(property);

        //Set<String> stringPropertyName()  从该属性列表中返回一个不可修改的键集,其中键及其对应的值是字符串
        Set<String> set = properties.stringPropertyNames();
        for (String s : set) {
            Object o = properties.get(s);
            System.out.println(s + "," + o);
        }

    }
}

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-VdckePR9-1651821374388)(F:\image\图片\学习\Screenshot_20220504-013044.jpg)]

package basics.io.special_stream;

import java.io.*;
import java.util.Properties;

/*
Propertis和IO流结合的方法
    void load(InputStream inStream)     从输入字节流读取属性列表(键和元素对)
    void store(OutputStream out,String comments)
    将此属性列表(键和元素对)写入Propertis表中以适合于使用load(InputStream)方式的格式写入输出字节流

    void load(Reader reader)    从输入字符流读取属性列表(键和元素对)
    void store(Writer writer,String comments)
    将此属性列表(键和元素对)写入Propertis表中以适合于使用load(Reader)方式的格式写入输出字符流
 */
public class Test04_3 {
    public static void main(String[] args) throws IOException {
//        byteStore();
//        byteLoad();
//        charStore();
        charLoad();
    }

    //写入字节流
    public static void byteStore() throws IOException {
        Properties prop = new Properties();

        prop.setProperty("001", "张三");
        prop.setProperty("002", "李四");
        prop.setProperty("003", "王五");
        prop.setProperty("004", "小红");

//        FileOutputStream fos = new FileOutputStream("");
//        prop.store(fos,null);

        prop.store(new FileOutputStream("JavaSE\\src\\basics\\io\\special_stream\\Test04_3.txt"), null);
    }
    
    //从字节流读取
    public static void byteLoad() throws IOException {
        Properties prop = new Properties();

        prop.load(new FileInputStream("JavaSE\\src\\basics\\io\\special_stream\\Test04_3.txt"));

        System.out.println(prop);
    }

    //写入字符流
    public static void charStore() throws IOException{
        Properties prop = new Properties();

        prop.setProperty("001","张三");
        prop.setProperty("002","李四");
        prop.setProperty("003","王五");
        prop.setProperty("004","小红");

        prop.store(new FileWriter("JavaSE\\src\\basics\\io\\special_stream\\Test04_3_2.txt"),null);

    }

    //从字符流读取
    public static void charLoad() throws IOException {
        Properties prop = new Properties();

        prop.load(new FileReader("JavaSE\\src\\basics\\io\\special_stream\\Test04_3_2.txt"));

        System.out.println(prop);
    }
}

案例2:游戏次数

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-DJtrZGh0-1651821374388)(F:\image\图片\学习\Screenshot_20220504-013631.jpg)]

package basics.io.special_stream;

import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.util.Properties;
import java.util.Random;
import java.util.Scanner;

/*
游戏次数:
    需求:请写程序实现猜数字小游戏,只能试玩三次,如果还想玩,提示:游戏试玩已结束,想玩请充值!
 */
public class Example2 {
    public static void main(String[] args) throws IOException {
        Properties properties = new Properties();

        properties.load(new FileReader("JavaSE\\src\\basics\\io\\special_stream\\game.txt"));

        String count = properties.getProperty("count");
        int i = Integer.parseInt(count);

        if (i >= 3){
            System.out.println("试玩已结束,想玩请充值!");     //冲多少次,文件中改为负多少
        }else {
            System.out.println("还剩" + (3 - i) + "次机会");
            numGame();
            i++;
            properties.setProperty("count",String.valueOf(i));
            properties.store(new FileWriter("JavaSE\\src\\basics\\io\\special_stream\\game.txt"),null);
        }
    }


    //猜数字游戏
    public static void numGame() {
        Scanner sc = new Scanner(System.in);
        Random random = new Random();
        int i = random.nextInt(101);

        System.out.println("猜数字游戏");

        while (true) {
            System.out.print("请输入你猜的数字:");
            int i1 = sc.nextInt();
            if (i == i1) {
                System.out.println("恭喜你猜对了!");
                break;
            } else {
                if (i1 > i) {
                    System.out.println("你猜大了!");
                } else {
                    System.out.println("你猜小了!");
                }
            }
        }

    }
}

总结

IO流小结

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

  • 字节流:
    • new FileOutputStream(String pathname)
    • new FileInputStream(String pathname)
  • 字节缓冲流:
    • new BufferedOutputStream(new FileOutputStream(String pathname))
    • new BufferedInputStream(new FileInputStream(String pathname))
  • 字符流:
    • new OutputStreamWriter (new FileOutputStream(String pathname))
    • new InputStreamReader(new FileInputStream(String pathname))
  • 字符缓冲流:
    • new BufferedWriter (new OutputStreamWriter (new FileOutputStream(String pathname))
    • new BufferedReader(new InputStreamReader(new FileInputStream(String pathname)))
  • 字符流简化:但是如果涉及到编码解码问题还得用本来的方法
    • new OutputStreamWriter (new FileOutputStream(String pathname)) = new FileWriter(String pathname)
    • new InputStreamReader(new FileInputStream(String pathname)) = new FileReader(String pathname)
    • new BufferedWriter(new FileWriter(String pathname))
    • new BufferedReader(new FileReader(String pathname))
  • 字符流写数据需要刷新
  • 字节流可以复制任意文件的数据,一般采用字节缓冲流一次读写一个字节数组的方式
  • 字符流只能复制文本数据,一般采用字符缓冲流的特有功能

注解

1.注解入门

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-qroLETnp-1651910216775)(F:\image\图片\学习\Screenshot_20220504-234052.jpg)]

2.内置注解

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-aIhG9JCE-1651910216778)(F:\image\图片\学习\Screenshot_20220504-234608.jpg)]

package annotationAndReflection.annotation;

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

//什么是注解
public class Test01 extends Object{
    //@Override     重写的注解
    @Override
    public String toString() {
        return super.toString();
    }

    //@Deprecated      不推荐程序员使用,或者有更好的替代方式,还可以使用
    @Deprecated
    public static void test(){
        System.out.println("Deprecated");
    }

    //@SuppressWarnings     抑制编译时的警告信息,放在类上,抑制类里边的警告信息;放在方法上,抑制方法里边的警告信息
    @SuppressWarnings("all")
    public void test2(){
        List list = new ArrayList();
    }

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

3.元注解

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-LWrRiRoV-1651910216778)(F:\image\图片\学习\Screenshot_20220504-235651.jpg)]

package annotationAndReflection.annotation;

import java.lang.annotation.*;

//测试元注解(负责注解其他的注解)
@myAnnotation
public class Test02 {

    @myAnnotation
    public void test(){}
}

//自定义一个注解

//@Target 用于描述注解的主要范围,参数为数组@Target(value = {})
@Target(value = {ElementType.METHOD,ElementType.TYPE})

//@Retention 用于描述注解的生命周期 (RUNTIME>CLASS>SOURCE)
//                                 运行时>class文件>源码
@Retention(value = RetentionPolicy.RUNTIME)

//@Documented  说明该注释将被包含在javadoc中
@Documented

//@Inherited  说明子类可以继承父类中的该注解
@Inherited
@interface myAnnotation{
}

4.自定义注解

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-4poSOTaG-1651910216779)(F:\image\图片\学习\Screenshot_20220505-000743.jpg)]

package annotationAndReflection.annotation;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

//自定义注解
public class Test03 {
    //注解可以显示赋值,如果注解没有默认值,我们就必须给注解赋值
//    @myAnnotation2(name = "张三")
    @myAnnotation2(age = 18,name = "张三") //参数顺序不做保证
    @myAnnotation3("张三")   //只有一个参数成员,一般是value,参数名可以省略
    public void test(){}
}


@Target(value = {ElementType.TYPE,ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@interface myAnnotation2{
    //注解的参数 :  参数类型 参数名();
    //注解默认值  default 值;
    String name() default "";
    int age();
    int id() default -1;  //默认值为-1,代表这个id不存在

    String[] schools = {"清华大学","北京大学"};
}

@Target({ElementType.TYPE,ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@interface myAnnotation3{
    String value();
//    int value();   错误
//    int age();   有超过一个参数成员就不能省略value
}

反射

1.Java反射机制概述

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-0cHEAQhz-1651910216779)(F:\image\图片\学习\Screenshot_20220505-002842.jpg)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-aGwrP2ou-1651910216780)(F:\image\图片\学习\Screenshot_20220505-003117.jpg)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-hPpXjkOn-1651910216780)(F:\image\图片\学习\Screenshot_20220505-003420.jpg)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-aAciqdx1-1651910216781)(F:\image\图片\学习\Screenshot_20220505-003448.jpg)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-AGQXAYoT-1651910216781)(F:\image\图片\学习\Screenshot_20220505-003515.jpg)]

package annotationAndReflection.annotation;

//什么叫反射
public class Test04 {
    public static void main(String[] args) throws ClassNotFoundException {
        //通过反射获取类的class对象
        Class c1 = Class.forName("annotationAndReflection.annotation.User");

        System.out.println(c1);

        Class c2 = Class.forName("annotationAndReflection.annotation.User");
        Class c3 = Class.forName("annotationAndReflection.annotation.User");
        Class c4 = Class.forName("annotationAndReflection.annotation.User");

        //一个类在内存中只能有一个Class对象
        //一个类被加载后,类的整个结构都会被封装在Class对象中
        System.out.println(c1.hashCode());  //856419764
        System.out.println(c2.hashCode());  //856419764
        System.out.println(c3.hashCode());  //856419764
        System.out.println(c4.hashCode());  //856419764
    }
}

//实体类  pojo entity
class User{
    private String name;
    private int id;
    private int age;

    public User() {
    }

    public User(String name, int id, int age) {
        this.name = name;
        this.id = id;
        this.age = age;
    }

    public String getName() {
        return name;
    }

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

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

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

2.理解Class类并获取Class实例

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-5B1qxEVy-1651910216782)(F:\image\图片\学习\Screenshot_20220505-003949.jpg)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-0ZimOmJs-1651910216782)(C:\Users\86177\AppData\Roaming\Typora\typora-user-images\image-20220505181848685.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-b74zMIuS-1651910216783)(F:\image\图片\学习\Screenshot_20220505-004219.jpg)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-W6Yqx992-1651910216783)(F:\image\图片\学习\Screenshot_20220505-004300.jpg)]

package annotationAndReflection.reflection;

//测试Class类的创建方式有哪些
public class Test02 {
    public static void main(String[] args) throws ClassNotFoundException {
        Person person = new Student();
        System.out.println("这个人的姓名是:" + person.name);

        //方法一:通过类名.class获得
        Class<Student> c1 = Student.class;
        System.out.println(c1);

        //方法二:通过对象名.getClass获得
        Class c2 = person.getClass();
        System.out.println(c2);

        //方法三:Class.forName获得
        Class c3 = Class.forName("annotationAndReflection.reflection.Student");
        System.out.println(c3);

        System.out.println(c1.hashCode());
        System.out.println(c2.hashCode());
        System.out.println(c3.hashCode());

        //方法四:基本内置类型的包装类都有一个TYPE属性
        Class c4 = Integer.TYPE;
        System.out.println(c4);

        //获得父类类型
        Class c5 = c1.getSuperclass();
        System.out.println(c5);
    }
}

class Person{
    String name;

    public Person() {
    }

    public Person(String name) {
        this.name = name;
    }

    @Override
    public String toString() {
        return "Person{" +
                "name='" + name + '\'' +
                '}';
    }
}

class Student extends Person{
    public Student(){
        this.name = "学生";
    }
}

class Teacher extends Person{
    public Teacher() {
        this.name = "老师";
    }
}

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-PZUDxqZN-1651910216784)(F:\image\图片\学习\Screenshot_20220505-005011.jpg)]

package annotationAndReflection.reflection;

import java.lang.annotation.ElementType;

//哪些类型可以有class对象
public class Test03 {
    public static void main(String[] args) {
        Class c1 = Object.class;    //类
        Class c2 = Runnable.class;  //接口
        Class c3 = String[].class;  //一维数组
        Class c4 = int[][].class;   //二维数组
        Class c5 = Override.class;  //注解
        Class c6 = ElementType.class;   //枚举
        Class c7 = Integer.class;   //基本数据类型
        Class c8 = void.class;      //void
        Class c9 = Class.class;     //Class

        //快捷键:按住alt
        System.out.println(c1);
        System.out.println(c2);
        System.out.println(c3);
        System.out.println(c4);
        System.out.println(c5);
        System.out.println(c6);
        System.out.println(c7);
        System.out.println(c8);
        System.out.println(c9);

        //只要元素类型与维度一样,就是同一个Class
        int[] a = new int[10];
        int[] b = new int[100];

        System.out.println(a.getClass().hashCode());
        System.out.println(b.getClass().hashCode());
    }
}

3.类的加载与ClassLoader

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-fY6a6reX-1651910216784)(F:\image\图片\学习\Screenshot_20220505-005510.jpg)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-WvEHvOAz-1651910216785)(F:\image\图片\学习\Screenshot_20220505-005536.jpg)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-vXy0A9xX-1651910216785)(F:\image\图片\学习\Screenshot_20220505-005614.jpg)]

package annotationAndReflection.reflection;

//类的加载
/*
1.类加载到内存,会产生一个类对应的Class对象
2.链接,链接结束后 m=0(为类变量(static)分配内存,并设置类变量默认初始值)
3.初始化
        <clinit>(){
                System.out.println("A类静态代码块初始化");
                m = 300;
                System.out.println("A类的无参构造初始化");
                m = 100;  覆盖了m = 300;
        }
 */
public class Test04 {
    public static void main(String[] args) {
        A a = new A();
        System.out.println(A.m);
    }
}

class A{
    static {
        System.out.println("A类静态代码块初始化");
        m = 300;
    }

    static int m = 100;

    public A(){
        System.out.println("A类的无参构造初始化");
    }
}


/*
A类静态代码块初始化
A类的无参构造初始化
100
 */

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Chr3gRp5-1651910216785)(F:\image\图片\学习\Screenshot_20220505-083802.jpg)]

package annotationAndReflection.reflection;

//测试类什么时候会初始化
public class Test05 {
    public static void main(String[] args) throws ClassNotFoundException {
        //1.类的主动引用,一定会发生类的初始化
        //new 一个类的对象
//        Son son = new Son();      //父类被加载  子类被加载

        //使用类的静态成员和静态方法
//        int m = Son.m;  //父类被加载  子类被加载

        //反射也会产生主动引用
//        Class c = Class.forName("annotationAndReflection.reflection.Son");  //父类被加载  子类被加载


        //2,类的被动引用,不会发生类的初始化
//        类的被动引用,子类引用父类的静态变量,不会发生类的初始化
//        int a = Son.a;  //父类被加载

        //类的被动引用,引用常量,不会发生类的初始化
//        System.out.println(Son.M);

        //通过数组定义类引用,不会触发此类的初始化
        Son[] sons = new Son[5];
    }
}

class Father{
    static int a = 10;

    static {
        System.out.println("父类被加载");
    }
}

class Son extends Father{
    static {
        System.out.println("子类被加载");
    }

    static int m = 100;
    static final int M = 1;
}

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-2nYETHNM-1651910301215)(F:\image\图片\学习\Screenshot_20220505-084448.jpg)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-CCoJ3JjI-1651910301215)(F:\image\图片\学习\Screenshot_20220505-084554.jpg)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-HhqUrYuW-1651910301216)(C:\Users\86177\AppData\Roaming\Typora\typora-user-images\image-20220505205544206.png)]

双亲委派机制:就是防有人替换系统级别的类String.java,因为当一个类需要加载的时候,最先尝试加载的是引导类加载器,所以其它类加载器并没有机会去加载,从一定程度上防止了危险代码的植入

package annotationAndReflection.reflection;

//获取类的加载器
public class Test06 {
    public static void main(String[] args) throws ClassNotFoundException {
        //获取系统类的加载器
        ClassLoader systemClassLoader = ClassLoader.getSystemClassLoader();
        System.out.println(systemClassLoader);//sun.misc.Launcher$AppClassLoader@18b4aac2

        //获取系统类加载器的父类加载器-->扩展类加载器
        ClassLoader parent = systemClassLoader.getParent();
        System.out.println(parent);//sun.misc.Launcher$ExtClassLoader@330bedb4

        //获取扩展类加载器的父类加载器-->根加载器(C/C++)
        ClassLoader parent1 = parent.getParent();
        System.out.println(parent1);//null

        //测试当前类是哪个类加载器加载的
        Class c = Class.forName("annotationAndReflection.reflection.Test06");
        ClassLoader classLoader = c.getClassLoader();
        System.out.println(classLoader);sun.misc.Launcher$AppClassLoader@18b4aac2

        //测试JDK内置类是哪个加载器加载的
        Class aClass = Class.forName("java.lang.Object");
        ClassLoader classLoader1 = aClass.getClassLoader();
        System.out.println(classLoader1);//null

        //获得系统类加载器可以加载的路径
        System.out.println(System.getProperty("java.class.path"));

        //双亲委派机制

        /*
        C:\Program Files\Java\jdk1.8.0_191\jre\lib\charsets.jar;
        C:\Program Files\Java\jdk1.8.0_191\jre\lib\deploy.jar;
        C:\Program Files\Java\jdk1.8.0_191\jre\lib\ext\access-bridge-64.jar;
        C:\Program Files\Java\jdk1.8.0_191\jre\lib\ext\cldrdata.jar;
        C:\Program Files\Java\jdk1.8.0_191\jre\lib\ext\dnsns.jar;
        C:\Program Files\Java\jdk1.8.0_191\jre\lib\ext\jaccess.jar;
        C:\Program Files\Java\jdk1.8.0_191\jre\lib\ext\jfxrt.jar;
        C:\Program Files\Java\jdk1.8.0_191\jre\lib\ext\localedata.jar;
        C:\Program Files\Java\jdk1.8.0_191\jre\lib\ext\nashorn.jar;
        C:\Program Files\Java\jdk1.8.0_191\jre\lib\ext\sunec.jar;
        C:\Program Files\Java\jdk1.8.0_191\jre\lib\ext\sunjce_provider.jar;
        C:\Program Files\Java\jdk1.8.0_191\jre\lib\ext\sunmscapi.jar;
        C:\Program Files\Java\jdk1.8.0_191\jre\lib\ext\sunpkcs11.jar;
        C:\Program Files\Java\jdk1.8.0_191\jre\lib\ext\zipfs.jar;
        C:\Program Files\Java\jdk1.8.0_191\jre\lib\javaws.jar;
        C:\Program Files\Java\jdk1.8.0_191\jre\lib\jce.jar;
        C:\Program Files\Java\jdk1.8.0_191\jre\lib\jfr.jar;
        C:\Program Files\Java\jdk1.8.0_191\jre\lib\jfxswt.jar;
        C:\Program Files\Java\jdk1.8.0_191\jre\lib\jsse.jar;
        C:\Program Files\Java\jdk1.8.0_191\jre\lib\management-agent.jar;
        C:\Program Files\Java\jdk1.8.0_191\jre\lib\plugin.jar;
        C:\Program Files\Java\jdk1.8.0_191\jre\lib\resources.jar;
        C:\Program Files\Java\jdk1.8.0_191\jre\lib\rt.jar;
        F:\Java\sw\out\production\JavaSE;
        F:\Java\sw\lib\kotlin-stdlib.jar;
        F:\Java\sw\lib\kotlin-reflect.jar;
        F:\Java\sw\lib\kotlin-test.jar;
        F:\Java\sw\lib\kotlin-stdlib-jdk7.jar;
        F:\Java\sw\lib\kotlin-stdlib-jdk8.jar;
        D:\软件\IDEA\IntelliJ IDEA 2021.2.3\lib\idea_rt.jar
         */
    }
}

4.创建运行时类的对象

5.获取运行时类的完整结构

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-bBrlX7IP-1651910301216)(F:\image\图片\学习\Screenshot_20220505-090001.jpg)]

package annotationAndReflection.reflection;

import java.lang.annotation.Annotation;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;

//获得类的信息
public class Test07 {
    public static void main(String[] args) throws ClassNotFoundException, NoSuchFieldException, NoSuchMethodException {
        Class c1 = Class.forName("annotationAndReflection.reflection.User");

        User user = new User();
        c1 = user.getClass();

        //获得类的名字
        System.out.println(c1.getName());   //获得包名+类名
        System.out.println(c1.getSimpleName()); //获得类名

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

        //获得类的属性,只能获得类的public属性
        Field[] fields = c1.getFields();
        for (Field field : fields) {
            System.out.println("getFields:" + field);
        }

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

        //获得类的属性,可以获得类的全部属性
        Field[] declaredFields = c1.getDeclaredFields();
        for (Field declaredField : declaredFields) {
            System.out.println("getDeclaredFields:" + declaredField);
        }

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

        //获得指定属性的值
        Field name = c1.getDeclaredField("name");
        System.out.println(name.getName());

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

        //获得类的方法,获得本类及其父类所有的public方法
        Method[] methods = c1.getMethods();
        for (Method method : methods) {
            System.out.println("getMethods:" + method);
        }

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

        //获得类的方法,获得本类所有的方法(public,protect,private)
        Method[] declaredMethods = c1.getDeclaredMethods();
        for (Method declaredMethod : declaredMethods) {
            System.out.println("getDeclaredMethods:" + declaredMethod);
        }

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

        //获得指定的方法
        //方法的重载
        Method getName = c1.getDeclaredMethod("getName", null);
        System.out.println(getName);
        Method test = c1.getDeclaredMethod("test", null);
        System.out.println(test);
        System.out.println(c1.getDeclaredMethod("setName", String.class));

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


        //获得类的构造器

//        //获得类的无参构造
//        Constructor constructor = c1.getConstructor();
//        System.out.println("getConstructor:" + constructor);

        //获得类的所有构造器(无参构造和有参构造)
        Constructor[] constructors = c1.getConstructors();
        for (Constructor constructor1 : constructors) {
            System.out.println("%%getConstructors:" + constructor1);
        }

        //获得类的所有构造器(无参构造和有参构造)
        Constructor[] declaredConstructors = c1.getDeclaredConstructors();
        for (Constructor declaredConstructor1 : declaredConstructors) {
            System.out.println("##getDeclaredConstructors:" + declaredConstructor1);
        }

        //获得指定的构造器,无参构造
        Constructor declaredConstructor = c1.getDeclaredConstructor();
        System.out.println("getDeclaredConstructor:" + declaredConstructor);

        //获得指定的构造器,有参构造
        Constructor declaredConstructor1 = c1.getDeclaredConstructor(String.class, int.class, int.class);
        System.out.println(declaredConstructor1);

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

        //获得类实现的全部接口
        Class[] interfaces = c1.getInterfaces();
        for (Class anInterface : interfaces) {
            System.out.println("getInterfaces:"+anInterface);
        }

        //获得类的注解
        Annotation[] annotations = c1.getAnnotations();
        for (Annotation annotation : annotations) {
            System.out.println("getAnnotations:"+annotation);
        }

        //获得类所继承的父类
        Class superclass = c1.getSuperclass();
        System.out.println("getSuperclass:"+superclass);
    }
}

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-h0vF1pOY-1651910301217)(F:\image\图片\学习\Screenshot_20220505-091140.jpg)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Kfy4WpVF-1651910322803)(F:\image\图片\学习\Screenshot_20220505-091207.jpg)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Gy5ozQ0s-1651910322804)(F:\image\图片\学习\Screenshot_20220505-092246.jpg)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-2gfNPb2T-1651910322805)(F:\image\图片\学习\Screenshot_20220505-092304.jpg)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-RGrdYkwh-1651910322805)(F:\image\图片\学习\Screenshot_20220505-092326.jpg)]

package annotationAndReflection.reflection;

import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

//动态的创建对象,通过反射
//通过反射操作对象的属性和方法,一般是不能直接访问private修饰的,需要关闭程序的安全检查。在使用前,利用方法或属性的对象显式调用setAccessible(true)方法,就可以访问了
public class Test08 {
    public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException, NoSuchMethodException, InvocationTargetException, NoSuchFieldException {
        //获得Class对象
        Class c1 = Class.forName("annotationAndReflection.reflection.User");

        //构造一个类的对象
//        User user = (User) c1.newInstance();    //本质是调用了类的无参构造器
//        System.out.println(user);

        //如果类没有无参构造
        //通过类的有参构造创建对象
//        Constructor declaredConstructor = c1.getDeclaredConstructor(String.class, int.class, int.class);
//        User user2 = (User) declaredConstructor.newInstance("张三",001,18);
//        System.out.println(user2);

        //通过反射调用普通方法
        //1.构造一个对象
        User user3 = (User) c1.newInstance();
        //2.通过反射获取一个方法
        Method setName = c1.getDeclaredMethod("setName", String.class);
        //3.激活方法(invoke)
        //(对象,方法参数的值)
        setName.invoke(user3, "张三");
        System.out.println(user3.getName());

        Method setId = c1.getDeclaredMethod("setId", int.class);
        setId.invoke(user3,001);
        System.out.println(user3.getId());

        Method test = c1.getDeclaredMethod("test");
        test.setAccessible(true);
        test.invoke(user3);

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

        //通过反射操作属性
        //1.构造一个对象
        User user4 = (User) c1.newInstance();

        //2.通过反射获得一个属性
        Field name = c1.getDeclaredField("name");

        //操作属性
        name.setAccessible(true);
        name.set(user4,"李四");
        System.out.println(user4.getName());

        //public修饰的属性则不需要调用setAccessible(true)方法
        Field address = c1.getDeclaredField("address");
        address.set(user4,"庆阳");
        System.out.println(user4.getAddress());

    }
}

6.调用运行时类的指定结构

分析性能问题

package annotationAndReflection.reflection;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

//分析性能问题
public class Test09 {
    public static void main(String[] args) throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
          test1();
          test2();
          test3();
    }

    //普通方式调用
    public static void test1(){
        User user = new User();

        long startTime = System.currentTimeMillis();

        for (int i = 0; i < 1000000000; i++) {
            user.getName();
        }

        long endTime = System.currentTimeMillis();

        System.out.println("普通方法执行10亿次需要:" + (endTime - startTime) + "ms");

    }

    //反射方式调用
    public static void test2() throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
        User user = new User();
        Class aClass = user.getClass();
        Method getName = aClass.getDeclaredMethod("getName");

        long startTime = System.currentTimeMillis();

        for (int i = 0; i < 1000000000; i++) {
            getName.invoke(user,null);
        }

        long endTime = System.currentTimeMillis();

        System.out.println("反射方式调用执行10亿次需要:" + (endTime - startTime) + "ms");
    }


    //关闭检测,反射方式调用
    public static void test3() throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
        User user = new User();
        Class aClass = user.getClass();
        Method getName = aClass.getDeclaredMethod("getName");
        getName.setAccessible(true);

        long startTime = System.currentTimeMillis();

        for (int i = 0; i < 1000000000; i++) {
            getName.invoke(user,null);
        }

        long endTime = System.currentTimeMillis();

        System.out.println("关闭检测,反射方式调用执行10亿次需要:" + (endTime - startTime) + "ms");
    }
}

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-blaVOy9E-1651910322805)(C:\Users\86177\AppData\Roaming\Typora\typora-user-images\image-20220506112338555.png)]

package annotationAndReflection.reflection;

import java.lang.reflect.Method;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.List;
import java.util.Map;

//通过反射操作泛型
public class Test10 {
    public static void main(String[] args) throws NoSuchMethodException {
        Class c = Test10.class;
        Method test1 = c.getDeclaredMethod("test1", Map.class, List.class);

        Type[] genericParameterTypes = test1.getGenericParameterTypes();
        for (Type genericParameterType : genericParameterTypes) {
            System.out.println("##" + genericParameterType);
            if (genericParameterType instanceof ParameterizedType){
                Type[] actualTypeArguments = ((ParameterizedType) genericParameterType).getActualTypeArguments();
                for (Type actualTypeArgument : actualTypeArguments) {
                    System.out.println(actualTypeArgument);
                }
            }
        }

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

        Method test2 = c.getDeclaredMethod("test2");
        Type[] genericParameterTypes1 = test2.getGenericParameterTypes();
        for (Type type : genericParameterTypes1) {
            System.out.println(type);
        }//该方法没有参数,所有不运行这一块

        Type genericReturnType = test2.getGenericReturnType();
        System.out.println("**:" +genericReturnType);
        if (genericReturnType instanceof ParameterizedType){
            Type[] actualTypeArguments = ((ParameterizedType) genericReturnType).getActualTypeArguments();
            for (Type actualTypeArgument : actualTypeArguments) {
                System.out.println("%%:" + actualTypeArgument);
            }
        }
    }


    //集合作为参数
    public void test1(Map<String,User> map, List<User> list){
        System.out.println("test1");
    }

    //集合作为返回值类型
    public Map<String,User> test2(){
        System.out.println("test2");
        return null;
    }
}

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-7littbzg-1651910322806)(C:\Users\86177\AppData\Roaming\Typora\typora-user-images\image-20220506112347073.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-gD2wmyg6-1651910322806)(C:\Users\86177\AppData\Roaming\Typora\typora-user-images\image-20220506112354156.png)]

package annotationAndReflection.reflection;

import java.lang.annotation.*;
import java.lang.reflect.Field;

//反射操作注解
//练习ORM     要求:利用注解和反射完成类和表结构的映射关系
public class Test11 {
    public static void main(String[] args) throws ClassNotFoundException, NoSuchFieldException {
        Class aClass = Class.forName("annotationAndReflection.reflection.Student1");

        //通过反射获得类的注解
        Annotation[] annotations = aClass.getAnnotations();
        for (Annotation annotation : annotations) {
            System.out.println(annotation);
        }

        //获得注解的Value的值
        Table table = (Table) aClass.getAnnotation(Table.class);
        String value = table.value();
        System.out.println(value);

        //获得类指定的注解
        Field id = aClass.getDeclaredField("id");
        Filed file = id.getAnnotation(Filed.class);
        System.out.println(file.columnName());
        System.out.println(file.type());
        System.out.println(file.length());
    }
}



//学生实体类,对应数据库中的学生表
@Table("db_student")
class Student1{
    @Filed(columnName = "db_id",type = "int",length = 10)
    private int id;
    @Filed(columnName = "db_name",type = "varchar",length = 3)
    private String name;
    @Filed(columnName = "db_age",type = "int",length = 10)
    private int age;

    public Student1() {
    }

    public Student1(int id, String name, int age) {
        this.id = id;
        this.name = name;
        this.age = age;
    }

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

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

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




//实体类的注解(表名)
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@interface Table{
    String value();  //该注解参数为数据库中表的名字
}

//实体类属性的注解(字段,类型,长度)
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
@interface Filed{
    String columnName();    //表的列名
    String type();    //列名的类型
    int length();   //列名的长度
}

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值