文章目录
Java SE进阶知识总结-2
常用的基本Java类
类名 | 用途 |
---|---|
Objects | 所有的类都直接或间接继承该类(祖宗类),其内的方法都可用 |
Math | 包含基本的数字运算方法 |
System | 都是静态方法,可以直接调用 |
BigDecimal | 用于解决小数运算中,出现的不精确问题 |
用到再学,常用常新
包装类
什么是包装类?
- 将基本数据类型及一些辅助方法包装成为类,转为引用数据类型,就可以方便操作
基本数据类型对应的包装类
基本数据类型 | 对应的包装类 |
---|---|
byte | Byte |
short | Short |
int | Integer |
long | Long |
char | Character |
float | Float |
double | Double |
boolean | Boolean |
除了int、char的包装类之外,其余基本数据类型的包装类都是首字母大写
包装类的自动拆箱和自动装箱问题
JDK5之前需要手动拆箱和装箱,不然无法进行运算
// 手动装箱操作
int i=500;
Integer t = new Integer(i);
// 手动拆箱操作
int i = t.intValue()
JDK5之后,有自动拆、装箱操作:基本数据类型和对应的包装类可以直接相互赋值运算,不用担心转换问题
// 自动装箱
Integer I = 5;
//自动拆箱
int i = I;
包装类的一个常见问题
public static void main(String[] args) {
Integer i1 = 127; // .class字节码里面:Integer i1 = Integer.valueOf(127);
Integer i2 = 127;
System.out.println(i1 == i2); // true
Integer i3 = 129;
Integer i4 = 129;
System.out.println(i3 == i4); // false
Long i11 = 129L;
Long i22 = 129L;
System.out.println(i11 == i22); // false
System.out.println(i11.equals(i22)); // true
}
自动装箱的本质是调用底层装箱方法(通过javap反编译看一下.class源码,可以知道是调用了valueOf
方法):
-
数值范围在-128-127,给定指定数组,不会创建新的对象,所以上述比较结果是true
-
不在上述数值范围内,就会创建新的对象,所以后续比较结果是false
时间类
时间类总共分为两大部分:jdk8以前的时间类和jdk8以后的时间类,主要特点如下:
JDK8以前的时间类 | JDK8以后的时间类 |
---|---|
设计欠妥,使用不方便,已淘汰 | 设计合理,功能丰富,使用方便 |
都是可变对象,修改后会丢失原有数据 | 都是不可变对象,修改后返回新的时间对象 |
线程不安全 | 线程安全 |
只能精确到毫秒 | 可以精确到纳秒 |
jdk8以前的时间类主要有:
Date、SimpleDateFormat、Calendar |
---|
jdk8以后的时间类主要有:
时间类别 | 类 |
---|---|
日历类(获取当前时间) | LocalDate、LocalTime、LocalDateTime |
日期格式化类(格式化时间) | DateTimeFormatter |
时间类(获取时间) | Instant、ZoneId、ZoneDateTime |
工具类(计算时间间隔) | Period、Duration、ChronoUnit |
递归
什么是递归?
- 方法直接或间接的调用本身
异常
异常的学习要求?
-
看得懂异常信息
-
了解异常体系结构和分类
-
掌握异常的两种处理方式
-
自定义异常
异常的体系
Error异常:严重级别问题
Exception异常:
- RuntimeException 及其子类:运行时可能出现的异常
- 除RuntimeException 之外所有的异常:编译时可能出现的异常(起提醒作用,要在准备运行前解决)
异常的处理方式
Java默认的处理方式
- 创建异常对象:虚拟机在异常代码位置,自动创建一个异常对象:
ArithmeticException
- 逐层抛出:在出现异常的地方抛出给调用者,再抛出给JVM虚拟机
- 接受处理:虚拟机接收到异常对象后,在控制台输出异常信息
- 程序终止:异常点之后的代码不再运行
try…catch…异常捕捉
- 可以捕捉异常后,给出处理方案
- 代码可以继续运行
异常有关的两个关键字区别:throw和throws
throw
- 使用位置:方法中
- 作用:程序运行到此处,若有异常,抛出异常对象
- 时机:运行时可能出现的异常,用
throw
创建
throws
- 使用位置:方法名后面
- 作用:声明该方法存在异常,需要调用者进行处理
- 时机:编写代码时候,就有方法可能在调用过程中出现异常,就用
throws
创建,以通过编译
Stream流
Stream流的用途?
简化对集合、数据的一些复杂操作。流操作不会改变原数据
Stream流的思想
首先:将数据放到流中,获取一个流对象
其次:调用中间方法。对流对象进行操作,操作后的返回值依然是流对象,就可以实现链式调用
最后:调用终结方法。对流对象的最终操作,操作后的流对象不可再用,操作结束
【补充】
-
流的中间方法和终结方法的区别?
-
中间方法操作后的返回结果,依旧是流对象
-
终结操作操作后,或有返回结果,结果不再是流对象;或没有返回值
-
被终结方法操作过的流对象,不能再进行中间方法操作
-
Stream流对象的获取
集合获取流对象
**set集合:**直接获取:set.stream()
public class StreamDemo1 {
public static void main(String[] args) {
Set<String> set = new HashSet<String>();
set.add("张三丰");
set.add("张无忌");
set.add("张翠山");
set.add("王二麻子");
set.add("张良");
set.add("谢广坤");
set.stream().forEach(s -> System.out.println(s));
}
}
**map集合:**间接获取:map.entrySet.stream()
public class StreamDemo1 {
public static void main(String[] args) {
Map<String, Integer> map = new HashMap<String, Integer>();
map.put("张三丰", 100);
map.put("张无忌", 35);
map.put("张翠山", 55);
map.put("王二麻子", 22);
map.put("张良", 30);
map.put("谢广坤", 55);
Set<Map.Entry<String, Integer>> entrySet = map.entrySet();
entrySet.stream().forEach(s -> System.out.println(s));
}
}
数组获取流对象
public class StreamDemo1 {
/*
直接获取:list.stream()
*/
public static void main(String[] args) {
List<String> list = new ArrayList<String>();
list.add("张三丰");
list.add("张无忌");
list.add("张翠山");
list.add("王二麻子");
list.add("张良");
list.add("谢广坤");
list.stream().forEach(s -> System.out.println(s));
}
}
零散的数据获取流对象
public class StreamDemo1 {
public static void main(String[] args) {
Stream.of(1, 2, 3, 4, 5, 6).forEach(s -> System.out.println(s));
Stream.of("张三", "李四", "王五", "赵六").forEach(s -> System.out.println(s));
}
}
Stream流的中间操作方法
过滤、获取、跳过、去重、合并
public class StreamDemo2 {
public static void main(String[] args) {
// 需求: 将集合中以 【张】 开头的数据,过滤出来并打印在控制台
ArrayList<String> list = new ArrayList<String>();
list.add("林青霞");
list.add("张曼玉");
list.add("王祖贤");
list.add("柳岩");
list.add("张敏");
list.add("张无忌");
list.stream().filter(s -> s.startsWith("张")).filter(s -> s.length() == 3).forEach(s -> System.out.println(s));
System.out.println("-------------------------------------");
// 需求1: 取前3个数据在控制台输出
list.stream().limit(3).forEach(s -> System.out.println(s));
System.out.println("-------------------------------------");
// 需求2: 跳过3个元素, 把剩下的元素在控制台输出
list.stream().skip(3).forEach(s -> System.out.println(s));
System.out.println("-------------------------------------");
// 需求3: 跳过2个元素, 把剩下的元素中前2个在控制台输出
list.stream().skip(2).limit(2).forEach(s -> System.out.println(s));
System.out.println("-------------------------------------");
// 需求4: 取前4个数据组成一个流
Stream<String> s1 = list.stream().limit(4);
// 需求5: 跳过2个数据组成一个流
Stream<String> s2 = list.stream().skip(2);
// 需求6: 合并需求4和需求5得到的流, 并把结果在控制台输出
Stream<String> s3 = Stream.concat(s1, s2);
// s3.forEach(s -> System.out.println(s));
System.out.println("-------------------------------------");
// 需求7: 合并需求4和需求5得到的流, 并把结果在控制台输出,要求字符串元素不能重复
s3.distinct().forEach(s -> System.out.println(s));
}
}
Stream流的终结操作方法
public class StreamDemo3 {
public static void main(String[] args) {
long count = Stream.of(1, 2, 3, 4, 5, 6).filter(s -> s % 2 == 0).count();
System.out.println(count);
}
}
Stream流的收集操作
将流操作后的结果返回为对象
收集操作调用的方法:
Collectors工具类提供的收集方法:
public class StreamDemo4 {
public static void main(String[] args) {
List<Integer> list1 = Stream.of(1, 2, 3, 4, 5, 6, 7, 8, 9, 10).filter(s -> s % 2 == 0).collect(Collectors.toList());
System.out.println(list1);
Set<Integer> list2 = Stream.of(1, 2, 3, 4, 5, 6, 8, 9, 10, 10, 10).filter(s -> s % 2 == 0).collect(Collectors.toSet());
System.out.println(list2);
}
}
File类
什么是File类?
- File类代表操作系统的文件对象(文件、文件夹)
从文件、文件夹到File类的处理
File类的创建
package com.itheima.day12.file;
import java.io.File;
import java.io.IOException;
public class FileDemo1 {
public static void main(String[] args) throws IOException {
// 根据文件路径创建对象
File f1 = new File("D:\\A.txt");
f1.createNewFile();
// 根据文件夹路径创建对象
File f2 = new File("D:\\test");
System.out.println(f2.exists());
// 根据父路径+子路径名字的字符串创建对象
File f3 = new File("D:\\", "test");
System.out.println(f3.exists());
// 根据父路径对应的文件对象+子路径名字的字符串创建对象
File f4 = new File(new File("D:\\"), "test");
System.out.println(f4.exists());
}
}
File封装的特点:
- File封装的对象可以是文件,也可以是文件夹
- File封装的对象仅仅是一个路径名:路径可以存在,也可以不存在
File类的常用方法
【补充】
针对length()
方法:
public class FileMethodDemo3 {
public static void main(String[] args) {
File f1 = new File("D:\\A.txt");
System.out.println(f1.isDirectory()); // false
System.out.println(f1.isFile()); // true
System.out.println(f1.exists()); // true
System.out.println("----------------------");
File f2 = new File("D:\\test");
System.out.println(f1.length());
System.out.println(f2.length());
System.out.println("----------------------");
File f3 = new File("A.txt");
System.out.println(f3.getAbsolutePath());
System.out.println("----------------------");
System.out.println(f1.getName());
System.out.println(f2.getName());
System.out.println(f3.getName());
System.out.println("----------------------");
long time = f1.lastModified();
System.out.println(new Date(time));
}
}
File类遍历方法
package com.itheima.day12.file;
import java.io.File;
public class FileMethodDemo5 {
/*
File类的遍历方法 :
public File[] listFiles() 获取当前目录下所有的 "一级文件对象" 返回 File 数组
*/
public static void main(String[] args) {
File f = new File("D:\\test");
File[] files = f.listFiles();
for (File file : files) {
System.out.println(file);
}
}
}
- 当调用者File表示的路径不存在时,返回null
- 当调用者File表示的路径是文件时,返回null
- 当调用者File表示的路径是需要权限才能访问的文件夹时,返回null
- 当调用者File表示的路径是一个空文件夹时,返回一个长度为0的数组
从File类到文件、文件夹的处理
文件、文件夹的创建、删除
注意:delete方法:针对文件,空或不空都可以删除;针对文件夹,只能删除空的文件夹
public class FileMethodDemo4 {
public static void main(String[] args) throws IOException {
File f1 = new File("src\\com\\itheima\\day12\\B.txt");
System.out.println(f1.createNewFile());
File f2 = new File("src\\com\\itheima\\day12\\aaa");
System.out.println(f2.mkdirs());
File f3 = new File("src\\com\\itheima\\day12\\C.txt"); // 也是创建的文件夹,C.txt就是文件夹的名字
// 创建的是什么,跟路径没关系,跟调用的方法有关
System.out.println(f3.mkdirs());
System.out.println(f1.delete());
System.out.println(f2.delete());
}
}