常用类
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集合的概述:
- 是单列集合的顶层接口,它表示一组对象,这些对象也成为Collection的元素
- JDK不提供此接口的任何直接实现,它提供更具体的子接口(如List和Set)实现
- 创建Collection集合的对象:
- 多态的方式
- 具体的实现类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集合的概述:
- 有序集合(也称为序列),用户可以精确控制列表中的每个元素的插入位置。用户可以通过整数索引访问元素,并搜索列表中的元素
- 与Set集合不同,列表通常允许重复的元素
- List集合的特点:
- 有序:存储和取出的元素顺序一致
- 可重复:存储的元素可以重复
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集合的特点
- 不包含重复元素的集合
- 没有带索引的方法,所以不能用普通的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(); //列名的长度
}