public String(char[] value,int index,int count)
:把字符数组的一部分转成字符串
String为什么要设计成final
1、常量池中的数据可以被共享,导致可能很多地方都在操作这个对象,尤其在多线程中是很危险的。定义成final不可变可以保证线程安全
2、字符串进入常量池后,数据共享,再次调用可节省资源,调高效率
String 中的 equals 方法是被重写过的,因为 object 的 equals 方法是比较的对象的内存地址,而 String 的 equals 方法比较的是对象的值。
String s1 = new String(“abc”);
//创建两个对象,一个在常量池,一个在堆内存中
String s1 = new String(“abc”); //在堆内存中的地址值
String s2 = “abc”; //在常量池中的地址值
System.out.println(s1 == s2); //false
System.out.println(s1.equals(s2)); //true
String s1 = “a” + “b” + “c”;
String s2 = “abc”;
System.out.println(s1 == s2); //true,Java中有常量优化机制
System.out.println(s1.equals(s2)); //true
String s1 = “ab”; //常量池中
String s2 = “abc”; //常量池中
String s3 = s1 + “c”; //在堆中,由toString方法化为字符串
System.out.println(s3 == s2); //false
System.out.println(s3.equals(s2)); //true
boolean equalsIgnoreCase(String str):比较字符串的内容是否相同,忽略大小写
boolean contains(String str):判断大字符串中是否包含小字符串
boolean startsWith(String str):判断字符串是否以某个指定的字符串开头
boolean endsWith(String str):判断字符串是否以某个指定的字符串结尾
boolean isEmpty():判断字符串是否为空。
""表示字符串为空,而不是null
""和null的区别:
""是字符串常量,同时也是一个String类的对象,既然是对象当然可以调用String类中的方法
null是空常量,不能调用任何的方法,否则会出现空指针异常,null常量可以给任意的引用数据类型赋值
byte[] getBytes():把字符串转换为字节数组。
char[] toCharArray():把字符串转换为字符数组。
public static void main(String[] args) {
System.out.println(Integer.toBinaryString(60));//111100,整数转成二进制字符串
System.out.println(Integer.toOctalString(60));//74,整数转成八进制字符串
System.out.println(Integer.toHexString(60));//3c,整数转成十六进制字符串
}
Integer.MAX_VALUE:2147483647整型的最大值(2*10^9)
Integer.MIN_VALUE:‐2147483648整型的最小值
和""进行拼接
public static String valueOf(int i)
String.valueOf(i);
int ‐‐ Integer ‐‐ String(Integer类的toString()方法)
Integer i2 = new Integer(i);
String s3 = i2.toString();
public static String toString(int i)(Integer类的静态方法)
String s4 = Integer.toString(i);
String ‐‐ Integer ‐‐ int
public static int parseInt(String s)//要求传入的字符串是数字字符串,跟public Integer(String s)完全一样
String s = "200";
Integer i3 = new Integer(s);
int i4 = i3.intValue();//200,Integer对象的整型值方法转换成了int数
int i5 = Integer.parseInt(s);//200,Integer的静态解析整型方法,将String转换为int,推荐用这种
JDK5的新特性自动装箱和拆箱:
Integer ii = 100;
//基本类型转换为包装类类型,自动装箱
ii += 200;
//把包装类类型转换为基本类型,自动拆箱,底层调用了包装类对象的intValue方法,所以ii不能为null
自动拆箱,底层调用了包装类对象的intValue方法,如int z = i2 + 200;底
层调用的是int z = i2.intValue() + 200;所以,对象i2不能赋值为null再调用
方法,否则会报运行时异常的空指针异常,但是编译符合语法是通过的,这个要
区别开哦!
Integer i5 = 127;
//自动装箱底层调用的是valueOf方法,Integer i5 = Integer.valueOf(127);
Integer i1 = new Integer(97);
Integer i2 = new Integer(97);
System.out.println(i1 == i2);//false
System.out.println(i1.equals(i2));//true
System.out.println("‐‐‐‐‐‐‐‐‐‐‐");
Integer i3 = new Integer(197);
Integer i4 = new Integer(197);
System.out.println(i3 == i4);//false
System.out.println(i3.equals(i4));
System.out.println("‐‐‐‐‐‐‐‐‐‐‐");
Integer i5 = 97;
Integer i6 = 97;
System.out.println(i5 == i6);//true,自动装箱,真相只有一个,在字节范围内就使用,否则创建对象!
System.out.println(i5.equals(i6));
System.out.println("‐‐‐‐‐‐‐‐‐‐‐");
Integer i7 = 197;
Integer i8 = 197;
System.out.println(i7 == i8);//false
System.out.println(i7.equals(i8));
/*‐128到127是byte的取值范围,如果在这个取值范围内,自动装箱就不会新创建对象,而是从常量池中获取,
如果超过了byte取值范围就会再新创建对象,看自动装箱底层调用的valueOf方法的源码就知道了,如下所示:
public static Integer valueOf(int i) {
assert IntegerCache.high >= 127;
if (i >= IntegerCache.low && i <= IntegerCache.high)//i>= ‐128 && i <= 127,字节范围内,
return IntegerCache.cache[i + (‐IntegerCache.low)];//满足条件,从常量池获取
return new Integer(i);//否则,创建新对象!!!
}*/
这里凡是new出来的地址值都不同,另外如果是自动装箱,基本类型值范围在byte字节范围内**-128到+127**,就不用创建对象,直接使用byte常量池的值,地址值相同,否则要创建新对象,地址值不同,而equals方法重写了,比较的是内容,所以都相等
在Java中,由CPU原生提供的整型最大范围是64位long型整数。使用long型整数可以直接通过CPU指令进行计算,速度非常快。
如果我们使用的整数范围超过了long型怎么办?这个时候,就只能用软件来模拟一个大整数。java.math.BigInteger就是用来表示任意大小的整数。BigInteger内部用一个int[]数组来模拟一个非常大的整数:
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
和long型整数运算比,BigInteger不会有范围限制,但缺点是速度比较慢。
BigInteger类的常用方法:
public BigInteger add(BigInteger val) 返回当前大整数对象与参数指定的大整数对象的和
public BigInteger subtract(BigInteger val) 返回当前大整数对象与参数指定的大整数对象的差
public BigInteger multiply(BigInteger val) 返回当前大整数对象与参数指定的大整数对象的积
public BigInteger devide(BigInteger val) 返回当前大整数对象与参数指定的大整数对象的商
public BigInteger remainder(BigInteger val) 返回当前大整数对象与参数指定的大整数对象的余
public int compareTo(BigInteger val) 返回当前大整数对象与参数指定的大整数对象的比较结果,返回值是1、-1、0,分别表示当前大整数对象大于、小于或等于参数指定的大整数。
public BigInteger abs() 返回当前大整数对象的绝对值
public BigInteger pow(int exponent) 返回当前大整数对象的exponent次幂。
public String toString() 返回当前当前大整数对象十进制的字符串表示。
public String toString(int p) 返回当前大整数对象p进制的字符串表示。
也可以把BigInteger转换成long型:
BigInteger i = new BigInteger("123456789000");
System.out.println(i.longValue()); // 123456789000
System.out.println(i.multiply(i).longValueExact()); // java.lang.ArithmeticException: BigInteger out of long range
使用longValueExact()方法时,如果超出了long型的范围,会抛出ArithmeticException。
BigInteger和Integer、Long一样,也是不可变类,并且也继承自Number类。因为Number定义了转换为基本类型的几个方法:
转换为byte:byteValue()
转换为short:shortValue()
转换为int:intValue()
转换为long:longValue()
转换为float:floatValue()
转换为double:doubleValue()
因此,通过上述方法,可以把BigInteger转换成基本类型。如果BigInteger表示的范围超过了基本类型的范围,转换时将丢失高位信息,即结果不一定是准确的。如果需要准确地转换成基本类型,可以使用intValueExact()、longValueExact()等方法,在转换时如果超出范围,将直接抛出ArithmeticException异常。
计算1+2+…前30项和:
import java.math.BigInteger;
public class jc{
public static void main(String[] args) {
BigInteger sum=new BigInteger("0"),
xiang=new BigInteger("1"),
oNE=new BigInteger("1"),
i=oNE,m=new BigInteger("30");
while (i.compareTo(m)<=0) {
sum=sum.add(xiang);
i=i.add(oNE);
xiang=xiang.multiply(i);
}
System.out.println(sum);
}
}
和BigInteger类似,BigDecimal可以表示一个任意大小且精度完全准确的浮点数。商业计算往往要求结果精确,这时候就应该使用BigDecimal。
构造实例
public static void main(String[] args)
{
BigDecimal bigDecimal = new BigDecimal(2);
BigDecimal bDouble = new BigDecimal(2.3);
BigDecimal bString = new BigDecimal("2.3");
System.out.println("bigDecimal=" + bigDecimal);//输出:bigDecimal=2
System.out.println("bDouble=" + bDouble);//输出:bDouble=2.9999999
System.out.println("bString=" + bString);//输出:bString=2.3
}
构造方法注意事项
参数类型为double的构造方法的结果有一定的不可预知性;String 构造方法是完全可预知的;所以我们在编写代码时尽量都用String 构造方法。当double必须用作BigDecimal的源时可以用BigDecimal的静态方法 valueOf() 如:BigDecimal bDouble1 = BigDecimal.valueOf(2.3);
运算方法
public BigDecimal add(BigDecimal value); //加法
public BigDecimal subtract(BigDecimal value); //减法
public BigDecimal multiply(BigDecimal value); //乘法
public BigDecimal divide(BigDecimal value); //除法
运算注意事项
除法运算 divide() 方法,可能出现不能整除的情况,比如 4.5/1.3,这时会报错java.lang.ArithmeticException: Non-terminating decimal expansion; no exact representable decimal result。其实divide方法有可以传三个参数。
public BigDecimal divide(BigDecimal divisor, int scale, int roundingMode)
第一参数表示除数(num/divisor)
第二个参数表示小数点后保留位数,
第三个参数表示舍入模式,只有在作除法运算或四舍五入时才用到舍入模式。
舍入模式
ROUND_CEILING //向正无穷方向舍入
ROUND_DOWN //向零方向舍入
ROUND_FLOOR //向负无穷方向舍入
ROUND_HALF_DOWN //向(距离)最近的一边舍入,除非两边(的距离)是相等,如果是这样,向下舍入, 例如1.55 保留一位小数结果为1.5
ROUND_HALF_EVEN //向(距离)最近的一边舍入,除非两边(的距离)是相等,如果是这样,如果保留位数是奇数,使用ROUND_HALF_UP,如果是偶数,使用ROUND_HALF_DOWN
ROUND_HALF_UP //(四舍五入)向(距离)最近的一边舍入,除非两边(的距离)是相等,如果是这样,向上舍入, 1.55保留一位小数结果为1.6
ROUND_UNNECESSARY //计算结果是精确的,不需要舍入模式
ROUND_UP //向远离0的方向舍入
舍入实例方法
public static void main(String[] args)
{
BigDecimal a = new BigDecimal("4.5635");
a = a.setScale(3, RoundingMode.HALF_UP); //保留3位小数,且四舍五入
System.out.println(a);
}