java常用的类
- 输入类Scanner
- String 类 和StringBuffer类
- String类
- 注意一下equals()和==的区别
- StringBuffer类
- System类
- Math类
- random类
- 包装类:
- 日期与时间类
- 集合
- ArrayList 集合
- LinkedList 集合
- Collection 集合遍历
- lterator 遍历集合
- foreach 遍历集合
- set接口
- HashSet集合
- TreeSet集合
- Map接口
- HashMap 集合
- LinkedHashMap
- TreeMap集合
- 泛型(限制存入类型)
- 常用工具类
- Collections工具类:
- 添加,排序操作
- 查找,替换操作
- Arrays工具类
- 排序,查找,拷贝,所有元素替换成一个元素
- 聚合操作
- I/O流
- 字节流的读取文件,拷贝文件
- 字符流
- 字节流的转换
- File类
- 遍历当前目录下所有文件名:
- 删除
输入类Scanner
String 类 和StringBuffer类
- 1.前面要调用的库
import java.util.Scanner;
- 2.public 下面还要加
Scanner in = new Scanner(System.in)
调用这个class - 3.
int a= in.nextInt();
这个是输入int 类型的; -
int b = in.nextDouble()
;这个是输入Double类型; -
String s =in.nextLine()
这个是输入字符串 - …类似的可以推导
String类
Sring类的初始化
1.使用字符串常量初始化String 变量名=字符串
String name = "thm";
String str=null;
2.使用一个String 的构造方法初始化字符串对象String 变量名=new String("字符串")
;
Sring 的构造方法有很多种:
方法 | 功能介绍 |
String() | 创建一个内容为空的字符串 |
String(String value) | 根据指定的字符串内容创建对象 |
String(char[]) | 根据指定的字符数组创造对象 |
举一个例子:
public class Example {
public static void main(String[] args) {
// 创建一个空的字符串
String str1 = new String();
// 创建一个内容为abc的字符串
String str2 = new String("abc");
// 创建一个内容为字符数组的字符串
char[] charArray = new char[] { 'A', 'B', 'C' };
String str3 = new String(charArray);
// 输出结果
System.out.println("a" + str1 + "b");
System.out.println(str2);
System.out.println(str3);
}
}
输出结果:
ab
abc
ABC
String类的常见操作
方法的声明 | 功能的描述 |
int indexOf(int ch) | 返回指定字符串在此字符中出现第一次出现的索引 |
int lastIndexOf | 返回指定字符在这个字符串中最后一次出现处的索引 |
int indexOf(String str) | 返回指定子字符串在此字符串中第一次出现的索引 |
int lastIndexOf(String str) | 返回指定子字符串最后一次出现的索引 |
char charAt(int index) | 返回指定索引上的字符 |
boolean endsWith(String str) | 判断此字符串是否以指定字符串结尾 |
int length() | 返回字符串长度 |
boolean equals(Object anObject) | 比较字符串 |
boolean isEmpty() | 判断此字符串是否为空 |
boolean startsWith(String str) | 判断此字符串是否是指定字符开始 |
boolean contains(CharSequence cs) | 判断此字符串是否包含指定的字符串序列 |
String toLowerCase(String str) | 把字符串中的所有字符变成小写 |
String toUpperCase(String str) | 把字符串中的所有字符变成大写 |
static String valueOf(int i) | 返回int 参数的字符串表示形式 |
char[] toCharArray() | 将此字符串转换为一个字符数组 |
String replace (CharSequeence older,CharSequeence newser) | newser 替换了older |
String [] split(String str) | 根据str 进行分隔,行成多个字符串 |
String substring(int beginIndex) | 返回一个新的字符串,他包含指定的benginIndex起始角标开始,直到此字符串末尾的所有字符.(就是从这个下表进行切片) |
String substring (int beginIndex,intendIndex) | 切片,是beginIndex到intendIndex |
String trim() | 返回一个新的字符串,它去除了原字符串的首位空格 |
import java.util.Locale;
public class Example {
public static void main(String[] args) {
String str1 = new String("qwertyqer");
String str2 =new String("qwertyqer");
//返回指定字符串在此字符中出现第一次出现的索引
System.out.println(str1.indexOf("q"));
//返回指定字符在这个字符串中最后一次出现处的索引
System.out.println(str1.lastIndexOf("q"));
//返回指定子字符串在此字符串中第一次出现的索引
System.out.println(str1.lastIndexOf("er"));
//返回指定子字符串最后一次出现的索引
System.out.println(str1.lastIndexOf("er"));
//返回指定索引上的字符
System.out.println(str1.charAt(2));
//判断此字符串是否以指定字符串结尾
System.out.println(str1.endsWith("r"));
//返回字符串长度
System.out.println(str1.length());
//比较字符串
System.out.println(str1.equals(str2));
//判断字符串是否为空
System.out.println(str1.isEmpty());
//判断此字符串包含指定的字符串序列
System.out.println(str1.contains("qwer"));
//把字符串中的所有字符变成大写
System.out.println(str1.toUpperCase(Locale.forLanguageTag(str1)));
//返回int 参数的字符串表示形式
System.out.println(str1.valueOf(1));
//将此字符串转换为一个字符数组
System.out.println(str1.toCharArray());
//替换字符串
System.out.println(str1.replace("qwer","1234"));
//根据str 进行分隔,行成多个字符串
System.out.println(str1.split(""));
}
}
输出结果:
0
6
7
7
e
true
9
true
false
true
QWERTYQER
1
qwertyqer
1234tyqer
[Ljava.lang.String;@16b98e56
需要注意:需要赋值之后才能够改变原来的值!
注意一下equals()和==的区别
public class Example {
public static void main(String[] args) {
String str1 = new String("qwertyqer");
String str2 = new String("qwertyqer");
System.out.println(str1 == str2);
System.out.println(str1.equals(new StringBuilder("qwertyqer")));
System.out.println(str1.equals(str2));
}
}
输出:
false
true
原因:
String 里的 equals() 是比较两个字符串中的字符值是否相同,StringBuffer 里的equals和==方法用于比价两个字符串对象的内存地址是否相同
StringBuffer类
因为String类是final 类型,所以使用它的时候不能对它进行增删减插
,而StringBuffer 可以进行,它类似一个字符的容器,在其中增删减插
不会创造一个新的对象.
StringBuilder 也是一个可以修改的字符串对象,和StringBuffer 差不多
其中的一系列操作
方法声明 | 功能描述 |
StringBuffer append(char c) | 添加字符到StringBuffer对象中末尾 |
StringBuffer insert(int offset ,String str) | 在StringBuffer对象中的offser中插入字符串str |
StringBuffer deleteCharAt(int index) | 安装index 的下标删除元素 |
StringBuffer delete(int start, int end) | 删除 start 到end 下标中的字符 |
StringBuffer replace(int start ,int end,String s) | 将start到end下标字符串代替成s字符串 |
void setCharAt(int index,char ch) | 修改指定位置index处的字符 |
String toString() | 返回StringBuffer 缓冲区中得知字符串对象 |
StringBuffer reverse() | 将字符串反转 |
public class Example {
public static void main(String[] args) {
StringBuffer str=new StringBuffer("asdasd");
str.append("123");//加末尾加字符串
System.out.println("加末尾加字符串:"+str);
str.insert(0,0);// 在0的下标下面插入0
System.out.println("在0的下标下面插入0:"+str);
str.delete(0,1);//删除第一个字符
System.out.println("删除第一个字符:"+str);
str.replace(0,2,"*");//替换索引0到2字符
System.out.println("替换索引0到2字符:"+str);
str.setCharAt(0, '#');//替换索引为1的地方的字符
System.out.println("替换索引为1的地方的字符:"+str);
str.reverse();//反转
System.out.println("反转:"+str);
str.toString();
System.out.println("toString:"+str);
}
}
输出结果:
加末尾加字符串:asdasd123
在0的下标下面插入0:0asdasd123
删除第一个字符:asdasd123
替换索引0到2字符:*dasd123
替换索引为1的地方的字符:#dasd123
反转:321dsad#
toString:321dsad#
System类
system 的属性和方法都是静态的.
方法声明 | 功能描述 |
static void exit (int status) | 改方法用于终止当前正在运行的java虚拟机,其中参数status表示状态码,若状态码非0,则表示异常终止 |
static void gc() | 运行垃圾回收器 |
static native long currentTimeMillis() | 返回毫秒为单位的当前时间(可以用来记代码运行时间) |
static void arraycopy(Object src ,int srcPos,Object dest,int destPos,int length) | 从str引用的指定原数组拷贝到dest引用的数组,拷贝从指定的位置开始,到目标数组的指定位置结束 |
static Preperties getProperties() | 获取当前系统的属性 |
static String getProperty(String key) | 获取指定键当前的系统属性 |
查看运行时间:
class Example {
public static void main(String[] args) {
long startTime = System.currentTimeMillis();// 循环开始时的当前时间
int sum = 0;
for (int i = 0; i < 100000000; i++) {
sum += i;
}
long endTime = System.currentTimeMillis();// 循环结束后的当前时间
System.out.println("程序运行时间为:"+(endTime - startTime)+ "毫秒");
}
}
运行结果:
程序运行时间为:53毫秒
拷贝数组:
arrycopy的参数有点复杂详细说明一下:
arraycopy(Object src ,int srcPos,Object dest,int destPos,int length)
①src :表示原数组
②dest:表示目标数组
③srcPos:表示原数组中拷贝元素的起始坐标
④destPos:表示拷贝到目标数组的起始位置.
⑤length:表示拷贝元素的个数
class Example1 {
public static void main(String[] args) {
int[] srcArray = { 101, 102, 103, 104, 105, 106 }; // 源数组
int[] destArray = { 201, 202, 203, 204, 205}; // 目标数组
System.arraycopy(srcArray, 2, destArray, 0, 4); // 拷贝数组元素
// 打印目标数组中的元素
for (int i = 0; i < destArray.length; i++) {
System.out.println(i + ": " + destArray[i]);
}
}
}
输出结果:
0: 103
1: 104
2: 105
3: 106
4: 205
原理:就是在第一个数组指定开始下标开始拷贝到指定数组的指定下标,最后一个参数是长度.
Math类
有下列这些方法:
class Example {
public static void main(String[] args) {
System.out.println("计算绝对值的结果: " + Math.abs(-1));
System.out.println("计算正弦的结果: " + Math.sin(1.57));
System.out.println("计算余弦的结果: " + Math.cos(2.0));
System.out.println("计算正切的结果: " + Math.tan(0.8));
System.out.println("计算平方根的结果: " + Math.sqrt(4));
System.out.println("计算立方根的结果: " + Math.cbrt(9));
System.out.println("计算乘方的结果: " + Math.pow(2,2));
System.out.println("求大于参数的最小整数: " + Math.ceil(4.6));
System.out.println("求小于参数的最大整数: " + Math.floor(-5.2));
System.out.println("对小数进行四舍五入后的结果: " + Math.round(-8.6));
System.out.println("求两个数的较大值: " + Math.max(5.1, 5.5));
System.out.println("求两个数的较小值: " + Math.min(5.1, 5.5));
System.out.println("生成一个大于等于0小于1的随机值: "+ Math.random());
}
}
random类
import java.util.Random;
class Example {
public static void main(String[] args) {
Random r = new Random();
System.out.println("生成boolean类型的随机数:"
+ r.nextBoolean());
System.out.println("生成double类型的随机数:"
+ r.nextDouble());
System.out.println("生成float类型的随机数:"
+ r.nextFloat());
System.out.println("生成int类型的随机数:"
+ r.nextInt());
System.out.println("生成0到10之间int类型的随机数:"
+ r.nextInt(10));
System.out.println("生成long类型的随机数:"+ r.nextLong());
}
}
输出结果:
生成boolean类型的随机数:true
生成double类型的随机数:0.4709797155543384
生成float类型的随机数:0.16692293
生成int类型的随机数:1527669305
生成0到10之间int类型的随机数:1
生成long类型的随机数:7014985944587952261
包装类:
java 是面向对象的编程语言,但是它所包含的8种基本数据类型却不支持面向对象的编程机制.所以需要包装类的数据类型,方便对数据的处理.
基本数据类型 | 对应包裹类 |
byte | Byte |
char | Character |
int | Integer |
short | Short |
long | Long |
float | Float |
double | Double |
boolean | Boolean |
记忆帮助:除了Integer 和Character 这个两个外其他的都是把第一个字母大写了而已
装箱,和拆箱过程:
基本类型和包裹类型的相互转换:
public class Example {
public static void main(String args[]) {
// 定义一个基本类型的变量a,并赋值为20
int a = 20;
// 自动装箱:将基本类型的变量a赋给Integer类型的变量b
Integer b = a;
System.out.println(b);
// 自动拆箱:将Integer类型的变量b赋给基本类型的变量a
int c = b;
System.out.println(c);
}
}
输出:
20
20
String类型
------转化
-------包装类型
(character除外):基本类型
------转化
------包裹类型
(character除外):
Integer i=Integer.valueOf("123");
Integer ii=Integer.valueOf(123);
Double a=Double.valueOf("13.4");
Double aa=Double.valueOf(13.4);
Float f=Float.valueOf("12.4");
通过包装类的有参构造方法将基本类型
和字符串
转化为包装类
Integer integer3 = new Integer(num);
Integer integer4 = new Integer(str);
System.out.println("通过构造器将int变量转换为包装类的结果:"+integer3);
System.out.println("通过构造器将字符串变量转换为包装类的结果:"+integer4);
①除了character外,包装类都有valueOf(String s)的方法,可以根据String类型的参数创建包装类对象,但参数字符串不能是null,而且字符串必须是可以解析相应基本类型的数据,否则虽然编译能通过,但是运行会报错
Integer i=Integer.valueOf("123");//合法
Integer a=Integer.valueOf("23a");//不合法
②除了Character外,包装类都有parseXXX(String s)的静态方法,将字符串
转化为对应的基本数据类型
的数据,参数s不能为null,而且同样必须是可以解析为相应基本类型的数据,否则虽然编译通过,但是运行会报错字符串
----转化
-----相应的数据类型
int i=Integer.parseInt("123");//合法
Integer in =Integer.parseInt("4aa4");//不合法
一个例子:
public class Example {
public static void main(String args[]) {
int num = 123;
// 1、通过String.valueOf()方法将基本类型转换为字符串
String string = String.valueOf(num);
System.out.println("将int变量转换为字符串的结果:"+string);
// 2、通过包装类的valueOf()静态方法将基本类型和字符串转换为包装类
String str = "998";
Integer integer = Integer.valueOf(num);
Integer integer2 = Integer.valueOf(str);
System.out.println("将int变量转换为包装类的结果:"+integer);
System.out.println("将字符串变量转换为包装类的结果:"+integer2);
// 3、通过包装类的有参构造方法将基本类型和字符串转换为包装类
Integer integer3 = new Integer(num);
Integer integer4 = new Integer(str);
System.out.println("通过构造器将int变量转换为包装类的结果:"
+integer3);
System.out.println("通过构造器将字符串变量转换为包装类的结果:"
+integer4);
// 4、通过包装类的parseXxx()静态方法将字符串转换为基本数据类型
int parseInt = Integer.parseInt(str);
System.out.println("将字符串转换为基本类型的结果:"+parseInt);
// 5、通过包装类的toString()方法将包装类转换为字符串
String string2 = integer.toString();
System.out.println("将包装类转换为字符串的结果:"+string2);
}
}
日期与时间类
Calendar类
Calendar是一个抽象类,是不可以被实例化的。在程序中需要调用静态方法getInstance()来得到一个Calendar对象才能够调用相应的方法
调用相应的库: import java.util.*;
Calendar calendar =Calendar.getInstabce();
Calendar 类的常用方法:
方法声明 | 功能描述 |
int get(int field) | 返回指定日历字段的值 |
void add(int field,int amount) | 根据日历规则,指定的日历字段增加或减去指定的时间量 |
viod set(int year,int mouth ,int date) | 设置Claendar对象的年,月,日三个字段的值 |
void set(int field ,int value) | 为指定日历字段设置指定值 |
void set (int year ,iny mouth,int date,int hourOfDay ,iny minute ,int second) | 设置Claendar 对象的年月,日,时,分,秒. |
import java.util.*;
public class Example {
public static void main(String[] args) {
// 获取表示当前时间的Calendar对象
Calendar calendar = Calendar.getInstance();
int year = calendar.get(Calendar.YEAR); // 获取当前年份
int month = calendar.get(Calendar.MONTH) + 1; // 获取当前月份
int date = calendar.get(Calendar.DATE); // 获取当前日
int hour = calendar.get(Calendar.HOUR); // 获取时
int minute = calendar.get(Calendar.MINUTE); // 获取分
int second = calendar.get(Calendar.SECOND); // 获取秒
System.out.println("当前时间为:" + year + "年 " + month + "月 "
+ date + "日 "+ hour + "时 " + minute + "分 " + second + "秒");
}
}
输出结果:
当前时间为:2021年 6月 15日 8时 31分 16秒
import java.util.*;
public class Example {
public static void main(String[] args) {
// 获取表示当前时间的Calendar对象
Calendar calendar = Calendar.getInstance();
// 设置指定日期
calendar.set(2018, 1, 1);
// 为指定日期增加时间
calendar.add(Calendar.DATE, 100);
// 返回指定日期的年
int year = calendar.get(Calendar.YEAR);
// 返回指定日期的月
int month = calendar.get(Calendar.MONTH) + 1;
// 返回指定日期的日
int date = calendar.get(Calendar.DATE);
System.out.println("计划竣工日期为:" + year + "年"
+ month + "月" + date + "日");
}
}
输出结果:
计划竣工日期为:2018年5月12日
集合
Collection 是所有单列集合的跟接口,因此在Collection中定义了单列集合的一些通用的方法
基本方法:
方法声明 | 功能描述 |
boolean add(Object o) | 向集合中添加一个元素 |
boolean addAll(Collection c) | 讲集合C所有元素添加到这个集合 |
void clear() | 删除该集合中的所有元素 |
boolean remove(Object o) | 删除指定的元素 |
boolean removeAll(Collection c) | 删除指定集合里面所有有的元素 |
boolean isEmpty() | 判断改集合是否为空 |
boolean contains(Object o) | 判断是否有包含某个元素 |
boolean containsAll(Collection C) | 判断该集合中是否包含指定集合C中所有元素 |
Iterator iteraror() | 返回该集合的元素上进行迭代的迭代器(Iterator),用于遍历 |
int size() | 获取该集合元素的个数 |
Streamstream() | 讲集合转换为有序的流对象 |
List 接口
List 接口继承自Collection接口
List 集合常用方法
方法的声明 | 功能描述 |
void add(int index ,Object elemnt) | 将元素element插入在List集合的指定索引位置 |
boolean addAall(int index ,Collection c) | 将集合c包含所有元素插入到List集合的指定索引位置 |
Object get(int index) | 获取集合索引index 处的元素 |
Object remove(int index) | 删除index索引处的元素 |
Object set(int index ,Object element) | 将索引index处元素替换成element元素,并将替换后的元素返回 |
int indexOf(Object o) | 返回对象o在List集合中首次出现的索引 |
int lastIndexOf( Object o ) | 返回对象o在List集合中最后一次出现的位置索引 |
List subList(int fromIndex,int toIndex) | 返回fromIndex到 toIndex这个两个索引进行切片 |
Object[ ] toArray() | 将集合元素转换为数组 |
default voidsort(comparator(Comparator<?super E>c)) | 根据指定的比较器规则对集合元素排序 |
ArrayList 集合
ArryList 是List接口的一个实现类,它是一个长度可以改变的数组对象.ArryList是内部的数据存储结构是数组形式,在增加或删除的时候会建立新的数组,所以效率比较低.但是ArrayList在便利和查找的时候就比较高效了.
需要调用的包:import java.util.ArrayList;
package com.itheima;
import java.util.ArrayList;
public class Example {
public static void main(String[] args) {
ArrayList list = new ArrayList(); // 创建ArrayList集合
list.add("stu1"); // 向集合中添加元素
list.add("stu2");
list.add("stu3");
list.add("stu4");
System.out.println("集合的长度:" + list.size()); // 获取集合中元素的个数
System.out.println("第2个元素是:" + list.get(1)); // 取出并打印指定位置的元素
}
}
输出结果:
集合的长度:4
第2个元素是:stu2
LinkedList 集合
调用包import java.util.LinkedList;
LinkedList包含两个Node类型的frist和last属性维护一个双向链表,这样他的删除和增加效率就比较高了
LinkedList 中的特有的方法
方法声明 | 功能描述 |
void add(int index,E elemnt) | 在此列表中指定位置插入指定的元素 |
void addFirst(Object o) | 将指定元素插入集合的开头 |
void addLast (Object o) | 将指定的元素放在集合的尾部 |
Object getFirs() | 返回集合的第一个元素 |
Object getLast() | 返回集合的最后一个元素 |
Object removeFirst() | 移除并返回第一个元素 |
Object removeLast() | 移除并返回最后一个元素 |
boolean offer(Object o) | 将指定元素添加到集合尾部 |
boolean offerFirst() | 将指定的元素加到表头 |
boolean offerLast() | 将指定的元素加到尾部 |
Object peek() | 获取集合的第一个元素 |
Object peekFirst() | 获取集合的第一个元素 |
Object peekLast() | 获取集合的最后第一个元素 |
Object poll() | 移除并返回元素的第一个元素 |
Object poolFisrt() | 移除并返回元素的第一个元素 |
Object pollLast() | 移除并返回元素的最后一个元素 |
void push(Object) | 将指定的元素添加到集合的开头 |
Object pop() | 移除并返回集合的第一个元素 |
package com.itheima;
import java.util.LinkedList;
public class Example {
public static void main(String[] args) {
LinkedList link = new LinkedList(); // 创建LinkedList集合
// 1、添加元素
link.add("stu1");
link.add("stu2");
System.out.println(link); // 输出集合中的元素
link.offer("offer"); // 向集合尾部追加元素
link.push("push"); // 向集合头部添加元素
System.out.println(link); // 输出集合中的元素
// 2、获取元素
Object object = link.peek();//获取集合第一个元素
System.out.println(object); // 输出集合中的元素
// 3、删除元素
link.removeFirst(); // 删除集合第一个元素
link.pollLast(); // 删除集合最后一个元素
System.out.println(link);
}
}
输出结果:
[stu1, stu2]
[push, stu1, stu2, offer]
push
[stu1, stu2]
Collection 集合遍历
lterator 遍历集合
这个是一个迭代器,可以修改数组,但是不能用remove(),原因是集合中删除了元素会导致迭代器预期的迭代次数发生改变.
调用包import java.util.Iterator;
package com.itheima;
import java.util.ArrayList;
import java.util.Iterator;
public class Example {
public static void main(String[] args) {
// 创建ArrayList集合
ArrayList list = new ArrayList();
// 向该集合中添加字符串
list.add("data_1");
list.add("data_2");
list.add("data_3");
// 获取Iterator对象
Iterator iterator = list.iterator();
// 判断集合中是否存在下一个元素
while (iterator.hasNext()) {
Object obj = iterator.next(); // 取出ArrayList集合中的元素
System.out.println(obj);
}
}
}
输出结果:
data_1
data_2
data_3
如果使用要删除数组里面的值,但是不能用remove(),原因是集合中删除了元素会导致迭代器预期的迭代次数发生改变
.下面就用了remove()
package com.itheima;
import java.util.ArrayList;
import java.util.Iterator;
public class Example {
public static void main(String[] args) {
ArrayList list = new ArrayList(); //创建ArrayList集合
list.add("Jack");
list.add("Annie");
list.add("Rose");
list.add("Tom");
Iterator it = list.iterator(); // 获得Iterator对象
while (it.hasNext()) { // 判断该集合是否有下一个元素
Object obj = it.next(); // 获取该集合中的元素
if ("Annie".equals(obj)) { // 判断该集合中的元素是否为Annie
list.remove(obj); // 删除该集合中的元素,这里会报错
// it.remove(); 如果使用这个方式就不会报错
}
}
System.out.println(list);
}
}
输出结果:
报错!!!!!!!
如果用的是it.remove() 就不会报错,这个原理是用了删除迭代器本身,所以不会报错.
如果要用list.remove(obj); 就必须和break;一起使用才不会报错
lambda的迭代器循环
package com.itheima;
import java.util.ArrayList;
import java.util.Iterator;
public class Example {
public static void main(String[] args) {
ArrayList list = new ArrayList();
list.add("data_1");
list.add("data_2");
list.add("data_3");
System.out.println(list);
// 将集合转换为Iterator迭代器对象
Iterator it = list.iterator();
// 使用JDK 8新增的forEachRemaining(Consumer action)来遍历迭代器对象
it.forEachRemaining(obj -> System.out.println("迭代集合元素:"+obj));
}
}
输出结果:
[data_1, data_2, data_3]
迭代集合元素:data_1
迭代集合元素:data_2
迭代集合元素:data_3
foreach 遍历集合
使用它的时候,只能访问集合中的元素,不能对其中的元素进行修改.
package com.itheima;
import java.util.ArrayList;
public class Example {
public static void main(String[] args) {
ArrayList list = new ArrayList(); // 创建ArrayList集合
list.add("data_1"); // 向ArrayList集合中添加字符串元素
list.add("data_2");
list.add("data_3");
for (Object obj : list) { // 使用foreach循环遍历ArrayList对象
System.out.println(obj); // 取出并打印ArrayList集合中的元素
}
}
}
输出结果:
data_1
data_2
data_3
用lambda函数用foreach循环
package com.itheima;
import java.util.ArrayList;
public class Example {
public static void main(String[] args) {
ArrayList list = new ArrayList();
list.add("data_1");
list.add("data_2");
list.add("data_3");
System.out.println(list);
// 使用JDK 8新增的forEach(Consumer action)方法遍历集合
list.forEach(obj -> System.out.println("迭代集合元素:"+obj));
}
}
输出结果:
[data_1, data_2, data_3]
迭代集合元素:data_1
迭代集合元素:data_2
迭代集合元素:data_3
set接口
继承于Collection接口,set接口中的元素无序,并且都会以某种规则保证存入元素不出现重复.相应的方法和collection当中的方法一样也没有新的方法
HashSet集合
需要调用的包:import java.util.HashSet;
创建一个set:HashSet set = new HashSet();
package com.itheima;
import java.util.HashSet;
public class Example {
public static void main(String[] args) {
HashSet set = new HashSet(); // 创建HashSet集合
set.add("Jack"); // 向该Set集合中添加元素
set.add("Eve");
set.add("Rose");
set.add("Rose"); // 向该Set集合中添加重复元素,但是他不会加入进去
// 遍历输出Set集合中的元素
set.forEach(o -> System.out.println(o));
}
}
输出结果:
Eve
Rose
Jack
为了保证HashSet的正常工作,需要存入对象的时候,需要重写Object中的hashCode()和equals()方法
现在用一个例子来说明:
package com.itheima;
import java.util.HashSet;
class Student {
String id;
String name;
public Student(String id,String name) { // 创建构造方法
this.id=id;
this.name = name;
}
public String toString() { // 重写toString()方法
return id+":"+name;
}
// 重写hashCode方法
public int hashCode() {
return id.hashCode(); // 返回id属性的哈希值
}
// 重写equals方法
public boolean equals(Object obj) {
if (this == obj) { // 判断是否是同一个对象
return true; // 如果是,直接返回true
}
if (!(obj instanceof Student)) { // 判断对象是为Student类型
return false; // 如果对象不是Student类型,返回false
}
Student stu = (Student) obj; // 将对象强转为Student类型
boolean b = this.id.equals(stu.id);// 判断id值是否相同
return b; // 返回判断结果
}
}
public class Example {
public static void main(String[] args) {
HashSet hs = new HashSet(); // 创建HashSet集合
Student stu1 = new Student("1", "Jack"); // 创建Student对象
Student stu2 = new Student("2", "Rose");
Student stu3 = new Student("2", "Rose");
hs.add(stu1);
hs.add(stu2);
hs.add(stu3);
System.out.println(hs);
}
}
输出结果:
[1:Jack, 2:Rose]
TreeSet集合
…待续
Map接口
一意对应的的接口,就想python里的字典,它是一个双列集合,每个元素都包括键对象Key和值对象Value
Map集合中常用的方法
方法声明 | 功能描述 |
void put(Object key ,Object value) | 向Map集合中添加指定键值映射的元素 |
int size() | 返回Map集合键值对映射的个数 |
Object get(Objet key) | 返回指定键值所映射的值,如果此映射不包含改键的映射关系,则返回null |
boolean containsKey(Object key) | 查看Map集合中是否存在指定的键对象key |
boolean containsValue(Object value) | 查看Map集合中是否存在指定的键对象value |
Object reove(Object key) | 删除并返回Map集合中指定键对象Key的键值映射元素 |
void clear() | 清空整个Map集合中的键值映射元素 |
Set keySet() | 以Set集合的形式返回Map中国所有的键对象key |
Collection values() | 以Collection 集合的形式返回Map集合中所有的值对象Value |
Set<Map.Entry<key,value>>entrySet() | 将Map集合转换为存储元素类型为Map的Set集合 |
Object getOrDefault(Object key ,Object deaflt Value) | 返回Map集合指定键所映射的值,如何不存在则返回默认的defaultValue |
void forEach(BiConsumer action) | 通过传入一个函数接口对Map集合元素进行遍历 |
Object putIfAbsent(Object key ,Object value) | 向集合中添加指定键值映射的元素,如果集合一存在该键值映射元素,则不在添加而是返回已经存在的值对象Value |
boolean remove(Object key ,Object value) | 删除Map集合中国键值映射同时匹配元素 |
boolean repalce(Object key ,Object value) | 将Map集合中指定键对象Key所映射的值修改为value |
HashMap 集合
HashMap集合是Map类的一个实现类.
用案例来学校HashMap:
import java.util.HashMap;
import java.util.Map;
public class Example {
public static void main(String[] args) {
// 创建HashMap对象
Map map = new HashMap();
// 1、向Map存储键值对元素
map.put("1", "Jack");
map.put("2", "Rose");
map.put("3", "Lucy");
map.put("4", "Lucy");
map.put("1", "Tom");
System.out.println(map);
// 2、查看键对象是否存在
System.out.println(map.containsKey("1"));
// 3、获取指定键对象映射的值
System.out.println(map.get("1"));
// 4、获取集合中的键对象和值对象集合
System.out.println(map.keySet());
System.out.println(map.values());
// 5、替换指定键对象映射的值
map.replace("1", "Tom2");
System.out.println(map);
// 6、删除指定键对象映射的键值对元素
map.remove("1");
System.out.println(map);
}
}
输出结果:
{1=Tom, 2=Rose, 3=Lucy, 4=Lucy}
true
Tom
[1, 2, 3, 4]
[Tom, Rose, Lucy, Lucy]
{1=Tom2, 2=Rose, 3=Lucy, 4=Lucy}
{2=Rose, 3=Lucy, 4=Lucy}
Map集合遍历
1.使用Iterator迭代器遍历Map集合,需要先将Map集合转化为Iterator接口对象.
2.使用Foreach循环加lambda表达式的方式遍历
package com.itheima;
import java.util.*;
public class Example {
public static void main(String[] args) {
Map map = new HashMap(); // 创建Map集合
map.put("1", "Jack"); // 存储元素
map.put("2", "Rose");
map.put("3", "Lucy");
System.out.println(map);
// 1、使用keySet()方法
Set keySet = map.keySet(); // 获取键的集合
Iterator it = keySet.iterator(); // 迭代键的集合
while (it.hasNext()) {
Object key = it.next();
Object value = map.get(key); // 获取每个键所对应的值
System.out.println(key + ":" + value);
}
// 2、使用entrySet()方法
System.out.println("使用entrySet()方法进行遍历:");
Set entrySet = map.entrySet();
Iterator it2 = entrySet.iterator(); // 获取Iterator对象
while (it2.hasNext()) {
// 获取集合中键值对映射关系
Map.Entry entry = (Map.Entry) (it2.next());
Object key = entry.getKey(); // 获取Entry中的键
Object value = entry.getValue(); // 获取Entry中的值
System.out.println(key + ":" + value);
}
// 3. 使用foreach循环
System.out.println("使用foreach循环:");
map.forEach((key,value) -> System.out.println(key + ":" + value));
//4. 使用Collection集合
System.out.println("使用collection集合对象进行遍历:");
Collection values = map.values(); // 获取Map集合中value值集合对象
// 遍历Map集合所有值对象V
values.forEach(v -> System.out.println(v));
}
}
输出结果:
{1=Jack, 2=Rose, 3=Lucy}
1:Jack
2:Rose
3:Lucy
使用entrySet()方法进行遍历:
1:Jack
2:Rose
3:Lucy
使用foreach循环:
1:Jack
2:Rose
3:Lucy
使用Collection集合对象进行遍历:
Jack
Rose
Lucy
LinkedHashMap
如果需要有顺序的集合需要使用 LinkedHashMap集合
就一个例子:
package com.itheima;
import java.util.*;
public class Example {
public static void main(String[] args) {
Map map1 = new HashMap(); // 创建HashMap集合
map1.put(2, "Rose");
map1.put(1, "Jack");
map1.put(3, "Lucy");
map1.forEach((key,value) -> System.out.println(key + ":" + value));
System.out.println("=====================");
Map map2 = new LinkedHashMap(); // 创建LinkedHashMap集合
map2.put(2, "Rose");
map2.put(1, "Jack");
map2.put(3, "Lucy");
map2.forEach((key,value) -> System.out.println(key + ":" + value));
}
}
输出结果:
1:Jack
2:Rose
3:Lucy
=====================
2:Rose
1:Jack
3:Lucy
TreeMap集合
待续…
泛型(限制存入类型)
接下来就建立了一个String列表的泛型,限制了它的类型,
package com.itheima;
import java.util.ArrayList;
public class Example {
public static void main(String[] args) {
ArrayList<String> list = new ArrayList<String>();// 创建ArrayList集合,使用泛型,只能传入String类型
list.add("String"); // 添加字符串对象
list.add("Collection");
for (String str : list) { // 遍历集合,可以直接指定元素类型
System.out.println(str);
}
}
}
常用工具类
Collections工具类:
添加,排序操作
import java.util.ArrayList;
import java.util.Collections;
public class Example {
public static void main(String[] args) {
ArrayList<String> list = new ArrayList<>();
Collections.addAll(list, "C","Z","B","K"); // 添加元素
System.out.println("排序前: " + list); // 输出排序前的集合
Collections.reverse(list); // 反转集合
System.out.println("反转后: " + list);
Collections.sort(list); // 按自然顺序排列
System.out.println("按自然顺序排序后: " + list);
Collections.shuffle(list); // 随机打乱集合元素
System.out.println("按随机顺序排序后: " + list);
Collections.swap(list, 0, list.size()-1); // 将集合首尾元素交换
System.out.println("集合首尾元素交换后: " + list);
}
}
输出结果:
排序前: [C, Z, B, K]
反转后: [K, B, Z, C]
按自然顺序排序后: [B, C, K, Z]
按随机顺序排序后: [C, Z, B, K]
集合首尾元素交换后: [K, Z, B, C]
查找,替换操作
import java.util.ArrayList;
import java.util.Collections;
public class Example {
public static void main(String[] args) {
ArrayList<Integer> list = new ArrayList<>();
Collections.addAll(list, -3,2,9,5,8); // 向集合中添加所有指定元素
System.out.println("集合中的元素: " + list);
System.out.println("集合中的最大元素: " + Collections.max(list));
System.out.println("集合中的最小元素: " + Collections.min(list));
Collections.replaceAll(list, 8, 0); // 将集合中的8用0替换掉
System.out.println("替换后的集合: " + list);
Collections.sort(list); //使用二分查找前,必须保证元素有序
System.out.println("集合排序后为: "+list);
int index = Collections.binarySearch(list, 9);
System.out.println("集合通过二分查找方法查找元素9所在角标为:"+index);
}
}
输出结果:
集合中的元素: [-3, 2, 9, 5, 8]
集合中的最大元素: 9
集合中的最小元素: -3
替换后的集合: [-3, 2, 9, 5, 0]
集合排序后为: [-3, 0, 2, 5, 9]
集合通过二分查找方法查找元素9所在角标为:4
Arrays工具类
排序,查找,拷贝,所有元素替换成一个元素
import java.util.Arrays;
public class Example {
public static void main(String[] args) {
int[] arr = { 9, 8, 3, 5, 2 };
int index = Arrays.binarySearch(arr, 3);
System.out.println("没排序前,元素3的索引是:" + index);
Arrays.sort(arr); // 调用排序方法,对数组排序
int index1 = Arrays.binarySearch(arr, 3); // 查找指定元素3
System.out.println("排序后,元素3的索引是:" + index1); // 输出打印元素所在的索引位置
//拷贝方法:
int[] copied = Arrays.copyOfRange(arr, 1, 7);// 拷贝 1索引到 7索引
for (int i = 0; i < copied.length; i++) {
System.out.print(copied[i] + " ");
}
System.out.println("只拷贝到1到它最后的索引,没有的用0来代替");
//所有元素的替换
Arrays.fill(arr, 8); // 用8替换数组中的每一个值
System.out.print("用8替换所有元素之后:");
for (int i = 0; i < arr.length; i++) {
System.out.print(arr[i]);
}
}
}
输出结果:
没排序前,元素3的索引是:2
排序后,元素3的索引是:1
3 5 8 9 0 0 只拷贝到1到它最后的索引,没有的用0来代替
用8替换所有元素之后:88888
聚合操作
…
I/O流
简单的说就是输入输出
1.字节流和字符流
字节流:以字节的单位进行数据的读写,一次读一个或多个字节数据(图片,文字,视频)
字符流:以字符为单位进行数据的读写,每次读一个或多个字符字节(文字)
2.输入流和输出流
输入流:只能在流中读取数据,不能写入数据
输出流:只能写入数据,不能读出数据
3.节点流和处理流
节点流:读写数据的流(低级流)
处理流:对节点的流进行连接和封装,在已经存在的流上进行封装(高级流)
字节流的读取文件,拷贝文件
首先提一点,一般在做这些的时候都会先抛出在去解决问题.
一般在后面都会加有一个finally的模块
finally{
try{
if(in!=null)
in.close();
}catch(Exception e){
e.printStakTrace();
}
try{
if(out!=null)
in.close();
}catch(Exception e){
e.printStakTrace();
}
}
读入文件,test.txt 文件里放入的 是 hello
import java.io.*;
public class Example {
public static void main(String[] args) throws Exception {
// 创建一个文件字节输入流来读取文件
FileInputStream in = new FileInputStream("test.txt");
// 定义一个int类型的变量b
int b = 0;
// 通过循环来读取文件,当返回值为-1结束循环
while((b=in.read()) != -1){
System.out.println(b);
}
// 关闭流
in.close();
}
}输出结果:
104
101
108
108
111
对结果进行分析:因为是字符h,e,l,l,o,各占一个字节,是以字节形式存在的,读出来的是对应的ASCII码
写文件:
package com.itheima;
import java.io.*;
public class Example {
public static void main(String[] args) throws Exception {
// 创建文件输出流对象,并指定输出文件名称
FileOutputStream out = new FileOutputStream("out.txt");
// 定义一个字符串
String str = "hello";
// 将字符串转换为字节数组进行写入操作
out.write(str.getBytes());
// 关闭流
out.close();
}
}
输出结果:
在out.tet 文件里面出现了hello,这里是"覆盖写"不是,续写如果想要"续写"的话
需要改一个地方:
FileOutputStream out = new FileOutputStream("out.txt",true);
文件的拷贝:
比较慢的拷贝方式,一个一个的运输,
接下来的例子都是拷贝一个source/src.jpg
下的图片到target/dest.jpg
import java.io.*;
public class Example {
public static void main(String[] args) throws Exception {
// 创建文件输入流对象读取指定目录下的文件
FileInputStream in = new FileInputStream("source/src.jpg");
// 创建文件输出流对象将读取到的文件内容写入到指定目录的文件中
FileOutputStream out = new FileOutputStream("target/dest.jpg");
// 定义一个int类型的变量len
int len = 0;
// 获取拷贝文件前的系统时间
long beginTime = System.currentTimeMillis();
// 通过循环将读取到的文件字节信息写入到新文件
while ((len = in.read()) != -1) {
out.write(len);
}
// 获取拷贝之后的系统时间
long endTime = System.currentTimeMillis();
// 输出拷贝花费时间
System.out.println("花费时间为:"+(endTime-beginTime) +"毫秒");
// 关闭流
in.close();
out.close();
}
}
输出结果:
花费时间为:2669毫秒
用字节流的缓冲区来加快拷贝速度:
import java.io.*;
public class Example {
public static void main(String[] args) throws Exception {
// 创建文件输入流对象读取指定目录下的文件
FileInputStream in = new FileInputStream("source/src.jpg");
// 创建文件输出流对象将读取到的文件内容写入到指定目录的文件中
FileOutputStream out = new FileOutputStream("target/dest.jpg");
// 定义一个int类型的变量len
int len = 0;
// 定义一个长度为1024的字节数组
byte[] buff = new byte[1024];
// 获取拷贝文件前的系统时间
long beginTime = System.currentTimeMillis();
// 通过循环将读取到的文件字节信息写入到新文件
while ((len = in.read(buff)) != -1) {
// 每循环读取一次字节数组,就将所读取到的内容写入到文件
out.write(buff,0,len);
}
// 获取拷贝之后的系统时间
long endTime = System.currentTimeMillis();
// 输出拷贝花费时间
System.out.println("花费时间为:"+(endTime-beginTime) +"毫秒");
// 关闭流
in.close();
out.close();
}
}
输出结果:
花费时间为:6毫秒
使用字节缓冲流
import java.io.*;
public class Example {
public static void main(String[] args) throws Exception {
// 创建用于输入和输出的字节缓冲流对象
BufferedInputStream bis = new BufferedInputStream(
new FileInputStream("source/src.jpg"));
BufferedOutputStream bos = new BufferedOutputStream(
new FileOutputStream("target/dest.jpg"));
// 定义一个int类型的变量len
int len = 0;
// 获取拷贝文件前的系统时间
long beginTime = System.currentTimeMillis();
// 通过循环读取输入字节缓冲流中的数据,并通过输出字节缓冲流写入到新文件
while ((len=bis.read()) != -1) {
bos.write(len);
}
// 获取拷贝之后的系统时间
long endTime = System.currentTimeMillis();
// 输出拷贝花费时间
System.out.println("花费时间为:"+(endTime-beginTime) +"毫秒");
// 关闭流
bis.close();
bos.close();
}
}
输出结果:
花费时间为:16毫秒
字符流
接下来以字符流的方式,来操作文件.
在reader.txt文件里面读出"java,是一门好的编程语言!"
在writer.txt文件里面写入一些文字
import java.io.*;
public class Example {
public static void main(String[] args) throws Exception {
// 创建FileReader对象,并指定需要读取的文件
FileReader fileReader = new FileReader("reader.txt");
// 定义一个int类型的变量len,其初始化值为0
int len = 0;
// 通过循环来判断是否读取到了文件末尾
while ((len = fileReader.read()) != -1) {
// 输出读取到的字符
System.out.print((char)len);
}
// 创建字符输出流对象,并指定输出文件,输入文件
FileWriter fileWriter = new FileWriter("writer.txt");
// 将定义的字符写入文件
fileWriter.write("轻轻的我走了,\r\n");
fileWriter.write("正如我轻轻的来;\r\n");
fileWriter.write("我轻轻的招手,\r\n");
fileWriter.write("作别西天的云彩。\r\n");
fileWriter.close();
// 关闭流
fileReader.close();
}
}
输出结果:
java,是一门好的编程语言!
在write文件也写入了东西,输出了文件.
用字符流的缓冲区拷贝文件
import java.io.*;
public class Example {
public static void main(String[] args) throws Exception {
// 创建FileReader对象,并指定需要读取的文件
FileReader fileReader = new FileReader("reader.txt");
// 创建FileWriter对象,并指定写入数据的目标文件
FileWriter fileWriter = new FileWriter("writer.txt");
// 定义一个int类型的变量len,其初始化值为0
int len = 0;
// 定义一个长度为1024的字符数组
char[] buff = new char[1024];
// 通过循环来判断是否读取到了文件末尾
while ((len = fileReader.read(buff)) != -1) {
// 输出读取到的字符
fileWriter.write(buff, 0, len);
}
// 关闭流
fileReader.close();
fileWriter.close();
}
}
字符缓冲流
import java.io.*;
public class Example {
public static void main(String[] args) throws Exception {
// 创建一个字符输入缓冲流对象
BufferedReader br = new BufferedReader(
new FileReader("reader.txt "));
// 创建一个字符输出缓冲流对象
BufferedWriter bw = new BufferedWriter(
new FileWriter("writer.txt"));
// 声明一个字符串变量str
String str =null;
// 循环时每次读取一行文本,如果不为null(即到了文件末尾),则继续循环
while ((str = br.readLine()) != null) {
// 通过缓冲流对象写入文件
bw.write(str);
// 写入一个换行符,该方法会根据不同的操作系统生成相应的换行符
bw.newLine();
}
// 关闭流
br.close();
bw.close();
}
}
字节流的转换
字节流转换为字符流只能针对操作文本的字节流进行操作,如果字节流操作的是字节码内容的文件(入图片,视频等),此时转换为字符流就会造成数据丢失.
接下来对一个字节流
转化为字符流
import java.io.*;
public class Example {
public static void main(String[] args) throws Exception {
// 1、创建字节输入流对象,获取源文件
FileInputStream in = new FileInputStream("reader.txt");
// 将字节输入流对象转换成字符输入流对象
InputStreamReader isr = new InputStreamReader(in);
// 创建字符输入缓冲流对象
BufferedReader br = new BufferedReader(isr);
// 2、创建字节输出流对象,指定目标文件
FileOutputStream out = new FileOutputStream("writer.txt");
// 将字节输出流对象转换成字符输出流对象
OutputStreamWriter osw = new OutputStreamWriter(out);
// 创建字符输出缓冲流对象
BufferedWriter bw = new BufferedWriter(osw);
// 定义一个字符串变量
String line = null;
// 通过循环判断是否读到文件末尾
while ((line = br.readLine()) != null) {
// 输出读取到的文件
bw.write(line);
bw.newLine();
}
// 关闭流
br.close();
bw.close();
}
}
File类
创建文件
,删除
,重命名
建立一个 test.txt文件
public class Example {
public static void main(String[] args) {
// 创建File文件对象
File file = new File("test.txt");
// 获取文件名称
System.out.println("文件名称:" + file.getName());
// 获取文件的相对路径
System.out.println("文件的相对路径:" + file.getPath());
// 获取文件的绝对路径
System.out.println("文件的绝对路径:" + file.getAbsolutePath());
// 获取文件的父路径
System.out.println("文件的父路径:" + file.getParent());
// 判断文件是否可读
System.out.println(file.canRead() ? "文件可读" : "文件不可读");
// 判断文件是否可写
System.out.println(file.canWrite() ? "文件可写": "文件不可写");
// 判断是否是一个文件
System.out.println(file.isFile() ? "是一个文件" :"不是一个文件");
// 判断是否是一个目录
System.out.println(file.isDirectory()? "是一个目录":"不是一个目录");
// 判断是否是一个绝对路径
System.out.println(file.isAbsolute() ? "是绝对路径": "不是绝对路径");
// 得到文件最后修改时间
System.out.println("最后修改时间为:" + file.lastModified());
// 得到文件的大小
System.out.println("文件大小为:" + file.length() + " bytes");
// 是否成功删除文件
System.out.println("是否成功删除文件"+file.delete());
}
}
输出结果:
文件名称:test.txt
文件的相对路径:test.txt
文件的绝对路径:D:\学习资料\java\源代码\《Java基础入门》第二版源代码_0816\chapter07\test.txt
文件的父路径:null
文件可读
文件可写
是一个文件
不是一个目录
不是绝对路径
最后修改时间为:1624181063834
文件大小为:5 bytes
是否成功删除文件true
遍历当前目录下所有文件名:
import java.io.File;
import java.util.Arrays;
public class Example {
public static void main(String[] args) {
// 创建File对象,并指定文件路径
File file = new File("D:\\学习资料\\java");
// 判断是否是目录
if (file.isDirectory()) {
// 获取目录中的所有文件的名称
String[] fileNames = file.list();
// 对指定路径下的文件或目录进行遍历
Arrays.stream(fileNames)
.forEach(f -> System.out.println(f));
}
}
}
输出结果:
.classpath
.idea
.project
.settings
bin
chapter07.iml
test.txt
time.txt
writer.txt
选出所有的txt后缀名的文件:
名字
import java.io.*;
import java.util.Arrays;
public class Example {
public static void main(String[] args){
// 创建File对象,并指定文件路径
File file = new File("D:\\学习资料\\英语");
// 判断是否是目录
if (file.isDirectory()) {
// 使用Lambda表达式过滤目录中所有以.txt结尾的文件的名称
String[] fileNames = file.list(
(dir,name) -> name.endsWith(".txt"));
// 对指定路径下的文件或目录进行遍历
Arrays.stream(fileNames)
.forEach(f -> System.out.println(f));
}
}
}
输出:
单词.txt
英语四级.txt
完整的路径
import java.io.*;
public class Example{
public static void main(String[] args){
// 创建File对象,并指定文件路径
File file = new File("D:\\学习资料\\英语");
// 调用fileDir()方法,遍历目录
fileDir(file);
}
// 遍历目录及其子目录
public static void fileDir(File file) {
// 获得目录下所有文件,并赋给数组
File[] listFiles = file.listFiles();
// 循环遍历数组
for (File files : listFiles) {
// 如果遍历的是目录,则递归调用fileDir()方法
if(files.isDirectory()){
fileDir(files);
}
// 输出文件路径
System.out.println(files);
}
}
}
输出结果:
D:\学习资料\英语\单词.txt
D:\学习资料\英语\英语四级.txt