字符串和编码
- String是一个引用类型,本身也是一个class
- String内部是通过一个char[]数组来表示
- 比较字符串时,必须用equals()而不能用==
- String类还提供了多种方法搜索子串、提取子串
- contain() indexOf() startsWith() endsWith() substring() trim() isEmpty() replace()
- UTF-8编码的另一个好处是容错能力强。如果传输过程中某些字符出错,不会影响后续字符,因为UTF-8编码依靠高字节位来确定一个字符究竟是几个字节,它经常用来作为传输编码
- GBK编码和utf-8编码
StringBuilder
- String每次都要创建新的字符串对象,然后扔掉旧的,会浪费内存,影响GC效率
- Java标准库提供了StringBuilder,它是一个可变对象,可以预分配缓冲区,这样,往StringBuilder中新增字符时,不会创建新的临时对象
public class Main {
public static void main(String[] args) {
var sb = new StringBuilder(1024);
sb.append("Mr ")
.append("Bob")
.append("!")
.insert(0, "Hello, ");
System.out.println(sb.toString());
}
}//MrBob!
还有一个StringBuffer,它和StringBuilder相比,通过同步保证了线程安全,缺点是执行速度下降。
包装类型
- 基本类型 byte,short,int,long,boolean,float,double,char
- 引用类型 class,interface
- 引用类型可以赋值为null,基本类型不能为null
- 比如int的引用类型Integer,char引用类型Character
JavaBean
- JavaBean主要用来传递数据,即把一组数据组合成一个JavaBean便于传输。此外,JavaBean可以方便地被IDE工具分析,生成读写属性的代码,主要用在图形界面的可视化设计中
枚举类
- enum 让某个值在枚举的集合内
- 定义的enum类型总是继承自java.lang.Enum,且无法被继承
- 只能定义出enum的实例,而无法通过new操作符创建enum的实例
- 可以将enum类型用于switch语句
- enum可以用==比较
public enum Weekday {
SUN, MON, TUE, WED, THU, FRI, SAT;
}
public class helloword {
public static void main(String[] args) {
Weekday day = Weekday.SUN;
switch(day) {
case MON:
case TUE:
case WED:
case THU:
case FRI:
System.out.println("Today is " + day + ". Work at office!");
break;
case SAT:
case SUN:
System.out.println("Today is " + day + ". Work at home!");
break;
default:
throw new RuntimeException("cannot process " + day);
}
}
}
enum Weekday {
MON, TUE, WED, THU, FRI, SAT, SUN;
}
BigInteger
- long是64位整数
- java.math.BigInteger表示任意大小的整数,用int[]来模拟一个非常大的整数
BigInteger bi = new BigInteger("1234567890");
System.out.println(bi.pow(5)); // 2867971860299718107233761438093672048294900000
- add() BigInteger sum = i1.add(i2);
- 可以把BigInteger转换成基本类型,如果BigInteger表示范围超过了基本类型的范围,转换时将丢失高位信息,即结果不一定是准确的
- BigInteger是不变类,并且继承自Number
BigDecimal
- BigDecimal可以表示一个任意大小而且精度完全准确的浮点数
BigDecimal d1 = new BigDecimal("123.45");
BigDecimal d2 = new BigDecimal("123.4500");
BigDecimal d3 = new BigDecimal("1234500");
System.out.println(d1.scale()); // 2,两位小数
System.out.println(d2.scale()); // 4
System.out.println(d3.scale()); // 0
- scale()表示小数位数
- 如果一个BigDecimal的scale()返回负数,例如,-2,表示这个数是个整数,并且末尾有2个0
public class Main {
public static void main(String[] args) {
BigDecimal d1 = new BigDecimal("123.456789");
BigDecimal d2 = d1.setScale(4, RoundingMode.HALF_UP); // 四舍五入,123.4568
BigDecimal d3 = d1.setScale(4, RoundingMode.DOWN); // 直接截断,123.4567
System.out.println(d2);
System.out.println(d3);
}
}
- 对BigDecimal做加、减、乘时,精度不会丢失,但是做除法时,存在无法除尽的情况,这时,就必须指定精度以及如何进行截断
- 在比较两个BigDecimal的值是否相等时,要特别注意,使用equals()方法不但要求两个BigDecimal的值相等,还要求它们的scale()相等
- 必须使用compareTo()方法来比较,它根据两个值的大小分别返回负数、正数和0,分别表示小于、大于和等于
常用工具类
- Math
- abs绝对值,max,min,pow,sqrt开方,exp
- random 是[0,1)之间
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
- 如果不给随机种子,就使用系统当前的时间戳作为种子,每次运行随机序列不一样,给了种子就会得到完全确定的随机数序列
import java.util.Random;
public class Main {
public static void main(String[] args) {
Random r = new Random(12345);
for (int i = 0; i < 10; i++) {
System.out.println(r.nextInt(100));
}
// 51, 80, 41, 28, 55...
}
}
- 在密码学中,安全的随机数非常重要。如果使用不安全的伪随机数,所有加密体系都将被攻破。因此,时刻牢记必须使用SecureRandom来产生安全的随机数
- Math:数学计算
- Random:生成伪随机数
- SecureRandom:生成安全的随机数