1.BigInteger
BigInteger
可以表示非常大范围的整数,理论上来说无限大
a.构造方法
构造方法 | 说明 |
---|---|
public BigInteger(int num, Random rnd) | 获取随机大整数,范围 : [0 ~ 2的num次方 - 1] |
public BigInteger(String val) | 获取指定的大整数 |
public BigInteger(String val, int radix) | 获取指定进制的大整数 |
public static BigInteger valueOf(long val) | 静态方法获取BigInteger的对象,内部有优化 |
对象一旦创建,里面的数据不能发生改变。
示例:
BigInteger(int num, Random rnd)
Random r = new Random();
for (int i = 0; i < 100; i++) {
BigInteger bd1 = new BigInteger(4,r);
System.out.println(bd1);//[0 ~ 15]
}
获取0 ~ 15的数字
2. BigInteger(String val)
字符串中必须是整数,否则会报错
BigInteger bd2 = new BigInteger("1.1");
System.out.println(bd2) ;//false
BigInteger bd3 = new BigInteger("abc");
System.out.println(bd3) ;//false
BigInteger(String val, int radix)
- 字符串中的数字必须是整数
- 字符串中的数字必须要跟进制吻合。
//比如二进制中,那么只能写0和1,写其他的就报错。
BigInteger bd4 = new BigInteger("100",2);
System.out.println(bd4) ;
输出的结果为:4为十进制
BigInteger valueOf(long val)
- 能表示范围比较小,只能在long的取值范围之内,如果超出
long
的范围就不行了。 - 在内部对常用的数字 : -16 ~ 16 进行了优化。
- 需要我们注意的是:long类型的数字需要在末尾加上L,因为在编译器中数字默认为int类型
- 提前把-16~16 先创建好BigInteger的对象, 如果多次获取不会重新创建新的。
BigInteger bd5 = BigInteger.valueOf(16);
BigInteger bd6 = BigInteger.valueOf(16);
System.out.println(bd5 == bd6);
返回的结果为:true
b.成员方法
成员方法 | 说明 |
---|---|
public BigInteger add(BigInteger val) | 加法 |
public BigInteger subtract(BigInteger val) | 减法 |
public BigInteger multiply(BigInteger val) | 乘法 |
public BigInteger divide(BigInteger val) | 除法,获取商 |
public BigInteger[ ] divideAndRemainder(BigInteger val) | 除法,获取商和余数 |
public boolean equals(Object x) | 比较是否相同 |
public BigInteger pow(int exponent) | 返回调用数字的exponent次幂 |
public BigInteger max/min(BigInteger val) | 返回较大值/较小值 |
public int intValue(BigInteger val) | 转为int类型整数,超出范围数据有误 |
创建对象:
BigInteger bd1 = new BigInteger("100");
BigInteger bd2 = new BigInteger("50");
像加法、减法之类直接使用对象调用即可,不再赘述
转换为int类型:
//转为int类型整数,超出范围数据有误
BigInteger bd6 = BigInteger.valueOf(2147483648L);
int i = bd6.intValue();
System.out.println(i);//返回错误的结果
BigInteger bd6 = BigInteger.valueOf(200);
double v = bd6.doubleValue();
System.out.println(v);//200.0
当然如上面的代码一样,还用其他的转换类型:doubleValue(), longValue()
2.BigDecimal
用BigDecimal
来解决小数精度的问题
看一段代码:
System.out.println(0.09 + 0.01);
System.out.println(0.216 - 0.1);
System.out.println(0.226 * 0.01);
System.out.println(0.09 / 0.1);
结果是:
所以说小数在编译器中做的运算和存储有很大可能是不精确的,为了解决这个问题,我么可以使用BigDecimal
的对象
- 可以进行小数的精确计算
- 可以用来表示很大的小数
a.构造方法
1.构造方法获取BigDecimal对象
public BigDecimal(double val);
public BigDecimal(String val);
2.静态方法获取BigDecimal对象
public static BigDecimal valueOf(double val);
代码示例:
- 传入
double
类型数字
BigDecimal bd1 = new BigDecimal(0.1);
BigDecimal bd2 = new BigDecimal(0.9);
如果进行打印我么可以知道,输入结果的小数精度很大,但是任然可能是不精确的
所以这个方法我们一般不用
BigDecimal(String val)
这个构造方法创建的对象保存数字是精确的
BigDecimal bd1 = new BigDecimal("0.01");
BigDecimal bd2 = new BigDecimal("0.9");
//在进行运算之后仍然是精确的
bd1.add(bd2);
- 通过静态方法
BigDecimal bd6 = BigDecimal.valueOf(10);
BigDecimal bd7 = BigDecimal.valueOf(10);
System.out.println(bd6 == bd7);
//true
细节:
- . 如果要表示的数字不大,没有超出
double
的取值范围,建议使用静态方法 - . 如果要表示的数字比较大,超出了
double
的取值范围,建议使用构造方法 - . 如果我们传递的是
0~10
之间的整数(包含0,包含10), 那么方法会返回已经创建好的对象,不会重新new(不会创建新的对象)
- 注意要进行优化只能传入的是整数,小数或者其他类型的数据不会被优化,仍然会创建对象
- 静态方法是精确的因为在底层调用的也是
BigDecimal(String val)
- 和BigInteger : -16 ~ 16 的优化相似
b.成员
public BigDecimal add(BigDecimal val): 加法
public BigDecimal subtract(BigDecimal val) : 减法
public BigDecimal multiply(BigDecimal val) : 乘法
public BigDecimal divide(BigDecimal val) : 除法(必须整除)
public BigDecimal divide(BigDecimal val,精确几位,舍入模式) : 除法
代码示例:
BigDecimal bd3 = new BigDecimal("1.00");
BigDecimal bd4 = BigDecimal.valueOf(12.0);
//加法
BigDecimal bd5 = bd3.add(bd4);
System.out.println(bd5);
//乘法
System.out.println(bd3.multiply(bd4));
//除法
//System.out.println(bd3.divide(bd4));
//1.0/12.0返回的不是整数-报错
//精度较大的除法
System.out.println(bd3.divide(bd4, 4, RoundingMode.DOWN));
需要我们注意的两点:
- 除法的方法有很多,一般情况下我们使用参数为三个的方法,在上面提供的另外的方法中不能整除的计算会报错
- 在选择除法的舍入方式的时候,我们一般使用
RoundingMode
中的枚举常量
枚举常量我们后面会讲
下面介绍一些常用的舍入方法:
- UP:远离0的方向舍入
- DOWN:靠近0的方向舍入
- GEILING:向正无限大方向舍入
- FLOOR:向负无限大的方向舍入
- HALF_UP:四舍五入
- HULF_DOWN:向最接近数字方向舍入的舍入模式,如果与两个相邻数字的距离相等,则向下舍入。如果被舍弃部分>0.5,则舍入行为同
RoundingMode.UP
;否则舍入行为同RoundingMode.DOWN
。
c.BigDecimal的底层存储方式
略
3.正则表达式
在我们对字符串进行处理的时候往往会有很多的规则,我们通常的做法是使用if语句进行条件或者规则的判断。
但是当有多个条件的时候,这种方法往往效率较低并且代码量较高
正则表达式的作用:
- 校检字符串是否满足规则
- 在一段文本中查找满足要求的内容
正则表达式规则:
调用字符串的方法matches(正则表达式)
,返回结果为boolean
类型
- 字符类
下面的式子,一个式子只匹配一个字符
式子 | 说明 |
---|---|
[abc] | 只能是a, b, 或c |
[^abc] | 除了a,b,c之外的任何字符 |
[a-zA-Z] | a到z,或A到Z |
[a-d[m-p]] | a到d, 或m到p |
[a-z&&[def]] | a-z和def的交集。为:d,e,f |
[a-z&&[^bc]] | a-z和非bc的交集。(等同于[ad-z]) |
[a-z&&[^m-p]] | a到z和除了m到p的交集。(等同于[a-lq-z]) |
代码示例:
String name = "lsh";
System.out.println(name.matches("[a-z]"));
System.out.println(name.matches("[a-z][s][h]"));
第一个输出语句返回:false
第二个输出语句返回:true
因为一个正则表达式只能匹配一个字符,要想完成匹配需要三个表达式
- 预定义字符
预定义字符,也只匹配一个字符
字符 | 说明 |
---|---|
. | 任何字符 |
\d | 一个数字:[0-9] |
\D | 非数字:[^0-9] |
\s | 一个空白字符:[\t\n\xOB\f\r] |
\S | 非空白字符:[^\s] |
\w | [a-zA-Z_0-9]英文、数字、下划线(一个单词字符) |
\W | [^\w]一个非单词字符 |
代码示例:
String ch = "abcd";
System.out.println(ch.matches("."));
System.out.println(ch.matches("...."));
System.out.println(ch);
//数字
String ch2 = "12";
System.out.println(ch2);
System.out.println(ch2.matches("\\d\\d"));
值得我们注意的是:\ 在Java中表示的是转义字符,作用是把一些特殊的字符转义为普通字符。
例如:
- " 表示的是字符串的开头或者结尾,一般情况我们是无法打印输出这个字符的,但是我们可以使用 \ " 来转义输出
- 所以如果在编译器中写 \d 意思是把字符d进行转义,所以要把这个\ 转义为普通的字符 \ \ 。所以最终的写法就是\ \d
后面的 \ \w, \ \W, \ \s, \ \S等也是因为这个
- 数量词
上面的代码都是只能用于一个字符的匹配,所以为了代码的方便和简练,我们引入数量词的概念——在表达式后边加上不同的符号表示不同的数量
数量词 | 说明 |
---|---|
X? | X,一次或0次 |
X* | X,零次或多次 |
X+ | X,一次或多次 |
X {n} | X,正好n次 |
X{n,} | X,至少n次 |
X{n,m} | X,至少n但不超过m次 |
代码示例:
// 必须是数字 字母 下划线 至少 6位
System.out.println("2442fsfsf".matches( regex:"\\w{6,}"));//true
System.out.println("244f".matches( regex:"\\w{6,}"));//false
// 必须是数字和字符,必须是4位
System.out.println("23dF".matches( regex: "[a-zA-Z0-9]{4}"));//true
System.out.println("23_F".matches( regex: "[a-zA-Z0-9]{4}"));//false
System.out.println("23dF".matches( regex:"[\\w&&[^_]]{4}"));//true
System.out.println("23_F".matches( regex:"[\\w&&[^_]]{4}"));//false
在API帮助文档中可以搜索
Pattern
查看详细信息