# 11.1 常用的包 (熟悉)
[TOC]
# 11.1.1 包的名称和功能
- java.lang 包,该包是 java 语言的核心包,并且该包中的所有内容由 java 虚拟机自动导入,如:System 类,String 类,...
: 如何记住 java.lang 这个包它是虚拟机自动导入的呢,可以理解为 java.lang (浪) 包,因为它很浪所以不能理会它
- java.util 包,该包是 java 语言的工具包,里面提供了大量工具类以及集合类等如:Scanner (扫描器) 类,Random 类,List 集合,...
- java.io 包,该包是 java 语言中的输入 / 输出包,里面提供了大量读写文件相关的类等如:FileInputStream 类,FileOutputStream 类,...
- java.net 包,该包是 java 语言中的网络包,里面提供了大量网络编程相关的类等如:ServerSocket 类,Socket 类,....
- java.sql 包,该包是 java 语言中的数据包,里面提供了大量的操作数据库的类和接口等如:DriverManager 类,Connection 接口,....
- ..... (还有其它的包)
- java 程序员在编程时可以使用大量类库,因此 java 编程时需要记得很多,对编程能力本身要求不是特别高
# 11.2 Object 类的概述 (重点)
# 11.2.1 基本概念
- java.lang.Object 类是 java 语言中类层次结构的根类,也就是说任何一个类都是该类的直接或者间接子类
- 如果定义一个 java 类时没有使用 extends 关键字声明其父类,则其父类为 java.lang.Object 类
- Object 类定义了 "对象" 的基本行为,被子类默认继承
# 11.2.2 常用的方法
方法声明 | 功能介绍 |
---|---|
Object( ) | 使用无参方式构造对象 |
boolean equals(Object obj) | 用于判断对象是否与参数对象相等,该方法默认比较两个对象的地址是否相等,与 == 运算符的结果一致,若希望比较两个对象的内容,则需要重写该方法,若该方法被重写后,则应该重写 hashCode 方法来保证结果一致性 |
int hashCode( ) | 用于获取调用对象的哈希码值,(内存地址的编号)<br > 若两个对象调用 equals 方法相等,则各自调用该方法的结果必须是相同 < br > 若两个调用对象 equals 方法不相同,则各自调用该方法的结果应该不相同 < br > 为了使得该方法与 equals 方法保持一致,需要重写该方法 |
String toString( ) | 用于获取调用对象的字符串形式 <br> 该方法默认返回的字符串为:<i > 包名 . 类名 @哈希码值的十六进制 </i><br > 为了返回更有意义的数据,需要重写该方法 < br > 使用 < kbd>print</kbd > 或 < kbd>println</kbd > 打印引用或字符串拼接引用都会自动调用该方法 |
Class<?> getClass( ) | 用于返回调用对象执行时的 <kbd>Class</kbd > 实例,反射机制使用 |
# 11.2.3 equals ( ) 方法默认功能的使用
equals 在没有被重写的情况下比较基本数据类型时是值,比较引用数据类型时是地址值 (如对象)
== 比较基本数据类型时是值,引用数据类型是地址值 (如对象)
比较对象是看的是地址值因为它们在创建的时候使用了 new 关键字,开辟了新的空间因此地址值就是不一样的
但是将一个使用 new 创建的对象赋值给了另一个变量此时这两个变量是一样的
/* 类对象:*/ Sent a = new Sent("张",18); | |
Sent a1 = new Sent("张",18);// 指向不同的内存空间不是同一个对象结果为 false | |
// Sent a1 = a; // 指向同一个内存空间,将对象 a 赋值给了 a1 是同一个对象 | |
boolean x = a.equals(a1);//false Sent a1 = a; true; | |
System.out.println(a == a1);//false Sent a1 = a; true; | |
System.out.println(x); |
# 11.2.4 equals ( ) 重写优化
重写 equals 可以让它的判断方式由自己来定义
@Override | |
public boolean equals(Object obj){ | |
// 当调用对象和参数对象指向同一个对象时,则内容一定相同 | |
if(this == obj) | |
return true; | |
// 判断如果传入对象是空的那么就没有可比性了直接返回 false, 不判断对象是否为空是因为对象为空就触发了 | |
//NullPointerException 空指针异常了 | |
if(obj == null) // 根据 Lambda 表达式规则方法体中只有一条语句时,可以省略大括号 | |
return false; | |
// 判断 obj 指向的对象是否为 Sent 类型的对象,若是则条件成立,否则条件不成立 | |
if(obj instanceof Sent){ | |
Sent ts = (Sent)obj; | |
return this.age == ts.age; | |
} | |
// 否则类型不一致没有可比性,则内容一定不相同 | |
return false; | |
} |
# 2. Hash Code 的总合同
只要在执行 Java 应用程序期间多次在同一个对象上调用它,Hash Code 方法必须始终返回相同的整数,前提是不修改对象上的 equals 比较中使用的信息,从应用程序的一次执行到同一应用程序的另一次执行,该整数不需要保持一致.
如果两个对象根据 equals (object) 方法相等,则对两个对象中的每个对象调用 Hash Code 方法必须生成相同的整数结果.
这不是必需的:如果两个对象不相等,equals ( Java.Lang.Object
) 方法,然后调用 Hash Code 在各两个对象的方法必须产生不同的证书结果,但是程序员应该知道为不等对象生成不同的整数结果可能会提高哈希表的性能.
尽管合理可行,但是类 Object 定义的 Hash Code 方法确实为不同的对象返回不同的整数.(Hash Code 可能会或可能不会在某个时间点实现为对象的内存地址的某些功能)
结果:对象的哈希码值
# 2.1 重写 hashCode ( ) 方法
/* 为了使得该方法的结果与 equals 方法的结果保持一致,从而满足 Java 官方的常规协定,需要重写该方法 */ | |
@Override | |
public int hashCode(){ | |
return Objects.hash(age); | |
} |
hashCode ( ) 源码
public int hashCode() { | |
int h = hash; | |
if (h == 0 && value.length > 0) { | |
char val[] = value; | |
for (int i = 0; i < value.length; i++) { | |
h = 31 * h + val[i]; | |
} | |
hash = h; | |
} | |
return h; | |
} |
# 2.2 重写 toString ( ) 与 只是用 toString 但是不重写前
// 不进行重写方法时 | |
// 下面调用 Object 类中继承下来的 toString 方法,获取调用对象的字符串形式:包名,类名 @哈希码值的十六进制 | |
String ar = a.toString( );//49 的十六进制数为:31 | |
System.out.println(ar); | |
//------------------------------------------------------------------------- | |
// 重写 toString 方法 | |
@Override | |
public String toString( ) { | |
return "{" + | |
" name='" + name + "'" + | |
", age='" + age + "'" + | |
"}"; | |
} |
不重写,打印结果: xianxipaix.Sent@31
重写,打印结果: { name='张', age='18'}
注意:如果重写了 toString () 则打印输出会自动调用 toString ()
// 重写了 toString 方法 | |
String ar = a.toString();//49 的十六进制数为:31 | |
System.out.println(ar); 结果: { name='张', age='18'} | |
System.out.println(a); 结果: { name='张', age='18'} |
如果定义 String 并赋值,打印时将该字符串跟对象拼接
Sent a = new Sent("张",18); | |
String hello = "hello"; | |
System.out.println(hello + a); |
打印结果: hello{ name='张', age='18'}
# 2.3 扩展
equals ( ) 方法重写的扩展与返回 String 数据类型的 hashCode 当然 Objects 工具类的方法也是可行的
@Override | |
public boolean equals(Object obj){ | |
// 当调用对象和参数对象指向同一个对象时,则内容一定相同 | |
if(this == obj) | |
return true; | |
// 判断如果传入对象是空的那么就没有可比性了直接返回 false, 不判断对象是否为空是因为对象为空就触发了 | |
//NullPointerException 空指针异常了 | |
if(obj == null) // 根据 Lambda 表达式规则方法体中只有一条语句时,可以省略大括号 | |
return false; | |
// 判断 obj 指向的对象是否为 Sent 类型的对象,若是则条件成立,否则条件不成立 | |
if(obj instanceof Sent){ | |
Sent ts = (Sent)obj; | |
// return this.age == ts.age; | |
/* 以年龄作为基准判断两个对象是否相等,int 是基本数据类型,内存空间中存放的就是数据本身,使用 == 可以判断数据是否相同 | |
* 以姓名作为基准判断两个对象是否相等,String 是引用数据类型,内存空间中方的是地址,使用 == 判断地址是否相同 | |
* 也就是判断两个对象中姓名的地址是否相同,虽然结果可以是 true 但是不够完美 | |
* 它们都是调用的成员变量中的 name 所以空间是同一个但是并不是同一个人 | |
* return this.name == ts.name; | |
*/ | |
return this.name.equals(ts.name); | |
} | |
// 否则类型不一致没有可比性,则内容一定不相同 | |
return false; | |
} | |
@Override | |
public int hashCode( ){ | |
int tmp = 12; | |
return tmp * 31 + name.hashCode( );// 因为姓名是 Stirng 类型的,可以调用 Object 的 hashCode 方法 | |
// 重写的 hashCode 方法不支持返回 String 数据类型因为它返回的是 int 数据类型的,所以计算 String 类型的 | |
// 哈希码值需要使用 String 类型调用 hashCode 来计算哈希值然后返回 | |
} |
** 问题: ** 那如果判断姓名加年龄呢?
@Override | |
public boolean equals(Object obj){ | |
// 当调用对象和参数对象指向同一个对象时,则内容一定相同 | |
if(this == obj) | |
return true; | |
// 判断如果传入对象是空的那么就没有可比性了直接返回 false, 不判断对象是否为空是因为对象为空就触发了 | |
//NullPointerException 空指针异常了 | |
if(obj == null) // 根据 Lambda 表达式规则方法体中只有一条语句时,可以省略大括号 | |
return false; | |
// 判断 obj 指向的对象是否为 Sent 类型的对象,若是则条件成立,否则条件不成立 | |
if(obj instanceof Sent){ | |
Sent ts = (Sent)obj; | |
// return this.age == ts.age; | |
/* 以年龄作为基准判断两个对象是否相等,int 是基本数据类型,内存空间中存放的就是数据本身,使用 == 可以判断数据是否相同 | |
* return this.age == ts.age; | |
* 以姓名作为基准判断两个对象是否相等,String 是引用数据类型,内存空间中方的是地址,使用 == 判断地址是否相同 | |
* 也就是判断两个对象中姓名的地址是否相同,虽然结果可以是 true 但是不够完美 | |
*/ | |
// return this.name.equals(ts.name); | |
//int 基本数据类型:== 判断两个值是否相等,&& 第二个条件 String 引用数据类型使用 equals 判断是否相等 | |
return this.age == ts.age && this.name.equals(ts.name); | |
} | |
// 否则类型不一致没有可比性,则内容一定不相同 | |
return false; | |
} | |
@Override | |
public int hashCode(){ | |
// 最不容易碰撞的数学计算 | |
int month = 31; | |
int day = 1; | |
day = day * month + age; | |
// 条件运算符 判断字符串是否为空 不为空计算姓名的哈希码值 | |
day = day * month + ((name == null) ? 0 : name.hashCode()); | |
return day; | |
} |
# 3. 包装类 (熟悉)
# 3.1 包装类的概念
通常情况下基本数据类型的变量不是对象,为了满足万物皆对象的理念就需要对基本数据类型的变量进行打包封装处理变成对象,而负责将这些变量声明为成员变量进行对象化处理的相关类,叫做包装类
如下 <kbd>Code</kbd > 解释:
Person p = new Person( ); //Person 类 引用指向 Person 类型对象 | |
int num = 10; // 基本数据类型 | |
public class Myint{ | |
// 将 num 放入成员变量中,当用这个类 new 对象时,这个对象中就包含了 num = 10; | |
// 无形中将这个 num 打包到了 Myint 类中,通过 new 的方式变成了对象 | |
private int num = 10; | |
} |
- 进行对象化处理的类我们叫做 <kbd> 包装类 </kbd>.
# 3.2 包装类的分类
包装类 | 对应的基本类型 |
---|---|
java.lang.Byte | byte |
java.lang.Short | short |
java.lang.Integer | int |
java.lang.Long | long |
java.lang.Float | float |
java.lang.Double | double |
java.lang.Boolean | boolean |
java.lang.Character | char |
# 3.3 Integer 类的概述
# (1) 基本概念
java.lang.Integer 类内部包装了一个 int 类型的变量作为成员变量,主要用于实现对 int 类型的包装并提供 int 类型到 String 类之间的转换等方法
# (2) 常用的常量
常量类型和名称 | 功能介绍 |
---|---|
public static final int MAX_VALUE | 表示 int 类型可以描述的最大值,即 231-1[减一是因为 0 占了一位] |
public static final int MIN_VALUE | 表示 int 类型可以描述的最小值,即 - 2^31 |
public static final int SIZE | 表示 int 类型采用二进制补码形式的位数 |
public static final int BYTES | 表示 int 类型所占的字节个数 |
public static final Class<Integer>TYPE | 表示 int 类型的 Class 实例 |
# (2.1) 常用的方法
方法声明 | 功能介绍 |
---|---|
Integer(int value) | 根据参数指定的整数来构造对象 (已过时) |
Integer(String s) | 根据参数指定的字符串来构造对象 (已过时) |
int intValue( ) | 获取调用对象中的整数值并返回 |
static Integer valueOf(int i) | 根据参数指定整数值得到 Integer 类型对象 |
boolean equals(Object obj) | 比较调用对象与参数指定的对象是否相等 |
String toString( ) | 返回描述调用对象数值的字符串形式 |
static int parseInt(String s) | 将字符串类型转换为 int 类型并返回 |
static String toString(int i) | 获取参数指定整数的十进制字符串形式 |
static String toBinaryString(int i) | 获取参数指定整数的二进制字符串形式 |
static String toHexString(int i) | 获取参数指定整数的十六进制字符串形式 |
static String toOctalString(int i) | 获取参数指定整数的八进制字符串形式 |
# (3) 装箱和拆箱的概念
在 java5 发布之前使用包装类对象进行位运算时,需要较为繁琐的 "拆箱" 和 "装箱" 操作,即运算前先将包装类对象拆分为基本数据类型,运算后再将结果封装成包装类对象
// 装箱 | |
Integer x1 = Integer.valueOf(10); | |
String srt = "10"; | |
// 拆箱 | |
int xx = x1.intValue(); |
从 java5 开始增加了 "自动装箱" 和 "自动拆箱" 的功能
// 拆箱 | |
Integer x = 10; | |
int x1 = x; | |
System.out.println(x1); | |
// 装箱 | |
int xx = 10; | |
Integer xx1 = xx; | |
System.out.println(xx1.MAX_VALUE); |
注意:基本数据类型不能调用一些静态常量方法但是包装类是可以的由此可见是为转换的哪种形式
# (4) 自动装箱池
在 Integer 类在内部提供了自动装箱池技术,将 - 128 到 127 之间的整数已经装箱完毕,当程序中使用该方位之间的整数时,无需装箱直接取用自动装箱池中的对象即可,从而提高效率.
案例 1:
Integer x = 127; | |
Integer x1 = 127; | |
Integer xx = new Integer(127); | |
Integer xx1 = new Integer(127); | |
System.out.println(x == x1); | |
System.out.println(x.equals(x1)); | |
System.out.println(xx == xx1); | |
System.out.println(xx.equals(xx1)); |
打印结果: true true false true
案例 2:
Integer x = 128; | |
Integer x1 = 128; | |
Integer xx = new Integer(128); | |
Integer xx1 = new Integer(128); | |
System.out.println(x == x1); | |
System.out.println(x.equals(x1)); | |
System.out.println(xx == xx1); | |
System.out.println(xx.equals(xx1)); |
打印结果: false true false true
这是为什么呢?可以查看一下源码
private static class IntegerCache { | |
static final int low = -128; | |
static final int high; | |
static final Integer cache[ ]; | |
static { | |
// high value may be configured by property | |
int h = 127; | |
String integerCacheHighPropValue = | |
sun.misc.VM.getSavedProperty("java.lang.Integer.IntegerCache.high"); | |
if (integerCacheHighPropValue != null) { | |
try { | |
int i = parseInt(integerCacheHighPropValue); | |
i = Math.max(i, 127); | |
// Maximum array size is Integer.MAX_VALUE | |
h = Math.min(i, Integer.MAX_VALUE - (-low) -1); | |
} catch( NumberFormatException nfe) { | |
// If the property cannot be parsed into an int, ignore it. | |
} | |
} | |
high = h; | |
cache = new Integer[(high - low) + 1]; | |
int j = low; | |
for(int k = 0; k < cache.length; k++) | |
cache[k] = new Integer(j++); | |
// range [-128, 127] must be interned (JLS7 5.1.7) | |
assert IntegerCache.high >= 127; | |
} | |
private IntegerCache( ) { } | |
} |
解释:
包装类事先给我们包装好了 - 128 - 127 之间的范围当然如果业务需要可以通过 JVM 来调优更好这个范围
通过一个故事来反应这个机制的意义:小明和小李公司活动外出采石头,公司部门可以提供盒子
但是小明自带了一个盒子范围就是可以装 127 个石头,如果小明的盒子满了
则需要向部门提供一个盒子,所以它们就不是同一个地址的石头了
注意:使用 new 来创建包装类的用法已过时,通常使用 valueOf 或者 parseXxx 来转换为包装类
Integer x = new Integer(10);// 这个方法已经过时,编译时会出现删除线 | |
Integer x1 = Integer.valueOf(10);// 返回给定参数的原生 number 对象值 | |
String srt = "10"; | |
Integer x2 = Integer.parseInt(srt);// 将 String 类型对应的数值转换为包装类,只用于 String-->Integer 或 String --> Integer --> int | |
int x3 = x2.intValue();// 只能用于将包装类转换为基本数据类型 |
除 intValue,parseXxx, 以外 像 valueOf,toString, 都是可以使用在除基本数据类型外其它类型中进行转换
# 3.4 Double 类的概述
(1) 基本概念
java.lang.Double 类型内部包含了一个 double 类型的变量作为成员变量,主要用于实现 double 类型的包装类并提供 boule 类型到 String 类之间的转换等方法
(2) 常用的常量
常量类型和名称 | 功能介绍 |
---|---|
public static final int SIZE | 表示 double 类型的二进制位数 |
public static final int BYTES | 表示 double 类型的字节个数 |
public static final Class<Double>TYPE | 表示 double 类型的 Class 实例 |
(3) 常用的方法
方法声明 | 功能介绍 |
---|---|
Double(double value) | 根据参数指定的浮点数据来构造对象 (已过时) |
Double(String s) | 根据参数指定的字符串来构造对象 (已过时) |
double doubleValue( ) | 获取调用对象中的浮点数据并返回 |
boolean equals(Object obj) | 比较调用对象与参数指定的对象是否相等 |
String toString( ) | 返回描述调用对象数值的字符串形式 |
static double parseDouble(String s) | 将字符串类型转换为 double 类型并返回 |
boolean isNaN( ) | 判断调用对象的数值是否为非数字 |
- 扩展: java.lang.Number 类是个抽象类,是上述类的父类来描述所有类共有的成员
Double x = 10.1; | |
Double x1 = 10.1; | |
double xx = 1.1; | |
double xx1 = 1.1; | |
System.out.println(x == x1); | |
System.out.println(xx == xx1); |
打印结果: false true
注意: Double 包装类中没有自带的盒子 (缓冲器) 所以无论赋值多少都不是同一个地址的使用 == 来判断
必定是 false, 基本数据类型使用 == 来判断是判断的值所以是 true
什么情况下 isNaN ( ) 判断结果为 true 呢?
Double x = Double.valueOf(0/0.0); | |
System.out.println(x.isNaN()); |
打印结果: true
# 3.5 Boolean 类的概述
(1) 基本概念
java.lang.Boolean 类型内部包装了一个 boolean 类型的变量作为成员变量,主要用于实现对 boolean 类型的包装并提供 boolean 类型到 String 类之间的转换等方法
(2) 常用常量
常量类型和名称 | 功能介绍 |
---|---|
public static final Boolean FALSE | 对应基值为 false 的对象 |
public static final Boolean TRUE | 对应基值为 true 的对象 |
public static fianl Class<Boolean>TYPE | 表示 boolean 类型的 Class 实例 |
(3) 常用的方法
方法声明 | 功能介绍 |
---|---|
Boolean(boolean value) | 根据参数指定的布尔数值来构造对象 (已过时) |
Boolean(String s) | 根据参数指定的字符串来构造对象 (已过时) |
boolean booleanValue( ) | 获取调用对象中的布尔数值并返回 |
static Boolean valueOf(boolean b) | 根据参数指定布尔数值得到 Boolean 类型对象 |
boolean equals(Object obj) | 比较调用对象与参数指定的对象是否相等 |
String toString( ) | 返回描述调用对象数值的字符串形式 |
static boolean parseBoolean(String s) | 将字符串类型转换为 boolean 类型并返回 |
# 3.6 Character 类的概述
(1) 基本概念
java.lang.Character 类型内部包装了一个 char 类型的变量作为成员变量,主要用于实现对 char 类型的包装并提供字符类别的判断和转换等方法
\textcolor{yellow}
常量类型和名称 | 功能介绍 |
---|---|
public static final int SIZE | 表示 char 类型的二进制位数 |
public static final int BYTES | 表示 char 类型的字节个数 |
public static final Class<Character>TYPE | 表示 char 类型的 Class 实例 |
\textcolor{yellow}
方法声明 | 功能介绍 |
---|---|
Character(char value) | 根据参数指定的字符数据来构造对象 (已过时) |
char charValue( ) | 获取调用对象中的字符数据并返回 |
static Character valueOf(char c) | 根据参数指定字符数据得到 Character 类型对象 |
boolean equals(Object obj) | 比较调用对象与参数指定的对象是否相等 |
String toString( ) | 返回描述调用对象数值的字符串形式 |
static boolean isUpperCase(char ch) | 判断参数指定字符是否为大写字符 |
static boolean isLowerCase(char ch) | 判断参数指定字符是否为小写 |
static boolean isDigit(char ch) | 判断参数指定字符是否为数字字符 |
static char toUpperCase(char ch) | 将参数指定的字符转换为大写字符 |
static char toLowerCase(char ch) | 将参数指定的字符转换为小写字符 |
# 3.6.1 包装类 (Wrapper) 的使用总结
基本数据类型转换为对应的包装类的方式
调用包装类的构造方法或静态方法即可
获取包装类对象中的基本数据类型变量数值的方式
调用包装类中的 xxxValue 方法即可
- 字符串转换为基本数据类型的方式
调用包装类中的 parseXxx 方法即可
# 4. 数学处理类 (熟悉)
4.1Math 类的概述
(1) 基本概念
java.lang.Math 类主要用于提供执行数学运算的方法,如:对数,平方根
(2) 常用的方法
方法声明 | 功能介绍 |
---|---|
static int max(int a,int b) | 返回两个参数中的最大值 |
static int min(int a,int b) | 返回两个参数中的最小值 |
static double pow(double a,double b) | 返回第一个参数的幂 |
static int abs(int a) | 返回参数指定数值的绝对值 |
static long round(double a) | 返回参数四舍五入的结果 |
static double sqrt(double a) | 返回参数的平方根 |
static double random( ) | 返回 0.0 到 1.0 的随机数 |
static double cos(double a) | 返回参数指定数值的余弦 |
static double sin(double a) | 返回参数指定数值的正弦 |
static final double PI | 返回圆周率静态常量 |
static double cbrt(double a) | 返回参数指定数值的立方根 |
static double ceil(double a) | 返回参数指定数值的向上取整 |
static double floor(double a) | 返回参数指定数值的向下取整 |
# 4.1.BigDecimal 类的概述
(1) 基本概念
由于 float 类型和 double 类型在运算时可能会有误差,若希望实现精确运算则借助 java.math.BigDecimal 类型加以描述
(2) 常用的方法
方法声明 | 功能介绍 |
---|---|
BigDecimal(String val) | 根据参数指定的字符串来构造对象 |
BigDecimal add(BigDecimal subtrahend) | 用于实现加法运算 |
BigDecimal subtract(BigDecimal subtrahend) | 用于实现减法运算 |
BigDecimal multiply(BigDecimal multiplicand) | 用于实现乘法运算 |
BigDecimal divide(BigDecimal divisor) | 用于实现除法运算 |
BigDecimal bigdecimal = new BigDecimal("5.2"); | |
BigDecimal bigdecimal1 = new BigDecimal("1.3"); | |
System.out.println("加法运算结果:"+bigdecimal.add(bigdecimal1)); //6.5 | |
System.out.println("减法运算结果:"+bigdecimal.subtract(bigdecimal1));//3.9 | |
System.out.println("乘法运算结果:"+bigdecimal.multiply(bigdecimal1)); //6.76 | |
System.out.println("除法运算结果:"+bigdecimal.divide(bigdecimal1)); //4 | |
System.out.println("----------------------------------------"); | |
System.out.print("没有精确运算的结果:"); | |
System.out.println(0.1+0.2); //0.30000000000000004 | |
// 创建 BigDecimal 对象计算精确的浮点数运算 | |
BigDecimal bigdecimal2 = new BigDecimal("0.1"); | |
BigDecimal bigdecimal3 = new BigDecimal("0.3"); | |
System.out.print("精确运算结果:"); | |
System.out.println(bigdecimal2.add(bigdecimal3));//0.4 |
注意:
System.out.println("------------注意事项------------"); | |
BigDecimal bi = new BigDecimal("2"); | |
BigDecimal bi1 = new BigDecimal("0.3"); | |
System.out.println(""+bi.divide(bi1));// 无限循环小数会导致 ArtimectiException 算术异常 | |
// 当然 0/0 也是行不通的 | |
BigDecimal bi = new BigDecimal("2"); | |
BigDecimal bi1 = new BigDecimal("0"); | |
System.out.println(""+bi.divide(bi1));//0 除以 0 导致 ArtimectiException 算术异常 |
打印结果: Exception in thread "main" java.lang.ArithmeticException:Non-terminating decimal expansion; no exact representable decimal result.
Non-terminating decimal expansion; no exact representable decimal result.
(翻译): 非终止小数扩展; 没有精确可表示的小数
解决办法:
RoundingMode.HALF_UP
: 进行四舍五入避免抛出 ArtimectiException
, 只用于除法运算!
RoundingMode.HALF_UP
:
BigDecimal bi = new BigDecimal("2"); | |
BigDecimal bi1 = new BigDecimal("0.3"); | |
// 进行四舍五入 | |
System.out.println(""+bi.divide(bi1,RoundingMode.HALF_UP)); |
打印结果: 7
# 4.2BigInteger 类的概述
(1) 基本概念
若希望表示比 long 类型范围还大的整数数据,则需要借助 java.math.BigInteger 类型描述 (能描述更大的对象)
(2) 常用的方法
方法声明 | 功能介绍 |
---|---|
BigIntger(String val) | 根据参数指定的字符串来构造对象 |
BigInteger add(BigInteger val) | 用于实现加法运算 |
BigInteger subtract(BigInteger val) | 用于实现减法运算 |
BigInteger multiply(BigInteger val) | 用于实现乘法运算 |
BigInteger divide(BigInteger val) | 用于实现除法运算 |
BigInteger remainder(BigInteger val) | 用于实现取余运算 (相当于 % 运算符) |
BigInteger[ ] divideAndRemainder(BigInteger val) | 用于实现取商和余数的运算 |
BigInteger biginteger = new BigInteger("20"); | |
BigInteger biginteger1 = new BigInteger("8"); | |
System.out.println("加法运算结果:"+biginteger.add(biginteger1));//28 | |
System.out.println("减法运算结果:"+biginteger.subtract(biginteger1));//12 | |
System.out.println("乘法运算结果:"+biginteger.multiply(biginteger1));//160 | |
System.out.println("除法运算结果:"+biginteger.divide(biginteger1));//2 | |
System.out.println("取余运算结果:"+biginteger.remainder(biginteger1));//4 | |
System.out.println("------------一次性得到商和余数------------"); | |
System.out.println("取商和取余运算结果:"+Arrays.toString(biginteger.divideAndRemainder(biginteger1)));//[2, 4] | |
BigInteger[] x = biginteger.divideAndRemainder(biginteger1); | |
//forEach 循环遍历 BigInteger 数组中元素 | |
for(BigInteger i : x){ | |
System.out.println("BigInteger[] = "+i); | |
} |
打印结果: 加法运算结果:28 减法运算结果:12 乘法运算结果:160 除法运算结果:2 取余运算结果:4 ------------一次性得到商和余数------------ 取商和取余运算结果:[2, 4] BigInteger[] = 2 BigInteger[] = 4