【Java】Java 常用类
Java 的常用类是 Java SE 的重要部分,这里是学习的笔记,课程选取的是 B 站 UP 主三更草堂,简单的描述了一些常用类的具体使用以及一些注意事项。
Object
Object 类的介绍
Object 类是所有的类的父类,所有的 Java 类都继承了 Object
隐式继承
1 | public class Demo01 { |
显式继承
1 | public class Demo02 extends Object { |
构造方法
序号 | 构造方法 | 描述 |
---|---|---|
1 | Object() | 构造一个新的对象 |
常用方法
序号 | 方法 | 描述 |
---|---|---|
01 | hashCode() | 获取对象的 hash 值 |
02 | getClass() | 获取对象的运行时对象的类 |
03 | toString() | 返回对象的字符串表示形式 |
04 | equals() | 比较两个对象是否相等 |
1 | Object s = new Object(); |
1 | 1078694789 |
注意
在 Object 的 equals 方法中的源码如下1
2
3public boolean equals(Object obj) {
return (this == obj);
}
可以看出在方法中比较的是对象的地址,所以无意义,通常会对方法进行重写
String
String 的介绍
在 Java 中字符串属于对象,Java 提供了 String 类来创建和操作字符串
创建字符串
1 | String s1 = "abc"; |
常用方法
序号 | 方法 | 描述 |
---|---|---|
01 | equals() | 将此字符串与指定的对象比较 |
02 | equalsIgnoreCase() | 用于将字符串与指定的对象比较,不考虑大小写 |
03 | indexOf() | 返回指定字符在字符串中第一次出现处的索引,如果此字符串中没有这样的字符,则返回 -1 |
04 | lastIndexOf() | 返回指定子字符串在此字符串中最右边出现处的索引,如果此字符串中没有这样的字符,则返回 -1 |
05 | length() | 用于返回字符串的长度,空字符串的长度返回 0 |
06 | replace() | 通过用 newChar 字符替换字符串中出现的所有 searchChar 字符,并返回替换后的新字符串 |
07 | split() | 根据匹配给定的正则表达式来拆分字符串 |
08 | substring() | 返回字符串的子字符串 |
09 | startsWith() | 检测字符串是否以指定的前缀开始 |
10 | trim() | 返回字符串的副本,忽略前导空白和尾部空白 |
11 | isEmpty() | 判断字符串是否为空 |
1 | String s1 = "abcabc"; |
包装类
包装类的介绍
Java 为每一个基本数据类型提供相对应的包装类,提供常用的方法
原始数据类型 | 包装类 |
---|---|
byte | Byte |
short | Short |
int | Integer |
long | Long |
float | Float |
double | Double |
boolean | Boolean |
char | Character |
Integer
对象创建
直接创建
1 | Integer i = 10; |
构造方法创建
1 | Integer i2 = new Integer(20); |
使用静态方法 valueOf () 创建
1 | Integer i3 = Integer.valueOf(30); |
常用方法
方法 | 返回值 | 功能描述 |
---|---|---|
byteValue() | byte | 以 byte 类型返回该 Integer 的值 |
compareTo(Integer anotherInteger) | int | 在数字上比较两个 Integer 对象。如果相同返回 0;调用对象的数值小于 anotherInteger 返回负值,反之,返回正值。 |
equals(Object IntegerObj) | boolean | 比较此对象与指定对象是否相等 |
intValue() | int | 以 int 型返回此 Integer 对象 |
shortValue() | short | 以 short 型返回此 Integer 对象 |
toString() | String | 返回一个表示该 Integer 值的 String 对象 |
valueOf(String str) | Integer | 返回指定 Sting 值的 Integer 对象 |
parseInt(String str) | int | 返回包含在由 str 指定的字符串中的数字的等价整数值 |
1 | Integer i = 1000; |
常用常量
序号 | 常量 | 描述 |
---|---|---|
1 | MAX_VALUE | 表示 int 型可取的最大值 |
2 | MIN_VALUE | 表示 int 型可取的最小值 |
3 | SIZE | 表示以 2 进制补码形式表示 int 值的位数 |
1 | //表示int型可取的最大值 |
Boolean
对象创建
1 | Boolean b = true; |
常用方法
方法 | 返回值 | 功能描述 |
---|---|---|
booleanValue() | boolean | 将 Boolean 对象的值以对应的 boolean 值返回 |
equals(Object obj) | boolean | 判断调用该方法的对象与 obj 是否相等,当且仅当参数不是 null,而且与调用该方法的对象一样都表示同一个 boolean 值的 Boolean 对象时才返回 true |
toString() | String | 返回一个表示该 boolean 值的 String 对象 |
valueOf(String str) | boolean | 返回一个用指定的字符串表示值的 boolean 值 |
parseBoolean(String str) | boolean | 将字符串参数解析为 boolean 值 |
常用常量
序号 | 常量 | 描述 |
---|---|---|
1 | TRUE | 对应基值 true 的 Boolean 对象 |
2 | FALSE | 对应基值 false 的 Boolean 对象 |
Byte
对象创建
1 | Byte b = 20; |
常用方法
方法 | 返回值 | 功能描述 |
---|---|---|
byteValue() | byte | 以一个 byte 值返回 Byte 对象 |
compareTo(Byte anotherByte) | int | 在数字上比较两个 Byte 对象 (两数相减) |
doubleValue() | double | 以一个 double 值返回 Byte 对象 |
equals(Object obj) | boolean | 比较此对象与指定对象是否相等 |
intValue() | int | 以 int 值返回此 Byte 的值 |
toString() | String | 返回一个 Byte 值的 String 对象 |
valueOf(String str) | byte | 返回指定 Sting 值的 Byte 对象 |
parseByte(String str) | byte | 返回包含在由 str 指定的字符串中的数字的等价 byte |
1 | byte b = 45; |
常用常量
1 | System.out.println(Byte.MAX_VALUE); //127 |
Character
创建对象
1 | Character c = '1'; |
常用方法
方法 | 返回值 | 功能描述 |
---|---|---|
charValue() | char | 返回此 Character 对象的值 |
compareTo(Character anotherCharacter) | int | 在数字上比较两个 Character 对象。 |
equals(Object obj) | boolean | 比较此对象与指定对象是否相等 |
toString() | String | 返回一个表示该 char 值的 String 对象 |
toUpperCase(char ch) | char | 将字符参数转为大写 |
toLowerCase(char ch) | char | 将字符参数转为小写 |
isUpperCase(char ch) | boolean | 判定指定字符参数是否为大写 |
isLowerCase(char ch) | boolean | 判定指定字符参数是否为小写 |
1 | Character c = '1'; |
Double
对象创建
1 | Double d = 10.0; |
常用方法
方法 | 返回值 | 功能描述 |
---|---|---|
byteValue() | byte | 以 byte 类型返回该 Double 对象的值(通过强制转换) |
compareTo(Double d) | int | 在数字上比较两个 Double 对象。如果相同返回 0;调用对象的数值小于 d 返回负值,反之,返回正值。 |
equals(Object obj) | boolean | 比较此对象与指定对象是否相等 |
intValue() | int | 以 int 型返回此 Double 对象 |
isNaN() | boolean | 如果此 double 是非数字,则返回 true |
toString() | String | 返回此 Double 对象值的 String 对象 |
valueOf(String str) | double | 返回指定 Sting 值的 Double 对象 |
doubleValue() | double | 以 double 形式返回此 Double 对象 |
longValue() | long | 以 long 形式返回此 Double 对象(通过强制转换) |
1 | Double d = 10.0; |
Number
常用方法
方法 | 返回值 | 功能描述 |
---|---|---|
byteValue() | byte | 以 byte 类型返回指定的数值 |
intValue() | int | 以 int 类型返回指定的数值 |
floatValue() | float | 以 float 类型返回指定的数值 |
shortValue() | short | 以 short 类型返回指定的数值 |
longValue() | long | 以 long 类型返回指定的数值 |
doubleValue() | double | 以 double 类型返回指定的数值 |
1 | Number n = 1000; |
自动装箱
占时跳过,实现 valueOf () 方法,具体看源码
StringBuffer 和 StringBuilder
区别
String 是不可变的字符串,每对 String 进行次变更操作都会创建一个新的对象。
StringBuilder 是可变字符序列,线程不安全,但效率高。
StringBuffer 是可变字符序列,具有线程安全的特性,相对于 StringBuilder 来说效率较低。
对象创建
1 | StringBuffer buffer = new StringBuffer(); |
String 对字符串的操作
1 | long startTime = System.currentTimeMillis(); |
String 对字符串的操作确实效率太低了,只是做了十万次的拼接,就耗费了 3.75s 的时间
StringBuilder 对字符串的操作
1 | long startTime = System.currentTimeMillis(); |
可以看出,StringBuilder 的性能有多优异,做了一亿次的字符串拼接,只花费了 0.469s 的时间,可以这么讲,相对于 String 的性能来说根本不是一个维度的。
StringBuffer 对字符串的操作
1 | long startTime = System.currentTimeMillis(); |
在前面说到 StringBuffer 的线程是安全的,但性能相对于 StringBuilder 来说是有所下降的,在一亿次的字符拼接拼接中,StringBuffer 花费了 1.68s,确实是有很大的差距。
常用方法
方法 | 返回类型 | 功能描述 |
---|---|---|
append() | StringBuilder | 将指定的字符串追加到此字符序列。 |
insert() | StringBuilder | 将字符串插入此字符序列. |
reverse() | StringBuilder | 导致此字符序列被序列的反向替换 |
setCharAt(int index, char ch) | void | 指定索引处的字符设置为 ch |
1 | StringBuffer buffer = new StringBuffer("Hello World"); |
集合框架
常用 list 集合
List 接口下的集合特点:
- 有索引
- 可以存储重复元素
- 元素的顺序和实际存储的顺序相同
ArrayList
创建对象
1 | ArrayList list = new ArrayList<>(); |
常用方法
add()
ArrayList 类提供了很多有用的方法,添加元素到 ArrayList 可以使用 add () 方法1
2
3
4
5
6
7ArrayList<String> games = new ArrayList<String>();
games.add("Counter-Strike: Global Offensive");
games.add("Dota 2");
games.add("PUBG: BATTLEGROUNDS");
games.add("Apex Legends");
games.add("Grand Theft Auto V");
System.out.println(games); //[Counter-Strike: Global Offensive, Dota 2, PUBG: BATTLEGROUNDS, Apex Legends, Grand Theft Auto V]
get()
访问 ArrayList 中的元素可以使用 get () 方法1
2
3
4
5
6
7ArrayList<String> games = new ArrayList<String>();
games.add("Counter-Strike: Global Offensive");
games.add("Dota 2");
games.add("PUBG: BATTLEGROUNDS");
games.add("Apex Legends");
games.add("Grand Theft Auto V");
System.out.println(games.get(4)); //Grand Theft Auto V
set()
如果要修改 ArrayList 中的元素可以使用 set () 方法1
2
3
4
5
6
7
8ArrayList<String> games = new ArrayList<String>();
games.add("Counter-Strike: Global Offensive");
games.add("Dota 2");
games.add("PUBG: BATTLEGROUNDS");
games.add("Apex Legends");
games.add("Grand Theft Auto V");
games.set(0,"CS:GO");//修改下标为0的游戏名称为CS:GO
System.out.println(games); //[CS:GO, Dota 2, PUBG: BATTLEGROUNDS, Apex Legends, Grand Theft Auto V]
remove()
如果要删除 ArrayList 中的元素可以使用 remove () 方法1
2
3
4
5
6
7
8ArrayList<String> games = new ArrayList<String>();
games.add("Counter-Strike: Global Offensive");
games.add("Dota 2");
games.add("PUBG: BATTLEGROUNDS");
games.add("Apex Legends");
games.add("Grand Theft Auto V");
games.remove(2);
System.out.println(games); //[Counter-Strike: Global Offensive, Dota 2, Apex Legends, Grand Theft Auto V]
size()
如果要计算 ArrayList 中的元素数量可以使用 size () 方法1
2
3
4
5
6
7ArrayList<String> games = new ArrayList<String>();
games.add("Counter-Strike: Global Offensive");
games.add("Dota 2");
games.add("PUBG: BATTLEGROUNDS");
games.add("Apex Legends");
games.add("Grand Theft Auto V");
System.out.println(games.size()); //5
ArrayList 遍历
for
1 | ArrayList<String> games = new ArrayList<String>(); |
for-each
1 | ArrayList<String> games = new ArrayList<String>(); |
迭代器 iterator ()
hasNext (),如果迭代有更多元素,则返回 true1
2
3
4
5
6
7
8
9
10ArrayList<String> games = new ArrayList<String>();
games.add("Counter-Strike: Global Offensive");
games.add("Dota 2");
games.add("PUBG: BATTLEGROUNDS");
games.add("Apex Legends");
games.add("Grand Theft Auto V");
Iterator<String> iterator = games.iterator();
while (iterator.hasNext()){
System.out.println(iterator.next());
}
并发修改异常
1 | // 在遍历过程中遇到PUBG时将其从ArrayList中移除 |
以上代码看似可以从 ArrayList 中移除指定的元素,但实际运行时会产生一个并发修改异常的错误,所以需要对相应的代码进行修改
为什么会产生并发修改异常
首先查看一下错误的信息1
2
3
4
5
6
7Counter-Strike: Global Offensive
Dota 2
PUBG: BATTLEGROUNDS
Exception in thread "main" java.util.ConcurrentModificationException
at java.base/java.util.ArrayList$Itr.checkForComodification(ArrayList.java:1013)
at java.base/java.util.ArrayList$Itr.next(ArrayList.java:967)
at com.sangeng.commonClass._03.ArrayListDemo04.main(ArrayListDemo04.java:19)
根据错误信息,可以发现错误发生在 ArrayList.java 的第 1013 行,所以去查看一下源代码1
2
3
4final void checkForComodification() {
if (modCount != expectedModCount)
throw new ConcurrentModificationException();
}
可以看到,在 modCount 和 expectedModCount 不相等时会抛出一个异常
那么,导致这两个不相等的情况,就很可能是在对 ArrayList 进行修改时发生的,查看 remove () 的源码1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19public boolean remove(Object o) {
final Object[] es = elementData;
final int size = this.size;
int i = 0;
found: {
if (o == null) {
for (; i < size; i++)
if (es[i] == null)
break found;
} else {
for (; i < size; i++)
if (o.equals(es[i]))
break found;
}
return false;
}
fastRemove(es, i);
return true;
}
通过查看源码,发现这里并没有对这两个的值进行修改啊,那么是不是调用的方法对这两个值进行修改了呢?
在查看 fastRemove () 时,发现这个方法果然对数据进行了修改1
2
3
4
5
6
7private void fastRemove(Object[] es, int i) {
modCount++;
final int newSize;
if ((newSize = size - 1) > i)
System.arraycopy(es, i + 1, es, i, newSize - i);
es[size = newSize] = null;
}
于是乎,我们来查看一下这个 modCount 到底是什么?
在查看源代码后,大致意思是它表示的是列表结构被修改的次数
在查看 Iterator 接口的实现类时发现1
int expectedModCount = modCount;
这里看到在对 expectedModCount 进行初始化是用的是 modCount 的值,当接下来 modCount 发生改变后再与 expectedModCount 进行比较就是不相等的,这时便会发生异常
解决思路一
1 | // 在遍历过程中遇到PUBG时将其从ArrayList中移除 |
解决思路二
1 | // 在遍历过程中遇到PUBG时将其从ArrayList中移除 |
foreach 产生并发修改的思考
1 | for(String game: games){ |
在使用 foreach 时发现这段代码居然也会产生并发修改异常,而且错误信息和之前完全一样,所以大胆的猜测使用 foreach 遍历 ArrayList 时,使用的依旧是 iterator 来实现的,通过 Debug 发现,果然是调用的 iterator,在 Iterator 接口的实现类的 next () 方法执行时,调用了 checkForComodification (),而由于上一次已经对 games 进行了修改,所以在 checkForComodification () 里进行判断时,modCount 不等于 expectedModCount 条件成立。
toArray()
以正确的顺序(从第一个到最后一个元素)返回一个包含此列表中所有元素的数组1
2
3
4
5
6
7
8
9
10ArrayList<String> games = new ArrayList<>();
games.add("Counter-Strike: Global Offensive");
games.add("Dota 2");
games.add("PUBG: BATTLEGROUNDS");
games.add("Apex Legends");
games.add("Grand Theft Auto V");
Object[] array = games.toArray();
for (int i = 0; i < array.length; i++) {
System.out.println(array[i]);
}
LinkedList(链表)
创建对象
1 | LinkedList linkedList = new LinkedList(); |
常用方法
方法 | 返回类型 | 描述 |
---|---|---|
add(E e) | Boolean | 链表末尾添加元素,返回是否成功,成功为 true,失败为 false。 |
add(int index, E element) | void | 向指定位置插入元素。 |
addFirst(E e) | void | 元素添加到头部。 |
addLast(E e) | void | 元素添加到尾部。 |
get(int index) | E | 返回指定位置的元素。 |
getFirst() | E | 返回第一个元素。 |
getLast() | E | 返回最后一个元素。 |
set(int index, E element) | E | 设置指定位置的元素。 |
removeFirst() | E | 删除并返回第一个元素。 |
removeLast() | E | 删除并返回最后一个元素。 |
remove(int index) | E | 删除指定位置的元素。 |
clear() | void | 清空链表。 |
contains(Object o) | boolean | 判断是否含有某一元素。 |
1 | LinkedList linkedList = new LinkedList(); |
遍历的三种方法
1 | LinkedList linkedList = new LinkedList(); |
ArrayList 和 LinkedList 的区别
都是实现了 List 接口,但底层存储数据的数据结构不同,ArrayList 底层是用数组来存储的,而 Linked 用的则是链表,所以各自的特点跟各自的数据结构特点一样。
ArrayList:查找快,增删慢
LinkedList:增删快,查找慢
常用 set 集合
set 集合的特点
不能存储重复数据
没有索引
HashSet
HashSet 的特点
- 底层数据结构是哈希表
- 存储元素的顺序和遍历的顺序可能是不一样的
- 没有索引
- 集合不能存储重复元素
- 基于 HashMap 来实现
- 允许 null 值
- 线程是不安全的,多线程操作可能结果有问题
- 实现了 Set 接口
创建对象
1 | HashSet hashSet = new HashSet(); |
常用方法
方法 | 返回类型 | 描述 |
---|---|---|
add(E e) | boolean | 添加元素,返回是否成功,成功为 true,失败为 false。 |
contains(E e) | boolean | 判断元素是否存在于集合当中 |
remove(E e) | boolean | 删除集合中的元素 |
1 | HashSet<String> strings = new HashSet<>(); |
遍历
与 list 集合类似,由于没有索引,索引不能通过索引来查询,但都是有迭代器 iterator 的1
2
3
4
5
6
7
8
9
10
11
12
13
14
15HashSet<String> strings = new HashSet<>();
strings.add("Counter-Strike: Global Offensive");
strings.add("Dota 2");
strings.add("PUBG: BATTLEGROUNDS");
strings.add("Lost Ark");
strings.add("Apex Legends");
System.out.println("------方法一-------");
for (String s: strings){
System.out.println(s);
}
System.out.println("------方法二-------");
Iterator<String> stringIterator = strings.iterator();
while (stringIterator.hasNext()){
System.out.println(stringIterator.next());
}
虽然看着是两种方法,其实都是通过 iterator 迭代器来实现的。
泛型
泛型类和泛型接口
泛型类和泛型接口都一样
泛型类就是泛型定义在类上,在使用该类时,才会把类型定义下来
泛型的定义
在类名猴子加 <>,在 <> 中的内容相当于泛型的名字
java 中泛型标记符:
- E - Element (在集合中使用,因为集合中存放的是元素)
- T - Type(Java 类)
- K - Key(键)
- V - Value(值)
- N - Number(数值类型)
- ? - 表示不确定的 java 类型
1 | public class Test<T>{ |
使用泛型
1 | public class Box<E> { |
在类中定义了泛型类,此时类型是没有确定的,只有在使用时才能确定1
2
3
4Box<String> stringBox = new Box<>();
stringBox.add("Java");
Box<Integer> integerBox = new Box<>();
integerBox.add(1);
泛型的确定并不是只有在使用时才确定,还有定义子类时可以确定1
2public class DoubleBox extends Box<Double>{
}
Double 类继承了 Box 类,并且指定了类型为 Double1
2DoubleBox doubleBox = new DoubleBox();
doubleBox.add(10.0);
泛型接口
首先定义一个泛型接口1
2
3public interface Test<T> {
T test(T t);
}
第二步是在接口实现类确定具体的类型1
2
3
4
5
6public class TestImpl implements Test<String>{
public String test(String s) {
return s;
}
}1
2Test<String> stringTest = new TestImpl();
String java = stringTest.test("Java");
泛型方法
每次调用方法的时候确定类型
泛型方法的定义
1 | public static <T> T test(T t){ |
泛型方法的使用
1 | public static void main(String[] args) { |
泛型上限与泛型下限
在特特定的情况下,需要对泛型做一定的限制,所以有了泛型的上限和泛型下限
格式1
<? extends 具体的类型>
举例
首先创建一个类1
2
3
4public class Person {
private String name;
private int age;
}
再创建一个类继承 Person 类1
2
3public class Student extends Person{
}1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 ArrayList<Person> people = new ArrayList<>();
ArrayList<Student> students = new ArrayList<>();
people.add(new Person());
students.add(new Student());
test(people);
test(students);
test2(people);
test2(students);
}
public static void test(List<? extends Person> list){
System.out.println(list.toString());
}
public static void test2(List<? super Student> list){
System.out.println(list.toString());
}
在测试方法 test 中,对 List 的泛型做了限制,test 的参数类型 List 的元素只能是 Person 或者继承 Person 的对象,所以在 list.add (1) 出会发生错误,因为不符合 test () 的泛型,而 people 和 students 都符合,所以这里的代码不会出现异常,这就是泛型上限。
在 test2 () 中,对泛型做了限制,List 的元素只能是 Student 或者 Student 的父类,people 和 students 分别是 Person 对象和 Student 对象,所以符合 test2 () 的条件,这就是泛型下限。
Map
Map 集合的概述
Map 接口是双列集合的顶层接口
Map 接口的定义如下1
public interface Map<K, V>
Map 的特征有如下
- 存储数据必须包含 key 和 value
- key 和 value 在 Map 集合中一一对应
- key 在 Map 中不会重复
HashMap
HashMap 的特征如下
- 底层数据结构是哈希表
- 存储元素的顺序和遍历取出来的顺序不一定一样
- key 不可重复
HashMap 的创建
1 | Map<String,String> stringMap = new HashMap<>(); |
HashMap 的常用方法
方法 | 返回类型 | 描述 |
---|---|---|
put(key,value) | value | 添加键值对 (key-value),如果 key 不存在则添加,如果 key 存在,则更新,添加时返回 null,更新时返回修改的值 |
get(key) | value | 通过 key 获取 value |
remove(key) | value | 删除 Map 中的元素,返回被删除的内容 |
containsKey(key) | boolean | 判断 key 是否存在 |
size() | int | 返回 Map 中的键和值的对数 |
clear() | void | 清空 Map 中的元素 |
1 | Map<String,String> stringMap = new HashMap<>(); |
HashMap 的遍历
第一种方法是通过 entrySet 方法获取一个 Set 集合,集合中存放这 Entry 对象,通过对象可以获取到里面的键值对。1
2
3
4
5
6
7
8
9
10HashMap<Integer,String> gameMap = new HashMap<>();
gameMap.put(1,"CSGO");
gameMap.put(2,"Dota 2");
gameMap.put(3,"PUBG");
gameMap.put(4,"Apex");
gameMap.put(5,"Lost Ark");
Set<Map.Entry<Integer, String>> entries = gameMap.entrySet();
for (Map.Entry<Integer, String> entry : entries) {
System.out.println(entry.getKey()+":"+entry.getValue());
}
第二中方法是 keySet 方法,返回一个 Set 集合,返回的是 Map 中 key 的值。1
2
3
4
5
6
7
8
9
10HashMap<Integer,String> gameMap = new HashMap<>();
gameMap.put(1,"CSGO");
gameMap.put(2,"Dota 2");
gameMap.put(3,"PUBG");
gameMap.put(4,"Apex");
gameMap.put(5,"Lost Ark");
Set<Integer> integers = gameMap.keySet();
for (Integer key : integers) {
System.out.println(key+":"+gameMap.get(key));
}
File
Java 文件类以抽象的方式代表文件名和目录路径名。该类主要用于文件和目录的创建、文件的查找和文件的删除等。
File 对象代表磁盘中实际存在的文件和目录。通过以下构造方法创建一个 File 对象。
通过给定的父抽象路径名和子路径名字符串创建一个新的 File 实例。
创建对象
1 | File file = new File("C:\\Users\\haiba\\Desktop\\Java\\IO\\file.txt"); |
通过全路径和父子路径来创建 File 对象
常用方法
方法 | 返回类型 | 描述 |
---|---|---|
createNewFile() | boolean | 创建文件,成功返回 TRUE,创建失败返回 false |
mkdir() | boolean | 创建文件夹,只能创建一级目录 |
mkdirs() | boolean | 创建多级文件夹 |
exists() | boolean | 判断是否存在 |
isFile() | boolean | 判断是否是文件 |
isDirectory() | boolean | 判断是否是文件夹 |
delete() | boolean | 删除文件或者文件夹,删除文件夹是文件夹必须为空 |
length() | long | 返回文件的大小,对于文件夹无意义 |
getName() | String | 获取文件名 |
getParentFile() | File | 获取父级目录对象 |
getAbsoluteFile() | File | 获取绝对路径 |
1 | File file = new File("C:\\Users\\haiba\\Desktop\\Java\\IO\\test.txt"); |
重要方法
1 | File file = new File("C:\\Users\\haiba\\Desktop\\Java\\IO"); |
通过 listFiles () 方法获取当前目录下的所有文件和文件夹对象,但对于当前对象是文件时无意义,返回 null
练习
获取扩展名
1 | private static String getExtensionName(File file){ |
获取当前目录的大小
1 | private static long getSize(File file){ |
递归计算文件夹下所有文件的大小
递归
什么是递归
序调用自身的编程技巧称为递归(recursion),它做为一种算法在程序设计语言中广泛应用。
递归练习 —— 阶乘
阶乘是基斯顿・卡曼于 1808 年发明的运算符号,是数学术语。
一个正整数的阶乘(factorial)是所有小于及等于该数的正整数的积,并且 0 的阶乘为 1。自然数 n 的阶乘写作 n!。1808 年,基斯顿・卡曼引进这个表示法。
亦即 n!=1×2×3×…×(n-1)×n。阶乘亦可以递归方式定义:0!=1,n!=(n-1)!×n。
既然已经知道了条件,那么用 Java 代码要怎么去表现呢?1
2
3
4
5
6
7
8
9public static void main(String[] args) {
System.out.println(getFactorial(5));
}
public static long getFactorial(int f){
if (f==1){
return 1;
}
return f * getFactorial(f-1);
}
递归练习 —— 斐波那契数列
什么是斐波那契数列?
斐波那契数列(Fibonacci sequence),又称黄金分割数列,因数学家莱昂纳多・斐波那契(Leonardo Fibonacci)以兔子繁殖为例子而引入,故又称为 “兔子数列”,指的是这样一个数列:1、1、2、3、5、8、13、21、34、…… 在数学上,斐波那契数列以如下被以递推的方法定义:F(0)=0,F(1)=1, F(n)=F(n - 1)+F(n - 2)(n ≥ 2,n ∈ N*)在现代物理、准晶体结构、化学等领域,斐波纳契数列都有直接的应用,为此,美国数学会从 1963 年起出版了以《斐波纳契数列季刊》为名的一份数学杂志,用于专门刊载这方面的研究成果。
既然已知递归方法定义,那么 Java 的代码实现怎么去完成呢?1
2
3
4
5
6
7
8public static void main(String[] args) {
System.out.println(fibonacciSequence(20));
}
private static long fibonacciSequence(int f){
if (f == 0) return 0;
if (f == 1) return 1;
return fibonacciSequence(f - 1) + fibonacciSequence(f - 2);
}