9.常用类、String、Math、日期
一、常用类
1. 包装类
包装类: 针对八种基本数据类型定义相应的引用类型;
基本数据类型 | 包装类 | 父类 |
---|---|---|
boolean | Boolean | Object |
char | Character | |
byte | Byte | Number |
short | Short | |
int | Integer | |
long | Long | |
float | Float | |
double | Double |
包装类与基本数据类型的转换
jdk5 以前为手动装箱、拆箱,jdk5 以后为自动装箱、拆箱(底层调用的是 ValueOf 和 IntValue)
其他包装类 的用法类似。
// 拆箱、装箱
public class Warpper01 {
public static void main(String[] args) {
// jdk 5 以前为手动装箱、拆箱
// 装箱
int n1 = 100;
Integer integer = Integer.valueOf(n1);
System.out.println(integer);
// 拆箱
int i = integer.intValue();
System.out.println(i);
// jdk 5 以后 为自动装箱、拆箱
int n2 = 200;
// 装箱
Integer itg = n2;
System.out.println(itg);
// 拆箱
int n3 = itg;
System.out.println(n3);
}
}
// 包装类 与 String 相互转换
public class Wrapper02 {
public static void main(String[] args) {
// 包装类 与 String 相互转换
Integer int1 = 123;
// 包装类 -> String
String str1 = int1 + "";
String str2 = int1.toString();
String str3 = String.valueOf(int1);
// String -> 包装类
Integer int2 = Integer.valueOf(str1);
Integer integer = new Integer(str2);
}
}
常用方法:
Integer.MIN_VALUE | 返回最小值 |
---|---|
Integer.MAX_VALUE | 返回最大值 |
Character.isDigit() | 是否为字母 |
Character.isLetter() | 是否为数字 |
Character.isUpperCase() | 是否为大写字母 |
Character.isLowerCase() | 是否为小写字母 |
Character.isWhitespace() | 是否为空格 |
Character.toUpperCase() | 转换为大写字母 |
Character.tpLowerCase() | 转换为小写字母 |
警告
只要有基本数据类型,“==”比较的就是值是否相等
// 面试题
public class Wrapper03 {
public static void main(String[] args) {
// new 关键字创建的,坑定是不同的对象
// 对象之间用 == 比较,比较的是两个对象的地址
Integer i1 = new Integer(127);
Integer i2 = new Integer(127);
System.out.println(i1 == i2); // false
Integer i3 = new Integer(128);
Integer i4 = new Integer(128);
System.out.println(i3 == i4); // false
// 底层为 Integer.valueOf()
// Integer 的范围为 -128 ~ 127
Integer i5 = 127;
Integer i6 = 127;
System.out.println(i5 == i6); // true
Integer i7 = 128;
Integer i8 = 128;
System.out.println(i7 == i8); // false
Integer i9 = 127; // 从数组中获取
Integer i10 = new Integer(127); // 不同的对象
System.out.println(i9 == i10); // false
// 只要有基本数据类型,== 判断的就是值是否相等
Integer i11 = 127;
int i12 = 127;
System.out.println(i11 == i12); // true
Integer i13 = 128;
int i14 = 128;
System.out.println(i13 == i14); // true
}
}
二、String
1. String
提示
String 特点:
- 字符串的字符使用 Unicode 字符编码,一个字符(不区分字母还是汉字)占两个字节;
- String 类有多种构造器,构造器重载
- new String();
- new String([String original]);
- new String(char[] a);
- new String(char[] a,int startIndex, int count);
- String 类实现了接口:
- Serializable (string 可以串行:即可以在网络传输)
- Comparable (String 对象可以进行比较)
- String 是 final 类,不能被其他类继承
- String 有属性 private final char value[] ,用于存放字符串内容
// 两种创建 String 对象的区别
String s1 = "hsp";
String s2 = new String("hsp");
提示
两种创建 String 对象的区别:
- 直接创建:
- 先从常量池查看是否有“hsp”数据空间,如果有则直接指向;
- 如果没有,则重新创建,然后指向;
- s 最终指向的是常量池的空间地址
- 利用构造器重建:
- 先在堆中创建空间,里面维护了 value 属性,指向常量池的 “hsp” 空间;
- 如果常量池没有 “hsp”,则重新创建;如果有,则通过 value 指向;
- 最终指向的是堆中的空间地址
// 两种创建 String 对象方法
public class String01 {
public static void main(String[] args) {
String a = "hsp"; // 指向常量池
String b = new String("hsp"); // b 先指向堆空间,再通过 value 属性指向常量池
System.out.println(a.equals(b)); // true 值相等
System.out.println(a == b); // false 地址不同
System.out.println(a == b.intern()); // true b.intern() 返回的是常量池的地址
System.out.println(b == b.intern()); // false b 指向堆空间地址
}
}
String 常用方法:
equals | 区分大小写,判断内容是否相等 |
---|---|
equalslgnoreCase | 不区分大小写,判断内容是否相等 |
length | 获取字符串长度 |
indexOf | 获取字符在字符串中第一次出现时的索引,找不到返回 -1 |
lastIndexOf | 获取字符在字符串中最后 1 次出现的索引,找不到返回 -1 |
substring | 截取指定范围的字符串 |
trim | 去除前后空格 |
charAt | 获取某索引出的字符,注意不能使用 Str[index] 方式 |
toUpperCase | 全部转为大写 |
toLowerCase | 全部转为小写 |
concat | 字符串拼接 |
replace | 替换字符串中的字符 |
split | 分割字符串 |
compareTo | 比较两个字符串大小,根据 ASCii 的编码比较,前面的数大,就返回正数,后面的数大,就返回负数,相等则返回 0,如果字符传部分相同,则比较字符串长度 |
format | 字符串格式化 |
toCharArray | 字符串转为 字符数组 |
// String 常用方法案例
public class String01{
public static void main(String[] args) {
// 1.equals 区分大小写比较
String s1 = "hello ";
String s2 = "HELLO ";
String s3 = "Where Are You Doing";
System.out.println(s1.equals(s2)); // false
// 2.equalsIgnoreCase 不区分大小写 比较
System.out.println(s1.equalsIgnoreCase(s2)); // true
// 3.length 获取数组长度
System.out.println(s1.length()); // 6
// 4. indexOf 获取字符第一次出现在字符串中的索引
System.out.println(s1.indexOf("l")); // 2
// 5. lastIndexOf 获取字符 最后一次出现在字符串中的索引
System.out.println(s1.lastIndexOf("l")); // 3
// 6. substring 根据下标截取字符串,左闭右开
System.out.println(s1.substring(2)); // llo
System.out.println(s1.substring(2,4)); // ll
// 7. trim 去除前后空格
System.out.println(s1.trim()); // hello
// 8. charAt 根据下标获取字符
System.out.println(s1.charAt(4)); // o
// 9. toUpperCase 全部大写
System.out.println(s3.toUpperCase(Locale.ROOT)); // WHERE ARE YOU DOING
// 10. toLowerCase 全部小写
System.out.println(s3.toLowerCase(Locale.ROOT)); // where are you doing
// 11. concat 合并数组
System.out.println(s3.concat(s1)); // Where Are You Doinghello
// 12. replace 替换字符串中的字符
System.out.println(s3.replace("Are",s2)); // Where HELLO You Doing
// 13. split 分割字符串
String[] s4 = s3.split(" ");
for (String s:s4){
System.out.println("s3.split = " + s);
}
// 14. compareTo 比较两个字符串的大小, 前者大返回正数,后者大返回负数,相等返回 0
System.out.println(s2.compareTo(s1)); // -32
// 15. toCharArray 转换成字符数组
char[] s5 = s2.toCharArray();
for(char s:s5){
System.out.println("s2.toCharArray = " + s);
}
// 16. format 字符串格式化 %s:字符串,%d:整型,%f:浮点型
System.out.printf("%s,今年%d 岁了,有%.2f压岁钱。","小明",5,100.5); // 小明,今年5 岁了,有100.50压岁钱。
}
}
2. StringBuffer 类
StringBuffer 代表可变的字符序列,可以对字符串内容进行增删,是可变长度
提示
String 和 StringBuffer 的区别:
- String 保存的是字符串常量,里面的值是不能更改的,
- 每次 String 类的更新实际上就是更改地址,效率较低
- char[] valre 放在常量池中
- StringBuffer 保存的字符串变量,里面的值是可以更改的
- 更新时,实际上是改变内容,而不是每次都更新地址
- char[] value 放在堆中
// StringBuffer 构造器
// 1. 创建一个大小为 16 的 char[] 数组,用于存放内容
StringBuffer s1 = new StringBuffer();
// 2. 通过构造器 指定 char[] 大小
StringBuffer s2 = new StringBuffer(100);
// 3. 给一个 字符串 创建 StringBuffer,char[]大小为 str.length() + 16
StringBuffer s3 = new StringBuffer("Hello");
// String 和 StringBuffer 相互转换
public class StringBuffer01 {
public static void main(String[] args) {
// String 和 StringBuffer 相互转换
String s1 = "Hello tom";
// String --> StringBuffer
// 通过构造器转换
StringBuffer sb1 = new StringBuffer(s1);
// 通过 append 转换
StringBuffer sb2 = new StringBuffer();
sb2.append(s1);
// StringBuffer --> String
StringBuffer sb3 = new StringBuffer("study Java");
// 通过 toString 方法转换
String s2 = sb3.toString();
// 通过 String 构造器转换
String s3 = new String(sb3);
}
}
StringBuffer 常用方法:
append | 增 |
---|---|
delete(start,end) | 删 |
replace(start,end,string) | 改(将 start 到 end 间的内容换掉,不含 end) |
indexOf | 查(查找字符串在字符串中第一次出现的索引,找不到返回-1) |
insert | 插入 |
length | 获取长度 |
// StringBuffer 增删改查
public class String02 {
public static void main(String[] args) {
// StringBuffer 增删改查
// 增
StringBuffer s = new StringBuffer("张三疯");
s.append(',');
s.append("宋无忌").append(",张翠山");
System.out.println("增加后:"+s);
// 删
s.delete(4,7);
System.out.println("删除后:"+s);
// 改
s.replace(4,5,"拳打敬老院,脚踩幼儿园");
System.out.println("修改后:"+s);
// 查
System.out.println("查找 张翠山 :"+s.indexOf("张翠山"));
// 插入
s.insert(4,"他的徒弟们,");
System.out.println("插入后:"+s);
}
}
3. StringBuilder
StringBuilder 是 StringBuffer 的简易替换 两者的方法是一样的 StringBuilder 主要用于单线程
注
- 一个可变的字符序列;
- 不是线程安全,主要用在字符串缓冲区被单线程使用的时候;
- 如果可以,建议使用该类,他不 StringBuffer 更快
- 主要操作是 append 和 insert 方法,可以重载这些方法,以接受任意类型的数据;
提示
String、StringBuffer、StringBuilder 的比较:
- StringBuilder 和 StringBuffer 非常类似,均代表可变的字符序列,而且方法也一样;
- String: 不可变字符序列,效率低,但是复用率高;
- 如果需要做大量的修改,不要使用 String;
- StringBuffer: 可变字符序列,效率较高(增删)、线程安全
- StringBuilder: 可变字符序列,效率最高,线程不安全
警告
String、StringBuffer、StringBuilder 的选择:
- 如果字符串存在大量的修改操作,一般使用 StringBuffer 或 StringBuilder
- 如果字符串存在大量的修改操作,并在单线程的情况,使用 StringBuilder
- 如果字符串存在大量的修改操作,并在多线程的情况,使用 StringBuffer
- 如果我们字符串很少修改,被多个对象引用,使用 String;
三、Math 类
Math 类包含用于执行基本数据运算的方法,如对数、平方根、三角函数等 Math 的方法 基本都是 静态方法,因此可以直接使用类名获取
Math 类常用方法:
abs | 绝对值 | System.out.println(Math.abs(-27)); 27 |
---|---|---|
pow | 求幂(求 a 的 b 次方) | System.out.println(Math.pow(3,4)); 81.0 |
ceil | 向上取整,返回>=该参数的最小整数 | System.out.println(Math.ceil(3.1415)); 4 |
floor | 向下取整,返回<=该参数的最大整数 | System.out.println(Math.floor(3.1415)); 3 |
round | 四舍五入 | System.out.println(Math.round(3.1415)); 3 |
sqrt | 求开方(参数必须大于等于 0) | System.out.println(Math.sqrt(18)); 4.2426406 |
random | 随机数(取值为>= 0,< 1 的小数) | System.out.println(Math.random()); 0.36541574255 |
min | 最小数值 | System.out.println(Math.min(18,22)); 18 |
max | 最大数值 | System.out.println(Math.max(18,22)); 22 |
// 随机数 - 案例
public class Math02 {
public static void main(String[] args) {
for (int i = 0; i < 10; i++) {
System.out.println(ran(2,7));
}
}
public static int ran(int a, int b){
// 最终返回的是 a <= x < b+1 的小数
return (int)(a + Math.random()*(b-a+1));
}
}
四、Arrays(数组)
常用方法:
toString | 返回数组的字符串形式 |
---|---|
sort | 排序(从小到大) |
binarySearch | 通过二分法进行查找(必须是有序数组) |
copyOf | 复制数组到新的数组 copyOf(原来的数组,复制的长度) |
fill | 数组元素的填充(替换数值中的所有元素) |
equals | 比较两个数组元素内容是否相同 |
asList | 将一组值,转换成 list |
// 自定义 排序,通过 Comparator接口实现
Arrays.sort(books, new Comparator<Book>() {
@Override
public int compare(Book o1, Book o2) {
// 因为返回值为 int ,需要做下转换
double num = o1.getPrice() - o2.getPrice();
// 通过控制 返回值的正负来确定排序方向
if (num > 0){
return 1;
}else if(num < 0){
return -1;
}else {
return 0;
}
}
});
// Arrays 常用方法
public class Arrays01 {
public static void main(String[] args) {
int[] a1 = {1,4,-10,-32,66,43,91};
int[] a2 = {33,44,55,-11,-22,-33};
// toString 返回数组的字符串形式
System.out.println(Arrays.toString(a1));
// sort 排序(从小到大)
Arrays.sort(a1);
System.out.println(Arrays.toString(a1));
// binarySearch 二分法查找,返回数组元素下标(数组必须是有序的)
// 如果找不到,则返回负值,负值为他应该存在的位置
// 如果数组长度不够,则最后赋值为 null
int index = Arrays.binarySearch(a1,6);
System.out.println(index);
// copyOf 复制数组到新的数组 copyOf(原来的数组,复制的长度)
int[] a3 = Arrays.copyOf(a2,3);
System.out.println(Arrays.toString(a3));
// fill 数组填充(替换原来数组中的所有元素)
Arrays.fill(a2,123);
System.out.println(Arrays.toString(a2));
// equals 比较两个数组内容是否一致
int[] arr1 = {1,22,333};
int[] arr2 = {1,22,333};
System.out.println(Arrays.equals(arr1,arr2));
}
}
// 排序 - 案例
public class Arrays02 {
public static void main(String[] args) {
Book[] books = new Book[5];
books[0] = new Book("红楼梦", 100);
books[1] = new Book("三国演义", 120);
books[2] = new Book("西游记", 150);
books[3] = new Book("水浒传", 99);
books[4] = new Book("天龙八部", 113);
System.out.println(Arrays.toString(books));
// 自定义 排序,通过 Comparator接口实现
Arrays.sort(books, new Comparator<Book>() {
@Override
public int compare(Book o1, Book o2) {
// 因为返回值为 int ,需要做下转换
double num = o1.getPrice() - o2.getPrice();
// 通过控制 返回值的正负来确定排序方向
if (num > 0){
return 1;
}else if(num < 0){
return -1;
}else {
return 0;
}
}
});
System.out.println(Arrays.toString(books));
}
}
class Book{
private String name;
private double price;
public Book(String name, double price) {
this.name = name;
this.price = price;
}
public double getPrice() {
return price;
}
public void setPrice(double price) {
this.price = price;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
return name + "\t" + price;
}
}
五、System 类
常见方法:
exit | 退出当前程序,0 表示正常状态 |
---|---|
arraycopy | 复制数组元素 |
currentTimeMillens | 返回当前时间的毫秒数 |
gc | 运行垃圾回收机制 |
提示
System.arraycopy(原数组,拷贝起始索引,目标数组,目标数组起始索引,拷贝数量)
六、 BigInteger 和 BigDecimal
BigInteger : 适合保存比较大的整数 > BigDecimal : 适合保存精度高的浮点数
提示
BigInteger 、BigDecimal 注意事项:
- 在进行加减乘除操作时,需要使用对应的方法,不能使用基础数据类型的操作方法
- 加:add()
- 减:subtract()
- 乘:multiply()
- 除:divide()
- BigDecimal 可能会有无限循环小数,所以需要指定精度(BigDecimal.ROUND_CEILING)
- 如果有无限循环小数,就会保留 分子 的精度
- 创建 BigInteger 对象时,最好以字符串的形式传参;
// BigInteger - 案例
public class BigInteger01 {
public static void main(String[] args) {
BigInteger bi1 = new BigInteger("12313231231893485938274592784952");
BigInteger bi2 = new BigInteger("123123");
System.out.println(bi1.add(bi2)); // 加
System.out.println(bi1.subtract(bi2)); // 减
System.out.println(bi1.multiply(bi2)); // 乘
System.out.println(bi1.divide(bi2)); // 除
}
}
// BigDecimal - 案例
public class BigInteger01 {
public static void main(String[] args) {
BigDecimal bi1 = new BigDecimal("3.14159263453542423424343");
BigDecimal bi2 = new BigDecimal("3.2342324123");
System.out.println(bi1.add(bi2)); // 加
System.out.println(bi1.subtract(bi2)); // 减
System.out.println(bi1.multiply(bi2)); // 乘
System.out.println(bi1.divide(bi2, BigDecimal.ROUND_CEILING)); // 除
}
}
七、日期类
1.第一代日期( Date)
Date:精确到毫秒,代表特定的瞬间
// 第一代 日期
public class Date01 {
public static void main(String[] args) throws ParseException {
// 获取当前时间
Date time = new Date();
System.out.println(time);
// 格式化日期,E 为星期
SimpleDateFormat sdf = new SimpleDateFormat("yyyy年 MM月 dd日 hh:mm:ss E");
System.out.println(sdf.format(time));
// 将个时候后的日期转为默认日期
// 默认会报异常,只需将异常抛出即可
String s = "2022年 05月 17日 05:23:48 周二";
Date parse = sdf.parse(s);
System.out.println(parse);
}
}
2. 第二代日期(Calendar 日历)
Calendar: 是一个抽象类,他为特定瞬间与一组日历字段之间的转换提供了方法。
// 第二代日期 - 案例
public class Calendar_ {
public static void main(String[] args) {
// Calendar 是一个抽象类,他的构造器是私有化的,需要用过 getInstance 来创建对象
Calendar c = Calendar.getInstance();
System.out.println(c);
System.out.println(c.get(Calendar.YEAR) + "年");
// 月份是从 0 开始返回的,因此需要 +1
System.out.println((c.get(Calendar.MONDAY) + 1)+ "月");
System.out.println(c.get(Calendar.DATE) + "日");
System.out.println(c.get(Calendar.HOUR) + "时");
System.out.println(c.get(Calendar.MINUTE) + "分");
System.out.println(c.get(Calendar.SECOND) + "秒");
}
}
3. 第三代日期
常见方法:
LocalDate | 只包含日期,可以获取日期字段 |
---|---|
LocalTime | 只包含时间,可以获取时间字段 |
LocalDateTime | 包含日期和时间 |
// 第三代日期
public class LocalDate_ {
public static void main(String[] args) {
LocalDateTime ld = LocalDateTime.now();
System.out.println(ld);
LocalDate now = LocalDate.now();
System.out.println(now);
LocalTime now1 = LocalTime.now();
System.out.println(now1);
System.out.println(ld.getYear());
System.out.println(ld.getMonth());
System.out.println(ld.getMonthValue());
System.out.println(ld.getDayOfMonth());
System.out.println(ld.getHour());
System.out.println(ld.getMinute());
System.out.println(ld.getSecond());
}
}
提示
DateTimeFormatter : 用于格式化日期 yyyy 年 MM 月 dd 日 HH:mm:ss E
// 格式化日期
public class LocalDate_ {
public static void main(String[] args) {
LocalDateTime ld = LocalDateTime.now();
System.out.println(ld);
// 格式化输出日期
DateTimeFormatter dtf = DateTimeFormatter.ofPattern("yyyy年 MM月 dd日 HH:mm:ss E");
System.out.println(dtf.format(ld));
}
}
时间戳
提示
Instant 转换为 Date:Date date = Date.from(Instant); Date 转换为 Instant: Instant instant = Date.toInstant();
// 时间戳
public class LocalDate_ {
public static void main(String[] args) {
// 获取当前时间
Instant now = Instant.now();
// 通过 from 方法把 Instant 转为 Date
Date date = Date.from(now);
System.out.println(date);
// 通过 toInstant 方法把 date 转为 Instant
Instant instant = date.toInstant();
System.out.println(instant);
}
}
// 日期的加减
public class LocalDate_ {
public static void main(String[] args) {
//
LocalDateTime now = LocalDateTime.now();
DateTimeFormatter dtf = DateTimeFormatter.ofPattern("yyyy年 MM月 dd日 HH:mm:ss E");
// 日期增加 890 天
LocalDateTime now1 = now.plusDays(890);
System.out.println(dtf.format(now1));
// 日期减少 120 天
LocalDateTime now2 = now.minusDays(120);
System.out.println(dtf.format(now2));
}
}