Java核心类
String类
new String()
:构造函数new String(String original)
:根据源String
构造新String
new String(StringBuilder builder)
new String(StringBuffer buffer)
new String(char[] value[, int offset, int count])
: 根据字符数组构造String
String.length()
: 返回字符串长度String.hashCode()
String.equals(Object anObject)
String.equalsIgnoreCase(String anotherString)
: 忽略大小写比较String.contains(CharSequence s)
: 内容判断String.indexOf(String str, [int fromIndex])
: 内容搜索String.lastIndexOf(String str, [int fromIndex])
: 反向搜索String.startsWith(String prefix, [int toffset])
: 前缀判断String.endsWith(String prefix)
: 后缀判断String.substring(int beginIndex, [int endIndex])
: 截取字串String.trim()
: 去除首尾空白字符(包含中文空格)String.strip()
: 去除首尾空白字符(不包含中文)String.stripLeading()
: 去头String.stripTrailing()
: 去尾String.replace(CharSequence target, CharSequence replacement)
: 字符串/序列替换String.replace(char oldChar, char newChar)
: 字符替换String.replaceAll(String regex, String replacement)
: 使用正则表达式替换所有String.replaceFirst(String regex, String replacement)
: 使用正则表达式替换第一个匹配子串String.split(String regex[, int limit])
: 正则表达式分割String.toUpperCase()
String.toCharArray()
String.charAt(int index)
: 获取索引位置的字符String.getBytes()
: 获取字符串的字节数组(可传入指定字符串编码)String.valueOf(any)
: 获取字符串表示(静态方法)String.join(CharSequence delimiter, CharSequence... elements)
: 连接字符串(静态方法)String.join(CharSequence delimiter, Iterable<? extends CharSequence> elements)
StringBuilder类
StringBuilder
, 可变对象,可以预分配缓冲区,
StringBuilder
方法返回自身,可以进行链式操作
StringBuffer
是StringBuilder
的线程安全版本, 使用了同步关键字synchronized
, 二者接口完全一致
new StringBuilder()
new StringBuilder(CharSequence seq)
: 初始内容new StringBuilder(int capacity)
: 初始容量new StringBuilder(String str)
: 初始内容StringBuilder.append(any)
: 添加内容StringBuilder.capacity()
: 获取容量StringBuilder.charAt(int index)
: 获取索引位置字符StringBuilder.insert(int dstOffset, CharSequence s[, int start, int end])
: 在指定位置插入序列StringBuilder.insert(int index, char[] str, int offset, int length)
: 插入字符数组StringBuilder.insert(int offset, anyOther)
: 插入其它对象StringBuilder.delete(int start, int end)
: 删除指定位置内容StringBuilder.deleteCharAt(int index)
: 删除指定字符StringBuilder.toString()
: 输出为String
StringJoiner类
对StringBuilder
的封装
new StringJoiner(CharSequence delimiter[, CharSequence prefix, CharSequence suffix])
: 构造对象指定连接符, 可加入前缀和后缀StringJoiner.add(CharSequence newElement)
: 添加内容, 自动连接StringJoiner.merge(StringJoiner other)
: 合并其它的StringJoiner
StringJoiner.toString()
: 输出为String
包装类型
JVM自动装箱拆箱, 但效率低
- bollean: java.lang.Boolean
- byte: java.lang.Byte
- short: java.lang.Short
- int: java.lang.Integer
- long: java.lang.Long
- float: java.lang.Float
- double: java.lang.Double
- char: java.lang.Character
- 包装类都是继承自
Number
类 - 所有包装类型都是不变类, 一旦创建就不可变
- 譬如
Integer.valueOf()
为静态工厂方法 - 我们把能创建“新”对象的静态方法称为静态工厂方法, 它尽可能地返回缓存的实例以节省内存。
- 创建新对象时,优先选用静态工厂方法而不是
new
操作符。
Integer类
var n1 = new Integer(10); // 不推荐, 编译警告, 因为没有利用工厂方法的缓存优势
var n2 = Integer.valueOf(100);
var n3 = Integer.valueOf("100");
int x = n3.intValue();
Integer n4 = 1000; // Auto Boxing 自动装箱
int y = n4; // Auto Unboxing 自动拆箱
/* 注意: 自动装箱和自动拆箱只发生在编译阶段,目的是为了少写代码。
装箱和拆箱会影响代码的执行效率,因为编译后的class代码是严格区分基本类型和引用类型的。
并且,自动拆箱执行时可能会报NullPointerException
*/
n2.equals(n3); // 对象相等使用equals方法
// 格式转换
Integer.parseInt("100"); // 默认10进制
integer.parseInt("100", 16); // 16进制
Integer.toString(100); // 10进制输出字符串"100"
Integer.toString(100, 36); // 36进制"2s"
Integer.toHexString(100); // 16进制"64"
Integer.toOctalString(100); // 8进制"144"
Integer.toBinaryString(100); // 2进制"1100100"
// 静态常量
Boolean.TRUE; // true
Boolean.FALSE; // false
Integer.MAX_VALUE; // 2147483647
Integer.MIN_VALUE; // -2147483648
Long.SIZE; // 64
Long.BYTES; // 8
// Number类型
Number n = new Integer(999);
byte b = n.byteValue(); // -25
int i = n.intValue(); // 999
long l = n.longValue(); // 999
float f = n.floatValue(); // 999.0
double d = n.doubleValue(); // 999.0
// 处理无符号整型
Byte.toUnsignedInt(-1); // 255
// 低位整型可以转换成int或long无符号整数
枚举类型enum
public class Main {
public static void main(String[] args) {
Weekday day = Weekday.SUN;
if (day == Weekday.SAT || day == Weekday.SUN) {
System.out.println("Work at home!");
} else {
System.out.println("Work at office!");
}
}
}
enum Weekday {
SUN, MON, TUE, WED, THU, FRI, SAT;
}
enum
常量本身带有类型信息, 编译器会自动检查出类型错误- 枚举类型不可能引用到非枚举的值, 因为无法通过编译
- 不同类型的枚举不能互相比较或者赋值, 因为类型不符
enum
类型可以使用==
比较, 简化equals
enum
定义的类型就是class
:- 定义的
enum
类型总是继承自java.lang.Enum
, 且无法被继承 - 只能定义出
enum的
实例,而无法通过new
操作符创建enum的实例 - 定义的每个实例都是引用类型的唯一实例
- 可以将
enum
类型用于switch
语句 enum
的toString()
方法默认与name()
输出一致, 可以重写, 但name()
不可以重写
- 定义的
enum
实例方法:- name() 返回常量名
- ordinal() 返回定义的常量顺序
- ordinal()返回结果与枚举常量定义的顺序有关, 如果不小心修改了枚举的顺序, 编译器是无法检查出这种逻辑错误的。可以定义private的构造方法, 给每个枚举常量添加字段:
public class Main {
public static void main(String[] args) {
Weekday day = Weekday.SUN;
if (day.dayValue == 6 || day.dayValue == 0) {
System.out.println("Work at home!");
} else {
System.out.println("Work at office!");
}
}
}
enum Weekday {
MON(1), TUE(2), WED(3), THU(4), FRI(5), SAT(6), SUN(0);
public final int dayValue;
// 字段可以是非final, 即运行中可以更改, 但不建议这样做
private Weekday(int dayValue) {
this.dayValue = dayValue;
}
}
BigInteger类
BigInteger
内部用一个int[]
数组通过软件模拟大整数- 对
BigInteger
做运算时,只能使用实例方法 BigInteger
继承自Number
, 属于不变类, 可以使用数据转换方法- 加减乘除取模乘方取素数…
var bi = new BigInteger("12432412412");
var bi2 = new BigInteger("42142124124512124");
BigInteger sum = bi.add(bi2);
long l = bi.longValue();
// 转换为long类型, 溢出会丢失高位信息
float f = bi.floatValue();
// 溢出结果为Infinite
int i = bi.intValueExact();
long l2 = bi.longValueExact();
// 溢出会抛出ArithmeticException, 从而捕获异常可以保证结果准确
BigDecimal类
-
和
BigInteger
类似,BigDecimal
可以表示一个任意大小且精度完全准确的浮点数。 -
BigDecimal.scale()
// 小数点位数, 如果返回负数, 表示为正数且低位有多少位0 -
BigDecimal.stripTrailingZeros()
// 去除小数末尾的0 -
BigDecimal.setScale(n, RoundingMode.HALF_UP)
// 四舍五入到n位 -
BigDecimal.setScale(n, RoundingMode.DOWN)
// 直接截断到n位 -
对
BigDecimal
做加、减、乘时,精度不会丢失,但是做除法时,存在无法除尽的情况,这时,就必须指定精度以及如何进行截断:BigDecimal d1 = new BigDecimal("3.456"); BigDecimal d2 = new BigDecimal("3.456789"); BigDecimal d3 = d1.divide(d2, 10, RoundingMode.HALF_UP); // 保留10位小数并四舍五入 BigDecimal d4 = d1.divide(d2); // 报错:ArithmeticException,因为除不尽
-
除法求余
BigDecimal n = new BigDecimal("12.345");
BigDecimal m = new BigDecimal("0.12");
BigDecimal[] dr = n.divideAndRemainder(m);
System.out.println(dr[0]); // 商102
System.out.println(dr[1]); // 余0.105
dr[1].signum() == 0; // 判断余是否为0
// signum为数位标志,可以表示负/零/正
- 比较BigDecimal
equals()
方法不但要求两个BigDecimal
的值相等,还要求它们的scale()
相等- 必须使用
compareTo()
方法来比较,它根据两个值的大小分别返回负数、正数和0,分别表示小于、大于和等于
BigDecimal
是通过一个BigInteger
和一个scale
来表示的,即BigInteger
表示一个完整的整数,而scale
表示小数位数
常用工具类
Math
Math.abs(x)
Math.max(x, y)
Math.min(x, y)
Math.pow(x, y)
Math.sqrt(x)
Math.exp(x)
Math.log(x)
Math.log10(x)
Math.sin(x)
Math.cos(x)
Math.tan(x)
Math.asin(x)
:arcsin函数Math.acos(x)
:arccos函数Math.PI
Math.E
Math.random()
Math.random()
实际上内部调用了Random
类的无参构造, 无法指定种子
18.Math
会尽量针对平台优化计算速度,StrictMath
保证所有平台(浮点数)计算结果都是完全相同的
Random
Random r = new Random(); // 可以指定随机种子
r.nextInt(); // 2071575453,每次都不一样
r.nextInt(10); // 5,生成一个[0,10)之间的int
r.nextLong(); // 8811649292570369305,每次都不一样
r.nextFloat(); // 0.54335...生成一个[0,1)之间的float
r.nextDouble(); // 0.3716...生成一个[0,1)之间的double
SecureRandom
SecureRandom
是用来创建安全的随机数SecureRandom
无法指定种子SecureRandom
的安全性是通过操作系统提供的安全的随机种子来生成随机数。这个种子是通过CPU的热噪声、读写磁盘的字节、网络流量等各种随机事件产生的“熵”。
import java.util.Arrays;
import java.security.SecureRandom;
import java.security.NoSuchAlgorithmException;
public class Main {
public static void main(String[] args) {
SecureRandom sr = null;
try {
sr = SecureRandom.getInstanceStrong();
// 获取高强度安全随机数生成器
} catch (NoSuchAlgorithmException e) {
sr = new SecureRandom();
// 获取普通的安全随机数生成器
}
byte[] buffer = new byte[16];
sr.nextBytes(buffer);
// 用安全随机数填充buffer
System.out.println(Arrays.toString(buffer));
}
}