Java基础:常用类(四)
文章目录
- Java基础:常用类(四)
- 1. String字符串类
- 1.1 简介
- 1.2 创建方式
- 1.3 构造方法
- 1.4 连接操作符
- 1.5 常用方法
- 2. StringBuffer和StringBuilder类
- 2.1 StringBuffer类
- 2.1.1 简介
- 2.1.2 构造方法
- 2.2 StringBuilder类
- 2.2.1 简介
- 2.2.2 构造方法
- 2.3 常用方法
- 3. Wrapper类(包装类)
- 3.1 简介
- 3.2 常用方法
- 4. Math类
- 4.1 简介
- 4.2 常用方法
- 5. Random类
- 5.1 简介
- 5.2 构造方法
- 5.3 常用方法
- 6. BigInteger和BigDecimal类
- 6.1 简介
- 6.2 创建方式
- 6.3 常用方法
- 6.4 RoundingMode处理方式
- 7. 日期和时间
- 7.1 Date类
- 7.2 DateFormat类
- 7.3 Calendar类
- 7.4 GregorianCalendar类
- 7.5 JDK8新增日期工具类
- 8. 正则表达式
- 8.1 简介
- 8.2 java.util.regex包
- 8.3 常用方法
- 8.3.1 Matcher类的方法
- 8.3.2 PatternSyntaxException类的方法
1. String字符串类
1.1 简介
- 引用类型:
String
不是基本数据类型,是一种引用类型。 - 不可改变:
String
代表一组不可改变的Unicode
字符序列。String
类对象的内容一旦被初始化,不能再改变。 - final修饰:
String
类是final
修饰的终结类,不能产生子类。
1.2 创建方式
- 静态方式创建(字符串字面量):当使用字符串字面量(如
"abc"
)来创建String
对象时,JVM会首先检查字符串常量池中是否已经存在具有相同内容的字符串对象。如果存在,则不会创建新的对象,而是直接返回对池中已存在对象的引用。如果不存在,则会在字符串常量池中创建一个新的字符串对象。
String str1 = "abc";
- 动态方式创建(使用new关键字):使用
new String("abc")
创建String
对象时,无论字符串常量池中是否存在相同内容的字符串对象,都会在堆内存中创建一个新的String
对象。
String str2 = new String("abc");
代码示例如下:
public class Test1 {
public static void main(String[] args) {
String str1 = "abc";
String str2 = new String("abc");
System.out.println(str1 == str2);
System.out.println(str1.equals(str2));
}
}
🆚🆚运行结果:
false
true
1.3 构造方法
String
类提供了多种构造方法来创建字符串对象。以下是一些常见的String
类构造方法:
- 无参构造方法:创建一个空的字符串对象。
String str = new String();
- 通过String直接构造:直接使用另一个
String
对象创建新的String
对象。
String str = new String(String original);
- 通过字符数组构造:使用字符数组来创建一个新的
String
对象,其内容为字符数组中的所有字符。
String str = new String(char[] chars);
- 通过字节数组构造:使用字节数组创建一个新的
String
对象,并使用平台的默认字符集将其解码为一个字符串。
String str = new String(byte[] bytes);
- 通过部分字符数组构造:使用字符数组的一部分来创建一个新的
String
对象,其中offset
是起始下标,count
是长度。
String str = new String(char[] chars, int offset, int count);
- 通过部分字节数组构造:使用字节数组的一部分来创建一个新的
String
对象,并指定字符集(以避免编码问题),其中offset
是起始下标,length
是长度。
String str = new String(byte[] bytes, int offset, int length);
- 通过StringBuffer或StringBuilder构造:使用
StringBuffer
或StringBuilder
的toString()
方法来创建一个新的String
对象,该对象包含StringBuffer
或StringBuilder
当前的内容。
StringBuffer sb = new StringBuffer("StringBuffer");
String str = sb.toString();
代码示例如下:
public class Test2 {
public static void main(String[] args) {
String str = "abc";
String str1 = new String(str);
char[] chars = str1.toCharArray();
for (char aChar : chars) {
System.out.println(aChar);
}
char[] c = {'c', 'h', 'a', 'r', 'A', 'r', 'r', 'a', 'y'};
byte[] b = {'b', 'y', 't', 'e', 'A', 'r', 'r', 'a', 'y'};
String str2 = new String(c);
String str3 = new String(b);
String str4 = new String(c, 0, 4);
String str5 = new String(b, 0, 4);
StringBuffer sb = new StringBuffer("StringBuffer");
String str6 = sb.toString();
System.out.println(str2);
System.out.println(str3);
System.out.println(str4);
System.out.println(str5);
System.out.println(str6);
}
}
🆚🆚运行结果:
a
b
c
charArray
byteArray
char
byte
StringBuffer
📌注:
- String:用于表示不可变的字符序列。一旦创建,
String
对象的内容就不能被修改。- StringBuffer:是一个表示可变字符序列的类,用于在字符串内容需要经常改变的情况下。它是线程安全的。
- StringBuilder:与
StringBuffer
类似,也是一个表示可变字符序列的类,但它不是线程安全的。在单线程环境中,StringBuilder
的性能通常优于StringBuffer
。
1.4 连接操作符
可以使用+
作为连接符,任何的数据类型和字符串使用加号连在一起,最后都会变成字符串类型。代码示例如下:
public class Test3 {
public static void main(String[] args) {
String str1 = "abc";
String str2 = "def";
String str3 = "abcdef";
System.out.println(str3 == str1 + str2); // 变量相加,先开辟空间地址,再做拼接,后比较
System.out.println(str3 == "abc" + "def"); // 先做拼接,再去常量池中查找
System.out.println(str3.equals(str1 + str2));
System.out.println(str3.equals("abc" + "def"));
}
}
🆚🆚运行结果:
false
true
true
true
1.5 常用方法
方法 | 说明 |
---|---|
char charAt(int index) | 返回指定索引处的char 值 |
int compareTo(Object o) | 把这个字符串和另一个对象比较 |
int compareTo(String anotherString) | 按字典顺序比较两个字符串 |
int compareToIgnoreCase(String str) | 按字典顺序比较两个字符串,不考虑大小写 |
String concat(String str) | 将指定字符串连接到此字符串的结尾 |
boolean contentEquals(StringBuffer sb) | 当且仅当字符串与指定的StringBuffer 有相同顺序的字符时候返回true |
static String copyValueOf(char[] data) | 返回指定数组中表示该字符序列的String |
static String copyValueOf(char[] data, int offset, int count) | 返回指定数组中表示该字符序列的String ,从指定的偏移量开始,长度为指定的字符数 |
boolean endsWith(String suffix) | 测试此字符串是否以指定的后缀结束 |
boolean equals(Object anObject) | 将此字符串与指定的对象比较 |
boolean equalsIgnoreCase(String anotherString) | 将此String 与另一个String 比较,不考虑大小写 |
byte[] getBytes() | 使用平台的默认字符集将此String 编码为byte 序列,并将结果存储到一个新的byte 数组中 |
byte[] getBytes(String charsetName) | 使用指定的字符集将此String 编码为byte 序列,并将结果存储到一个新的byte 数组中 |
void getChars(int srcBegin, int srcEnd, char[] dst, int dstBegin) | 将字符从此字符串复制到目标字符数组 |
int hashCode() | 返回此字符串的哈希码 |
int indexOf(int ch) | 返回指定字符在此字符串中第一次出现处的索引 |
int indexOf(int ch, int fromIndex) | 返回在此字符串中第一次出现指定字符处的索引,从指定的索引开始搜索 |
int indexOf(String str) | 返回指定子字符串在此字符串中第一次出现处的索引 |
int indexOf(String str, int fromIndex) | 返回指定子字符串在此字符串中第一次出现处的索引,从指定的索引开始 |
String intern() | 返回字符串对象的规范化表示形式 |
int lastIndexOf(int ch) | 返回指定字符在此字符串中最后一次出现处的索引 |
int lastIndexOf(int ch, int fromIndex) | 返回指定字符在此字符串中最后一次出现处的索引,从指定的索引处开始进行反向搜索 |
int lastIndexOf(String str) | 返回指定子字符串在此字符串中最右边出现处的索引 |
int lastIndexOf(String str, int fromIndex) | 返回指定子字符串在此字符串中最后一次出现处的索引,从指定的索引开始反向搜索 |
int length() | 返回此字符串的长度 |
boolean matches(String regex) | 判断字符串是否匹配给定的正则表达式 |
boolean regionMatches(boolean ignoreCase, int toffset, String other, int ooffset, int len) | 测试两个字符串区域是否相等 |
boolean regionMatches(int toffset, String other, int ooffset, int len) | 测试两个字符串区域是否相等,它默认是大小写敏感的,即ignoreCase 参数被设置为false |
String replace(char oldChar, char newChar) | 用于替换字符串中的所有指定字符 |
String replaceAll(String regex, String replacement) | 使用给定的replacement 替换此字符串所有匹配给定的正则表达式的子字符串 |
String replaceFirst(String regex, String replacement) | 使用给定的replacement 替换此字符串匹配给定的正则表达式的第一个子字符串 |
String[] split(String regex) | 根据给定正则表达式的匹配拆分此字符串 |
String[] split(String regex, int limit) | 根据匹配给定的正则表达式来拆分此字符串 |
boolean startsWith(String prefix) | 测试此字符串是否以指定的前缀开始 |
boolean startsWith(String prefix, int toffset) | 测试此字符串从指定索引开始的子字符串是否以指定前缀开始 |
CharSequence subSequence(int beginIndex, int endIndex) | 返回一个新的字符序列,它是此序列的一个子序列 |
String substring(int beginIndex) | 返回一个新的字符串,它是此字符串的一个子字符串,子字符串从指定的beginIndex 开始,直到此字符串的末尾 |
String substring(int beginIndex, int endIndex) | 返回一个新的字符串,它是此字符串的一个子字符串,子字符串从指定的beginIndex 开始,直到指定的endIndex 结束(不包括endIndex ) |
char[] toCharArray() | 将此字符串转换为一个新的字符数组 |
String toLowerCase() | 使用默认语言环境的规则将此String 中的所有字符都转换为小写 |
String toLowerCase(Locale locale) | 使用给定Locale 的规则将此String 中的所有字符都转换为小写 |
String toString() | 用于将对象转换为字符串表示形式 |
String toUpperCase() | 使用默认语言环境的规则将此String 中的所有字符都转换为大写 |
String toUpperCase(Locale locale) | 使用给定Locale 的规则将此String 中的所有字符都转换为大写 |
String trim() | 将字符串前后空格去除 |
static String valueOf(primitive data type x) | 用于将给定的基本数据类型参数x 转换为其字符串表示形式 |
contains(CharSequence chars) | 判断是否包含指定的字符系列 |
isEmpty() | 判断字符串是否为空 |
实现一个系统随机生成4位验证码,并允许用户从键盘输入一个不区分大小写的验证码进行判断的功能。代码示例如下:
public class Test4 {
public static void main(String[] args) {
String randCode = getCode(4);
System.out.println("验证码:" + randCode);
Scanner scanner = new Scanner(System.in);
System.out.print("请输入验证码:");
String userInput = scanner.next();
System.out.println(randCode.equalsIgnoreCase(userInput) ? "验证码输入正确" : "验证码输入错误");
}
public static String getCode(int length) {
String str = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
String code = "";
for (int i = 1; i <= length; i++) {
int index = (int) (Math.random() * str.length()); // 0-62之间的随机数
code = code + str.charAt(index);
}
return code;
}
}
🆚🆚运行结果:
验证码:6Zor
请输入验证码:6zor
验证码输入正确
实现一个方法来判断输入的字符串是否是有效的电子邮箱地址。代码示例如下:
public class Test5 {
public static boolean isValidEmail(String email) {
// 1. 检查是否为空或null
if (email == null || email.isEmpty()) {
return false;
}
// 2. 查找@符号
int atIndex = email.indexOf('@');
if (atIndex == -1) {
return false;
}
// 3. 检查@符号不是第一个或最后一个字符
if (atIndex == 0 || atIndex == email.length() - 1) {
return false;
}
// 4. 分割用户名和域名部分
String localPart = email.substring(0, atIndex);
String domainPart = email.substring(atIndex + 1);
// 5. 检查用户名部分
// 只包含字母、数字、点、下划线、连字符,且不以点开头或结尾
if (!isValidLocalPart(localPart)) {
return false;
}
// 6. 检查域名部分
// 包含至少一个点,并且点不能是第一个或最后一个字符
// 每个子域名只包含字母、数字或连字符,且不以连字符开头或结尾
if (!isValidDomainPart(domainPart)) {
return false;
}
// 7. 如果以上所有检查都通过,则认为是有效的电子邮件地址
return true;
}
private static boolean isValidLocalPart(String localPart) {
// 简化检查,只检查是否包含非法字符(如空格、特殊符号等)
// 这里可以根据需要添加更详细的检查
if (localPart.contains(" ") || !localPart.matches("^[a-zA-Z0-9_.+-]+$")) {
return false;
}
// 检查不以点开头或结尾
if (localPart.startsWith(".") || localPart.endsWith(".")) {
return false;
}
return true;
}
private static boolean isValidDomainPart(String domainPart) {
// 简化检查,只检查是否包含至少一个点,并且点不能是第一个或最后一个字符
// 这里可以根据需要添加更详细的检查,如子域名的长度限制等
if (!domainPart.contains(".") || domainPart.startsWith(".") || domainPart.endsWith(".")) {
return false;
}
// 分割子域名并检查每个子域名
String[] subdomains = domainPart.split("\\.");
for (String subdomain : subdomains) {
// 简化检查,只检查是否只包含字母、数字或连字符,且不以连字符开头或结尾
if (subdomain.isEmpty() || subdomain.startsWith("-") || subdomain.endsWith("-") || !subdomain.matches("^[a-zA-Z0-9-]+$")) {
return false;
}
}
return true;
}
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
while (true) {
System.out.print("请输入电子邮箱地址:");
String email = scanner.next();
boolean flag = isValidEmail(email);
if (flag) {
System.out.println("有效的电子邮箱");
break;
}
System.out.println("无效的电子邮箱");
}
}
}
🆚🆚运行结果:
请输入电子邮箱地址:example@gmail.com
有效的电子邮箱
2. StringBuffer和StringBuilder类
当对字符串进行修改的时候,需要使用
StringBuffer
和StringBuilder
类。和String
类不同的是,StringBuffer
和StringBuilder
都提供了多种方法来操作字符序列,如append()
、insert()
、delete()
、replace()
等,这些方法直接修改了对象的内容,而不是创建新的对象。
2.1 StringBuffer类
2.1.1 简介
StringBuffer
是一个线程安全的可变字符序列,可以在多线程环境中安全地使用。- 它继承自
AbstractStringBuilder
类,实现了CharSequence
接口。 - 由于其线程安全性,
StringBuffer
的所有公开方法都是同步的(使用synchronized
关键字修饰)。 - 初始时,
StringBuffer
通常会分配一个默认大小的内部字符数组(通常是16个字符)作为缓冲区。
2.1.2 构造方法
- new StringBuffer():创建一个空的
StringBuffer
对象,其初始容量为16
个字符。 - new StringBuffer(String str):使用指定的字符串
str
来初始化新的StringBuffer
对象,其初始容量至少为str.length() + 16
。 - new StringBuffer(int capacity):创建一个空的
StringBuffer
对象,并指定其初始容量。 - new StringBuffer(CharSequence seq):使用指定的
CharSequence
对象(如String
、StringBuffer
、StringBuilder
等)来初始化新的StringBuffer
对象,其初始容量至少为seq.length() + 16
。
2.2 StringBuilder类
2.2.1 简介
StringBuilder
是一个非线程安全的可变字符序列,更适合在单线程环境中使用。- 它同样继承自
AbstractStringBuilder
类,实现了CharSequence
、Appendable
和Serializable
接口。 - 与
StringBuffer
不同,StringBuilder
的方法没有被同步,因此在单线程环境下通常性能更高。 - 初始时,
StringBuilder
也会分配一个默认大小的内部字符数组作为缓冲区。
2.2.2 构造方法
- new StringBuilder():创建一个空的
StringBuilder
对象,其初始容量默认为16
个字符。 - new StringBuilder(CharSequence cs):创建一个包含指定
CharSequence
(如String
、StringBuffer
、StringBuilder
等)的字符序列的StringBuilder
对象,其初始容量设置为cs.length() + 16
。 - new StringBuilder(int initCapacity):创建一个具有指定初始容量
initCapacity
的StringBuilder
对象。 - new StringBuilder(String s):创建一个包含指定字符串
s
的字符序列的StringBuilder
对象。其初始容量设置为s.length() + 16
。
2.3 常用方法
方法 | 说明 |
---|---|
append(anyType value) | 用于将指定类型的数据(如String 、char 、int 、boolean 等)以及它们的数组(如String[] 、char[] 等)和其他Object 类型(通过调用其toString() 方法)追加到此字符序列的末尾 |
insert(int offset, anyType value) | 在指定的offset 处插入指定的数据 |
delete(int start, int end) | 移除此序列的子字符串中的字符,从start 到end - 1 的索引范围 |
deleteCharAt(int index) | 移除此对象中指定索引index 处的字符 |
replace(int start, int end, String str) | 使用给定字符串str 中的字符替换此字符序列的子字符串中的字符,子字符串从start 到end - 1 的索引范围 |
reverse() | 将此字符序列用其反转形式取代 |
length() | 返回当前对象的字符序列长度 |
indexOf(String str) | 用于查找字符串缓冲区中指定字符串首次出现的位置 |
lastIndexOf(String str) | 用于查找字符串缓冲区中指定字符串最后出现的位置 |
substring(int start, int end) | 用于获取从指定位置开始到结束位置的子字符串 |
setCharAt(int index, char ch) | 将给定索引index 处的字符设置为ch |
charAt(int index) | 用于获取指定位置的字符 |
toString() | 返回此序列中数据的字符串表示形式 |
capacity() | 返回当前StringBuffer 对象的容量,这个容量是StringBuffer 对象内部用于存储字符的数组的大小(StringBuffer 特有) |
3. Wrapper类(包装类)
3.1 简介
- 对象化操作:包装类(Wrapper Classes)将基本数据类型(Primitive Data Types)装成对象来操作。
- 类型转换:包装类提供了在基本数据类型和字符串之间进行转换的方法,如
Integer.parseInt(String s)
和Integer.toString(int i)
。 - 提供属性和方法:包装类中还包括了基本数据类型相关处理的属性和其他方法。
基本数据类型 | 包装类 |
---|---|
byte | Byte |
short | Short |
int | Integer |
long | Long |
float | Float |
double | Double |
char | Character |
boolean | Boolean |
3.2 常用方法
- XXX_VALUE:获取最大值和最小值,如
Integer.MAX_VALUE
和Integer.MIN_VALUE
。 - xxxValue():每种包装类都提供了将对象转换为对应基本数据类型的方法,如
doubleValue()
、floatValue()
、longValue()
、intValue()
、shortValue()
、byteValue()
、charValue()
。 - valueOf(Xxx x):将基本数据类型转换为对应的包装类对象。
Integer x = Integer.valueOf("123");
- parseXxx():将字符串转成基本数据类型。
String str = "123";
int x = parseInt(str);
- toString()、String.valueOf():将包装类对象转成字符串。
Integer x = 100;
String str1 = x.toString();
String str2 = String.valueOf(x);
- compare(T o1, T o2)、compareTo(T o):用于比较两个对象。返回负数、零或正数分别表示当前对象小于、等于或大于另一个对象。
- toBinaryString()、toOctalString()、toHexString():将整数转换为二进制、八进制或十六进制字符串表示。
- Character相关方法:
方法 | 描述 |
---|---|
isLetter() | 是否是一个字母 |
isDigit() | 是否是一个数字字符 |
isWhitespace() | 是否是一个空白字符 |
isUpperCase() | 是否是大写字母 |
isLowerCase() | 是否是小写字母 |
toUpperCase() | 指定字母的大写形式 |
toLowerCase() | 指定字母的小写形式 |
toString() | 返回字符的字符串形式,字符串的长度仅为1 |
📌注:
Integer
类有一个内部类IntegerCache
,这个缓存用于存储-128
到127
(包括两端)之间的整数对象。在此范围内,使用==
判断,会得到true
,超过此范围,返回为false
,应该使用equals
来判断值是否相等。
4. Math类
4.1 简介
Math
类是Java提供的一个用于执行基本数学运算的类,它包含了一系列用于数学计算的静态方法,比如计算绝对值、最大值、最小值、幂、平方根等。Math
类是final
修饰的,final
类不能被继承,也就是不能创建Math
类的子类。Math
类中的方法都是static
修饰的,可以通过类名.方法名
直接调用。
4.2 常用方法
方法 | 描述 |
---|---|
Math.abs(int a) | 返回参数的绝对值,可以处理多种数值类型(如int 、long 、float 、double 等) |
Math.ceil(double a) | 返回大于等于(>= )给定参数的最小整数,返回类型为double (双精度浮点型) |
Math.floor(double a) | 返回小于等于(<= )给定参数的最大整数,返回类型为double |
Math.rint(double a) | 返回与参数最接近的整数,但结果是double 类型,且是整数的精确表示 |
Math.round(float|double a) | 返回int 或long ,采用四舍五入法,获取最接近的整数值 |
Math.min(int a, int b) | 返回两个参数中的最小值,可以处理多种数值类型(如int 、long 、float 、double 等) |
Math.max(int a, int b) | 返回两个参数中的最大值,可以处理多种数值类型(如int 、long 、float 、double 等) |
Math.exp(double a) | 返回自然数底数e (约等于2.71828)的参数a 次方 |
Math.log(double a) | 返回参数的自然对数(以e 为底) |
Math.pow(double a, double b) | 方法返回参数a 的b 次方 |
Math.sqrt(double a) | 返回参数a 的算术平方根 |
Math.random() | 返回一个大于等于0.0 且小于1.0 的伪随机double 值 |
Math.sin(double a)/Math.cos(double a)/Math.tan(double a) | 返回给定弧度值的正弦、余弦和正切值 |
5. Random类
5.1 简介
java.util.Random
类在Java中是一个伪随机数生成器(PRNG,Pseudo-Random Number Generator)。这意味着它产生的数字序列在给定相同的种子(seed)时将是相同的。这种行为在可重复性和调试时是很有用的,但也可能在某些需要高度随机性或安全性的场景中造成问题。
5.2 构造方法
- new Random():当使用无参数的构造方法时,
Random
类会自动使用当前系统时间(通常是系统时间的某个部分,如毫秒数)作为种子值来初始化随机数生成器。 - new Random(long seed):可以自己来选定具体的种子值来构造
Random
对象。
5.3 常用方法
方法 | 描述 | 示例 |
---|---|---|
nextInt() | 返回int 类型的伪随机数 | Random random = new Random(); int randomInt = random.nextInt(); |
nextInt(int bound) | 返回0 (包含)到bound (不包含)之间的伪随机数 | int randomBoundedInt = random.nextInt(100); // 生成0到99之间的随机数 |
nextLong() | 返回long 类型的伪随机数 | long randomLong = random.nextLong(); |
nextFloat() | 返回一个伪随机单精度浮点数,范围在0.0 (包含)到1.0 (不包含)之间 | float randomFloat = random.nextFloat(); |
nextDouble() | 返回一个伪随机双精度浮点数,范围在0.0 (包含)到1.0 (不包含)之间 | double randomDouble = random.nextDouble(); |
nextBoolean() | 返回一个伪随机boolean 类型的值,true 或false 的概率相同 | boolean randomBoolean = random.nextBoolean(); |
6. BigInteger和BigDecimal类
6.1 简介
- BigInteger:用于支持任意精度的整数运算。整数可以是任意长度,只受限于可用内存的大小。通常用于需要处理非常大的整数的情况,如科学计算、密码学等领域。
- BigDecimal:用于支持任意精度的十进制数运算。由于
float
和double
类型是基于IEEE 754标准的二进制浮点数,它们无法精确表示所有的十进制数,因此在进行货币计算等需要高精度的场景时,使用BigDecimal
可以避免舍入误差。
6.2 创建方式
- BigInteger
- new BigInteger(String val):从字符串创建。
BigInteger bigInt = new BigInteger("1234567890");
- new BigInteger(String val, int radix):从字符串创建,指定进制。
BigInteger bigInt = new BigInteger("1A2B", 16); // 十六进制
- BigInteger.valueOf(long val):从
long
值创建。
BigInteger bigInt = BigInteger.valueOf(1234567890L);
- Scanner对象的nextBigInteger()方法:从输入流中读取。
Scanner scanner = new Scanner(System.in); BigInteger bigInt = scanner.nextBigInteger();
- BigDecimal
- new BigDecimal(String val):从字符串创建(推荐方式,因为可以避免精度问题)。
BigDecimal bigDecimal = new BigDecimal("123.456");
- new BigDecimal(BigInteger val): 从
BigInteger
值创建。
BigInteger bigInt = new BigInteger("1234567890"); BigDecimal bigDecimal = new BigDecimal(bigInt);
- new BigDecimal(BigInteger unscaledVal, int scale): 从
BigInteger
和一个小数点后的位数创建。
BigInteger unscaled = new BigInteger("1234567890"); int scale = 2; // 小数点后两位 BigDecimal bigDecimal = new BigDecimal(unscaled, scale); // 表示 1234567890.00
- BigDecimal.valueOf(double val):从
double
值创建。
BigDecimal bigDecimalSafe = BigDecimal.valueOf(123.456);
6.3 常用方法
- BigInteger
方法 | 描述 |
---|---|
BigInteger add(BigInteger val) | 加法 |
BigInteger subtract(BigInteger val) | 减法 |
BigInteger multiply(BigInteger val) | 乘法 |
BigInteger divide(BigInteger val) | 除法(只保留整数部分,余数会丢失) |
BigInteger remainder(BigInteger val) | 求余数 |
BigInteger[] divideAndRemainder(BigInteger val) | 同时返回除法的商和余数(作为BigInteger 数组) |
BigInteger max(BigInteger val) | 求大值 |
BigInteger min(BigInteger val) | 求小值 |
intValue(), longValue(), floatValue(), doubleValue() | 转换为基本数据类型(注意可能的溢出或精度损失) |
- BigDecimal
方法 | 描述 |
---|---|
BigDecimal add(BigDecimal augend) | 加法 |
BigDecimal subtract(BigDecimal subtrahend) | 减法 |
BigDecimal multiply(BigDecimal multiplicand) | 乘法 |
BigDecimal divide(BigDecimal divisor, int scale, int roundingMode) | 除法(需要指定小数点后的位数和舍入模式) |
BigDecimal remainder(BigDecimal divisor, int scale, int roundingMode) | 求余数(需要指定小数点后的位数和舍入模式) |
BigDecimal setScale(int newScale, int roundingMode) | 设置小数点后的位数和舍入模式 |
BigDecimal stripTrailingZeros() | 去除BigDecimal 值末尾的零 |
int compareTo(BigDecimal val) | 比较两个BigDecimal 对象 |
BigDecimal max(BigDecimal val) | 求大值 |
BigDecimal min(BigDecimal val) | 求小值 |
doubleValue(), floatValue(), longValue(), intValue(), shortValue(), byteValue() | 转换为基本数据类型(注意注意可能的精度损失、溢出和类型转换) |
6.4 RoundingMode处理方式
在BigDecimal
类中,RoundingMode
枚举类型定义了多种舍入处理方式,这些方式用于在数值运算中指定如何进行舍入。以下是RoundingMode
的各种处理方式:
- ROUND_UP:远离零方向舍入,即向绝对值最大的方向舍入。只要舍弃位非0即进位。示例:1.4舍入为2,-1.4舍入为-2。
- ROUND_DOWN:向零方向舍入,即直接截去需要舍入的部分(不进行进位)。示例:1.4舍入为1,-1.4舍入为-1。
- ROUND_CEILING:向正无限大方向舍入。如果结果为正,则行为类似于
ROUND_UP
;如果结果为负,则行为类似于ROUND_DOWN
。示例:1.4舍入为2,-1.4舍入为-1。 - ROUND_FLOOR:向负无限大方向舍入。如果结果为正,则行为类似于
ROUND_DOWN
;如果结果为负,则行为类似于ROUND_UP
。示例:1.4舍入为1,-1.4舍入为-2。 - ROUND_HALF_UP:四舍五入,即舍入部分大于等于0.5时进位,否则丢弃舍入部分。示例:1.5舍入为2,1.4舍入为1,-1.5舍入为-2,-1.4舍入为-1。
- ROUND_HALF_DOWN:五舍,即舍入部分大于0.5时进位,否则丢弃舍入部分。示例:1.5舍入为1,1.6舍入为2,-1.5舍入为-1,-1.6舍入为-2。
- ROUND_HALF_EVEN:银行家舍入法,向最接近数字方向舍入。如果与两个相邻数字的距离相等,则向相邻的偶数舍入。示例:1.5舍入为2(因为2是偶数),2.5舍入为2(因为需要舍去并且前一个数字是偶数),-1.5舍入为-2。
- ROUND_UNNECESSARY:用于断言请求的操作具有精确结果,因此不发生舍入。如果结果不精确,则抛出
ArithmeticException
。示例:在除法运算中,如果无法精确表示结果且使用了此舍入模式,则会抛出异常。
7. 日期和时间
7.1 Date类
java.util
包提供了Date
类来封装当前的日期和时间。Date
类提供两个构造函数来实例化Date
对象。
- new Date():当前系统日期和时间。
- new Date(long millisec):给定日期和时间。
Date
对象创建以后,可以调用以下常用的方法:
- long getTime( ):返回自1970年1月1日 00:00:00 GMT以来此
Date
对象表示的毫秒数。 - String toString():将此
Date
对象转换为一个字符串,其值是日期的日期-时间
表示形式。 - boolean after(Date date):若当调用此方法的
Date
对象在给定日期之后返回true
,否则返回false
。 - boolean before(Date date):若当调用此方法的
Date
对象在给定日期之前返回true
,否则返回false
。 - boolean equals(Object date):判断两个日期对象是否相等。
- int compareTo(Date date):比较两个日期的顺序。如果当前日期对象大于给定日期对象,返回正数;如果小于给定日期对象,返回负数;如果等于给定日期对象,返回零。
7.2 DateFormat类
java.text.DateFormat
是一个抽象类,用于日期和时间的格式化和解析。它不能直接实例化,但可以通过两种主要方式来获取其实例:
- 通过其提供的静态工厂方法来获取
DateFormat
的实例。 - 通过创建
SimpleDateFormat
子类对象,可以通过时间模式字符串来定义日期和时间的格式。
字母 | 描述 | 示例 |
---|---|---|
G | 纪元标记 | AD |
y | 年份 | 2024 |
M | 月份 | June or 06 |
d | 月份中的天数 | 26 |
E | 星期中的天数 | Wednesday |
H | 小时数(24小时) | 18 |
h | 小时数(12小时) | 6 |
m | 分钟数 | 30 |
s | 秒钟数 | 59 |
a | AM/PM 上午/下午标记 | PM |
S | 毫秒数 | 234 |
java.text.DateFormat
及其子类(如java.text.SimpleDateFormat
)提供了两个核心方法用于日期和时间的格式化和解析:
- format(Date date):用于将
Date
对象格式化为字符串。 - parse(String source):用于将字符串解析为
Date
对象。
代码示例如下:
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Locale;
public class Test1 {
public static void main(String[] args) {
// 1. 使用 DateFormat 的静态工厂方法
// 获取默认区域设置的日期实例
DateFormat dateInstance = DateFormat.getDateInstance();
Date date = new Date();
System.out.println("Date: " + dateInstance.format(date));
// 获取默认区域设置的时间实例
DateFormat timeInstance = DateFormat.getTimeInstance();
System.out.println("Time: " + timeInstance.format(date));
// 获取默认区域设置的日期和时间实例
DateFormat dateTimeInstance = DateFormat.getDateTimeInstance();
System.out.println("Date & Time: " + dateTimeInstance.format(date));
// 也可以指定区域设置和样式
DateFormat shortDateInstance = DateFormat.getDateInstance(DateFormat.SHORT, Locale.US);
System.out.println("Short Date (US): " + shortDateInstance.format(date));
// 2. 使用子类对象 SimpleDateFormat
// 创建 SimpleDateFormat 对象,指定日期和时间格式模式
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
// 获取当前日期/时间
Date date2 = new Date();
// 使用 SimpleDateFormat 对象来格式化日期/时间
String formattedDate = sdf.format(date2);
// 输出格式化后的日期/时间
System.out.println("Formatted Date: " + formattedDate);
// 尝试解析一个字符串到 Date 对象
try {
Date parsedDate = sdf.parse("2024-06-26 12:34:56");
System.out.println("Parsed Date: " + parsedDate);
} catch (Exception e) {
e.printStackTrace();
}
}
}
🆚🆚运行结果:
Date: 2024年6月26日
Time: 下午6:00:04
Date & Time: 2024年6月26日 下午6:00:04
Short Date (US): 6/26/24
Formatted Date: 2024-06-26 18:00:04
Parsed Date: Wed Jun 26 12:34:56 CST 2024
7.3 Calendar类
Calendar类是一个抽象类,它提供了处理日期和时间的功能,包括创建日期和时间、查询日期和时间的各个组成部分(年、月、日、小时、分钟等),以及修改日期和时间等。
常量 | 描述 |
---|---|
Calendar.YEAR | 年份 |
Calendar.MONTH | 月份 |
Calendar.DATE | 日期 |
Calendar.DAY_OF_MONTH | 日期 |
Calendar.HOUR | 12小时制的小时 |
Calendar.HOUR_OF_DAY | 24小时制的小时 |
Calendar.MINUTE | 分钟 |
Calendar.SECOND | 秒 |
Calendar.DAY_OF_WEEK | 星期几 |
Calendar类的主要方法包括:
- Calendar.getInstance():获取一个默认时区(通常是系统时区)和默认语言环境(通常是默认区域设置)的
Calendar
对象。 - int get(int field):返回给定日历字段的值。
- void set(int field, int value):将给定的日历字段设置为给定值。
- void add(int field, int amount):根据日历的规则,将指定的时间量添加到指定的日历字段中。
- Date getTime():返回一个表示此
Calendar
时间值(从历元至现在的毫秒偏移量)的Date
对象。 - void setTime(Date time):使用给定的
Date
设置此Calendar
的时间值。 - TimeZone getTimeZone():获取此
Calendar
的时区。 - void setTimeZone(TimeZone value):使用给定的时区值设置时区。
代码示例如下:
import java.util.Calendar;
public class Test2 {
public static void main(String[] args) {
// 获取Calendar实例
Calendar calendar = Calendar.getInstance();
// 打印当前日期和时间
System.out.println("Current Date and Time: " + calendar.getTime());
// 设置Calendar到特定的日期和时间(例如,2024年06月26日)
calendar.set(2024, Calendar.JUNE, 26, 0, 0, 0);
System.out.println("Set Date and Time: " + calendar.getTime());
// 添加一天
calendar.add(Calendar.DAY_OF_MONTH, 1);
System.out.println("After adding one day: " + calendar.getTime());
}
}
🆚🆚运行结果:
Current Date and Time: Wed Jun 26 18:00:30 CST 2024
Set Date and Time: Wed Jun 26 00:00:00 CST 2024
After adding one day: Thu Jun 27 00:00:00 CST 2024
7.4 GregorianCalendar类
Calendar
类实现了公历日历,GregorianCalendar
是Calendar
类的一个具体实现,它表示格里高利历(也称为公历或西历)。代码示例如下:
import java.util.Calendar;
import java.util.GregorianCalendar;
public class Test3 {
public static void main(String[] args) {
// 直接实例化 GregorianCalendar
GregorianCalendar gcalendar = new GregorianCalendar();
// 输出当前日期和时间
System.out.println("Current Date and Time (GregorianCalendar): " + gcalendar.getTime());
// 使用 Calendar.getInstance() 获取 GregorianCalendar 实例(默认行为)
Calendar calendar = Calendar.getInstance(); // 在大多数Java实现中,这将返回 GregorianCalendar 的实例
// 输出当前日期和时间
System.out.println("Current Date and Time (Calendar.getInstance()): " + calendar.getTime());
// 判断当前年份是否为闰年
boolean leapYear = gcalendar.isLeapYear(gcalendar.get(Calendar.YEAR));
System.out.println("leapYear = " + leapYear);
}
}
🆚🆚运行结果:
Current Date and Time (GregorianCalendar): Wed Jun 26 18:00:49 CST 2024
Current Date and Time (Calendar.getInstance()): Wed Jun 26 18:00:49 CST 2024
leapYear = true
📌注:
boolean isLeapYear(int year)
确定给定的年份是否为闰年。- 判断格里高利历中闰年的方法:四年一闰,百年不闰,四百年一大闰。 平年365天,闰年366天,年平均长度365天5小时49分12秒。
7.5 JDK8新增日期工具类
在Java 8(也称为JDK 8)中,引入了一个新的日期和时间API,它位于java.time
包下,用于替代旧的java.util.Date
和java.util.Calendar
类。这个新的API提供了更强大、更直观且线程安全的日期和时间操作。以下是Java 8中新增的一些主要的日期和时间工具类:
1、核心日期时间类
- LocalDate:用于表示一个日期,没有时间和时区信息。
LocalDate date = LocalDate.now();
LocalDate today = LocalDate.of(2024, Month.JUNE, 26);
- LocalTime:用于表示一天中的时间,没有日期和时区信息。
LocalTime time = LocalTime.of(12, 0);
- LocalDateTime:用于表示一个日期和时间,没有时区信息。
LocalDateTime dateTime = LocalDateTime.now();
2、时区相关类
- ZonedDateTime:用于表示一个日期、时间和时区。
ZonedDateTime zonedDateTime = ZonedDateTime.now();
- ZoneId:用于表示时区。
ZoneId systemDefaultZoneId = ZoneId.systemDefault();
ZoneId shanghaZoneId = ZoneId.of("Asia/Shanghai");
- OffsetDateTime:表示带有时区偏移量的日期和时间,例如UTC+8的日期和时间。
OffsetDateTime nowWithOffset = OffsetDateTime.now(ZoneOffset.ofHours(8));
3、时间间隔与周期类
- Instant:代表的是时间戳,用于表示时间线上的一个瞬时点。
Instant instant = Instant.now();
- Period:计算两个“日期”之间的间隔。
Period period = Period.between(startDate, endDate);
- Duration:计算两个“时间”之间的间隔。
Duration duration = Duration.between(startTime, endTime);
4、时间格式化和解析类
- DateTimeFormatter:用于做时间的格式化和解析。
LocalDateTime now = LocalDateTime.now();
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
String formattedDateTime = now.format(formatter);
String dateTimeString = "2024-06-26 00:00:00";
LocalDateTime dateTime = LocalDateTime.parse(dateTimeString, formatter);
5、时间单位与时间量类
- ChronoUnit:枚举类,提供了日期和时间字段的单位,如天(DAYS)、小时(HOURS)等,用于时间计算。
LocalDate startDate = LocalDate.of(2024, 6, 1);
LocalDate endDate = LocalDate.of(2024, 6, 26);
long daysBetween = ChronoUnit.DAYS.between(startDate, endDate);
- TemporalAmount:表示一个时间量,主要实现类是
Period
和Duration
。
6、其他辅助类
- TemporalAdjusters:时间调节器,例如“下一个月的第一天”或“下周的星期一”。
LocalDate firstDayOfNextMonth = LocalDate.now().with(TemporalAdjusters.firstDayOfNextMonth()); // 下一个月的第一天
LocalDate nextDayOfNextMonth = LocalDate.now().with(TemporalAdjusters.next(DayOfWeek.MONDAY)); // 下周的星期一
- Clock:用于访问当前日期和时间,可以替代
System.currentTimeMillis()
或System.nanoTime()
。
Clock defaultClock = Clock.systemDefaultZone();
Instant instant = Instant.now(defaultClock);
- Year、Month、YearMonth、MonthDay等:这些类分别表示年、月、年和月组合、月和日组合等更细分的日期时间信息。
YearMonth yearMonth = YearMonth.of(2024, Month.JUNE);
MonthDay monthDay = MonthDay.of(Month.JUNE, 26);
8. 正则表达式
8.1 简介
正则表达式(Regular Expression)定义了字符串的模式,可以用来搜索、编辑或处理文本。给定一个正则表达式和另一个字符串,我们可以达到如下的目的:
- 判断给定的字符串是否符合正则表达式的过滤逻辑(称作“匹配”)。
- 可以通过正则表达式,从字符串中获取我们想要的特定部分。
正则表达式由一些普通字符和一些元字符(metacharacters)组成。以下是一些常用的正则表达式和元字符的示例:
字符 | 描述 |
---|---|
\ | 将下一个字符标记为或特殊字符、或原义字符、或向后引用、或八进制转义符。例如,n 匹配字符 n 。\n 匹配换行符。序列\\ 匹配\ ,而\( 则匹配( 。 |
^ | 匹配输入字符串的开始位置。如果设置了RegExp 对象的Multiline 属性,^ 也匹配\n 或\r 之后的位置。 |
$ | 匹配输入字符串的结束位置。如果设置了RegExp 对象的Multiline 属性,$ 也匹配\n 或\r 之前的位置。 |
( ) | 标记一个子表达式(也称为捕获组)的开始和结束位置。子表达式可以获取供以后使用。要匹配这些字符,请使用\( 和 \) 。例如,\(([^)]*)\) 会匹配任何被括号包围的内容(不包括括号本身),其中[^)]* 是一个字符类。 |
* | 匹配前面的子表达式零次或多次。例如,zo* 能匹配z 以及zoo ,* 等价于{0,} 。 |
+ | 匹配前面的子表达式一次或多次。例如,zo+ 能匹配zo 以及zoo ,但不能匹配z ,+ 等价于{1,} 。 |
? | 匹配前面的子表达式零次或一次。例如,zo? 能匹配z 以及zo ,但不能匹配zoo ,? 等价于{0,1} 。 |
. | 匹配除换行符(\n 、\r )之外的任何单个字符。 |
{n} | n 是一个非负整数,匹配确定的n 次。例如,o{2} 不能匹配Bob 中的o ,但是能匹配food 中的两个o 。 |
{n,} | n 是一个非负整数,至少匹配n 次。例如,o{2,} 不能匹配Bob 中的o ,但能匹配foooood 中的所有o 。 |
{n,m} | m 和n 均为非负整数,其中n<=m 。最少匹配n 次且最多匹配m 次。例如,o{2,5} 将匹配fooooood 中的前五个o 。 |
\b | 匹配一个单词边界,也就是指单词和空格间的位置。例如,er\b 可以匹配never 中的er ,但不能匹配verb 中的er 。 |
\B | 匹配非单词边界的位置。例如,er\B 能匹配verb 中的er ,但不能匹配never 中的er 。 |
\d | 匹配一个数字字符,等价于[0-9] 。 |
\D | 匹配一个非数字字符,等价于[^0-9] 。 |
\s | 匹配任何空白字符,包括空格、制表符、换页符等等,等价于[ \f\n\r\t\v] 。 |
\S | 匹配任何非空白字符,等价于[^ \f\n\r\t\v] 。 |
\w | 匹配字母、数字、下划线,等价于[A-Za-z0-9_] 。 |
\W | 匹配非字母、非数字、非下划线,等价于[^A-Za-z0-9_] 。 |
x|y | 匹配x 或y 。例如,z|food 匹配z 或food 。(z|f)ood 匹配zood 或food 。 |
[xyz] | 字符集。匹配包含的任一字符。例如,[abc] 匹配plain 中的a 。 |
[^xyz] | 反向字符集。匹配未包含的任何字符。例如,[^abc] 匹配plain 中p ,l ,i ,n 。 |
[a-z] | 字符范围。匹配指定范围内的任何字符。例如,[a-z] 匹配a 到z 范围内的任何小写字母。 |
[^a-z] | 反向范围字符。匹配不在指定的范围内的任何字符。例如,[^a-z] 匹配任何不在a 到z 范围内的任何字符。 |
8.2 java.util.regex包
java.util.regex
包在Java中用于处理正则表达式,并且包含了Pattern
、Matcher
和 PatternSyntaxException
这三个主要类和异常。
- Pattern类:用于编译正则表达式并创建一个匹配模式。它没有公共的构造方法,因此需要使用其静态的
compile()
方法来创建一个Pattern
对象。compile()
方法接受一个字符串参数,该字符串表示要编译的正则表达式。
Pattern pattern = Pattern.compile("\\d+"); // 匹配一个或多个数字
- Matcher类:用于对输入字符串执行正则表达式匹配操作。它也没有公共构造方法,需要通过调用
Pattern
对象的matcher()
方法来获得Matcher
对象。
Matcher matcher = pattern.matcher("There are 123 apples and 456 oranges.");
while (matcher.find()) {
System.out.println(matcher.group()); // 输出匹配的数字
}
- PatternSyntaxException:
PatternSyntaxException
是一个在正则表达式模式字符串中出现语法错误时抛出的非强制异常。
try {
Pattern.compile("[a-z]+("); // 缺少闭合的右括号
} catch (PatternSyntaxException e) {
System.err.println("正则表达式语法错误:" + e.getMessage());
}
8.3 常用方法
8.3.1 Matcher类的方法
- 索引方法:索引方法提供了有用的索引值,精确表明输入字符串中在哪能找到匹配。
方法 | 说明 |
---|---|
public int start() | 返回以前匹配的初始索引 |
public int start(int group) | 返回在以前的匹配操作期间,由给定组所捕获的子序列的初始索引 |
public int end() | 返回最后匹配字符之后的偏移量 |
public int end(int group) | 返回在以前的匹配操作期间,由给定组所捕获子序列的最后字符之后的偏移量 |
- 查找方法:查找方法用来检查输入字符串并返回一个布尔值,表示是否找到该模式。
方法 | 说明 |
---|---|
public boolean lookingAt() | 尝试将从区域开头开始的子序列与模式匹配 |
public boolean find() | 尝试查找与模式匹配的下一个子序列 |
public boolean find(int start) | 重置此匹配器,然后尝试查找匹配该模式、从指定索引开始的输入序列的下一个子序列 |
matches() | 尝试将整个区域与模式匹配 |
- 替换方法:替换方法是替换输入字符串里文本的方法。
方法 | 说明 |
---|---|
public String replaceFirst(String replacement) | 替换第一个匹配项 |
public String replaceAll(String replacement) | 替换所有匹配项 |
public Matcher appendReplacement(StringBuffer sb, String replacement) | 实现非终端添加和替换步骤 |
public StringBuffer appendTail(StringBuffer sb) | 实现终端添加和替换步骤 |
public static String quoteReplacement(String s) | 返回指定字符串的字面替换字符串,这个方法返回一个字符串,就像传递给Matcher 类的appendReplacement 方法一个字面字符串一样工作 |
8.3.2 PatternSyntaxException类的方法
方法 | 说明 |
---|---|
public String getDescription() | 获取错误的描述 |
public int getIndex() | 获取错误的索引 |
public String getPattern() | 获取错误的正则表达式模式 |
public String getMessage() | 返回多行字符串,包含语法错误及其索引的描述、错误的正则表达式模式和模式中错误索引的可视化指示 |
✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨
以上内容是关于Java常用类的基础知识,希望对初学者或再次学习者有所帮助,基础打扎实,不怕风吹雨打!如果以上内容有错误或者内容不全,望大家提出!我也会继续写好每一篇博文!
👍👍👍
待续未完
🙊🙊🙊
欢迎观看和提问!!!
👏👏👏