String
字符串在String内部是通过一个char[]数组表示的
String s2 = new String(new char[] {'H', 'e', 'l', 'l', 'o', '!'});
各类函数的使用可参考官方文档
String和char[]类型可以互相转换,方法是:
char[] cs = "Hello".toCharArray(); //String -> char[]
String s = new String(cs); //char[] -> String
StringBuilder
虽然String可以直接拼接字符串。但是,在循环中,每次循环都会创建新的字符串对象,然后扔掉旧的字符串。这样,绝大部分字符串都是临时对象,不但浪费内存,还会影响GC效率。
StringBuilder,它是一个可变对象,可以预分配缓冲区,这样,往StringBuilder中新增字符时,不会创建新的临时对象
StringBuilder sb = new StringBuilder(1024);for (int i = 0; i < 1000; i++) {
sb.append(',');
sb.append(i);
}
String s= sb.toString();
并且StringBuilder支持链式操作:
var sb = new StringBuilder(1024);
sb.append("Mr ")
.append("Bob")
.append("!")
.insert(0, "Hello, ");
StringBuffer,这是Java早期的一个StringBuilder的线程安全版本,它通过同步来保证多个线程操作StringBuffer也是安全的,但是同步会带来执行速度的下降。
包装类
Java核心库为每种基本类型都提供了对应的包装类型:boolean Boolean; type Type; short Short; int Integer; long Long; float Float; double Double; char Character。
int i = 100;
Integer n=Integer.valueOf(i);int x =n.intValue();
Integer n= 100; //编译器自动使用Integer.valueOf(int)
int x = n; //编译器自动使用Integer.intValue()
Integer n= null;int i = n; //报错 基本类型不允许为null
所有的包装类型都是不变类。我们查看Integer的源码可知,它的核心代码如下:
public final classInteger {private final intvalue;
}
Enum
通过枚举定义的类和class定义的类没有任何区别。enum定义的类型就是class,只不过它有以下几个特点:
定义的enum类型总是继承自java.lang.Enum,且无法被继承;
只能定义出enum的实例,而无法通过new操作符创建enum的实例;
定义的每个实例都是引用类型的唯一实例;
可以将enum类型用于switch语句。
enumWeekday {
SUN, MON, TUE, WED, THU, FRI, SAT;
}
Weekday day=Weekday.SUN;
day== Weekday.SAT || day == Weekday.SUN //true
如果枚举包含数字和中文可以如下定义和使用:
public classMain {public static voidmain(String[] args) {
Weekday day=Weekday.SUN;if (day.dayValue == 6 || day.dayValue == 0) {
System.out.println("Today is " + day + ". Work at home!");
}else{
System.out.println("Today is " + day + ". Work at office!");
}
}
}enumWeekday {
MON(1, "星期一"), TUE(2, "星期二"), WED(3, "星期三"), THU(4, "星期四"), FRI(5, "星期五"), SAT(6, "星期六"), SUN(0, "星期日");public final intdayValue;private finalString chinese;private Weekday(intdayValue, String chinese) {this.dayValue =dayValue;this.chinese =chinese;
}
@OverridepublicString toString() {return this.chinese;
}
}
BigInteger
表示任意大小的整数。BigInteger内部用一个int[]数组来模拟一个非常大的整数;从Number继承
BigInteger bi = new BigInteger("1234567890");
System.out.println(bi.pow(5)); //2867971860299718107233761438093672048294900000
对BigInteger做运算的时候,只能使用实例方法,例如,加法运算:
BigInteger i1 = new BigInteger("1234567890");
BigInteger i2= new BigInteger("12345678901234567890");
BigInteger sum= i1.add(i2); //12345678902469135780
BigDecimal
和BigInteger类似,BigDecimal可以表示一个任意大小且精度完全准确的浮点数。也是继承至Number
BigDecimal用scale()表示小数位数,例如:
BigDecimal d1 = new BigDecimal("123.45");
System.out.println(d1.scale());//2,两位小数
通过BigDecimal的stripTrailingZeros()方法,可以将一个BigDecimal格式化为一个相等的,但去掉了末尾0的BigDecimal:
BigDecimal d1 = new BigDecimal("123.4500");
BigDecimal d2= d1.stripTrailingZeros(); //123.45
可以对一个BigDecimal设置它的scale setscale(),如果精度比原始值低,那么按照指定的方法进行四舍五入或者直接截断:
BigDecimal d1 = new BigDecimal("123.456789");
BigDecimal d2= d1.setScale(4, RoundingMode.HALF_UP); //四舍五入,123.4568
对BigDecimal做加、减、乘时,精度不会丢失,但是做除法时,存在无法除尽的情况,这时,就必须指定精度以及如何进行截断:
BigDecimal d1 = new BigDecimal("123.456");
BigDecimal d2= new BigDecimal("23.456789");
BigDecimal d3= d1.divide(d2, 10, RoundingMode.HALF_UP); //保留10位小数并四舍五入
BigDecimal d4 = d1.divide(d2); //报错:ArithmeticException,因为除不尽
BigDecimal做除法的同时求余数; 调用divideAndRemainder()方法时,返回的数组包含两个BigDecimal,分别是商和余数,其中商总是整数,余数不会大于除数。我们可以利用这个方法判断两个BigDecimal是否是整数倍数:
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
在比较两个BigDecimal的值是否相等时,要特别注意,使用equals()方法不但要求两个BigDecimal的值相等,还要求它们的scale()相等:
BigDecimal d1 = new BigDecimal("123.456");
BigDecimal d2= new BigDecimal("123.45600");
System.out.println(d1.equals(d2));//false,因为scale不同
System.out.println(d1.equals(d2.stripTrailingZeros())); //true,因为d2去除尾部0后scale变为2
System.out.println(d1.compareTo(d2)); //0
必须使用compareTo()方法来比较,它根据两个值的大小分别返回负数、正数和0,分别表示小于、大于和等于。
如果查看BigDecimal的源码,可以发现,实际上一个BigDecimal是通过一个BigInteger和一个scale来表示的,即BigInteger表示一个完整的整数,而scale表示小数位数:
public class BigDecimal extends Number implements Comparable{private finalBigInteger intVal;private final intscale;
}
Math
Math类就是用来进行数学计算的,它提供了大量的静态方法来便于我们实现数学计算
Random
Random用来创建伪随机数。所谓伪随机数,是指只要给定一个初始的种子,产生的随机数序列是完全一样的。
创建Random实例时,如果不给定种子,就使用系统当前时间戳作为种子,因此每次运行时,种子不同,得到的伪随机数序列就不同
SecureRandom
用来创建安全的随机数,SecureRandom无法指定种子,它使用RNG(random number generator)算法