常用类
一、Object类
java.lang.Object
在java中是万类的祖先,所有类都继承这个类,包括我们自己创建的类。Java中的继承是单继承的,如果一个类没有定义任何父类则这个类默认继承java.lang.Object
,故其中定义的方法可以被任意引用类型使用,前提是拥有足够的权限。
根据JDK的API文档,我们可以发现Object类当中包含的方法有11个。今天我们主要学习其中的2个:
public String toString()
:返回该对象的字符串表示。public boolean equals(Object obj)
:指示其他某个对象是否与此对象“相等”。protected native Object clone()
: 创建并返回此对象的一个副本。protected void finalize()
: 当垃圾回收器确定不存在对该对象的更多引用时,由对象的垃圾回收器调用此方法。
1.2 toString方法
当我们在直接输出打印一个引用类型的对象时发现输出结果为"类型+@+内存地址值"。这个结果其实就是调用了这个对象的toString方法的结果。我们可以通过Object的toString源码得到验证:
public String toString() {
return getClass().getName() + "@" + Integer.toHexString(hashCode());
}
由于toString方法返回的结果是内存地址,而在实际开发中,我们更多的是需要显示对象的属性特征,故我们一般都会重写这个方法。
public class Person {
private String name;
private int age;
@Override
public String toString() {
return "Person{" + "name='" + name + '\'' + ", age=" + age + '}';
}
}
在IntelliJ IDEA中,可以点击Code
菜单中的Generate...
,也可以使用快捷键alt+insert
,点击toString()
选项来快速生成这个方法的重写。
1.3 equals方法
`equals`方法指示其他某个对象是否与此对象“相等”。这个“相等”用上引号是以为它并不是数学意义上的相等,而是业务逻辑中的逻辑意义上的"相等",其判断的结果应该由我们业务逻辑来确定。
但Ojbect类并不知道其子类需要定义什么业务逻辑,故在Object中的默认实现逻辑就是判断是否是同一个对象,等效于==
,一般我们会根据业务逻辑来重写。
一般来说等号比的是地址,equals比的是值;
由于我们经常需要重写这个方法,我们可以通过Code
菜单中的Generate...
,也可以使用快捷键alt+insert
,点击equals()
选项来快速生成这个方法的重写。
假设我们定义人的姓名相同的2个Person对象就相等,否则就不相等。
public class Person {
// 姓名
private String name;
// 年龄
private int age;
@Override
public boolean equals(Object o) {
// 如果要比较的2个对象是同一个对象,则直接返回true
if (this == o) return true;
// 如果要比较的2个对象的类型不一致,则直接返回false
if (!(o instanceof Person)) return false;
// 将要比较的对象转成当前类型,并比较姓名是否相同
Person person = (Person) o;
return name.equals(person.name);
}
}
hashcode
方法通常需要跟equals
方法一起重写,作用跟用法我们今后学习。
二、 Math类
Math
类包含用于执行基本数学运算的方法,如初等指数、对数、平方根和三角函数。 math
中的所有方法都为static
类型的,故我们只需通过Math
类来使用这些方法,而不需要先创建对象。
此类大部分方法都属于数学领域的,我们一般只需用到其中比较常用的方法:
-
static double PI
: 比任何其他值都更接近 pi(即圆的周长与直径之比)的double
值。 -
static double abs(double a)
:返回double
值的绝对值。 -
static float abs(float a)
:返回double
值的绝对值。 -
static int abs(int a)
:返回double
值的绝对值。 -
static long abs(long a)
:返回double
值的绝对值。 -
static double ceil(double a)
: 返回最小的(最接近负无穷大)double
值,该值大于等于参数,并等于某个整数。 -
static double floor(double a)
: 返回最大的(最接近正无穷大)double
值,该值小于等于参数,并等于某个整数。 -
static long round(double a)
: 返回最接近参数的long
。 -
static int round(float a)
: 返回最接近参数的int
。 -
static long pow(double a, double b)
: 返回第一个参数的第二个参数次幂的值。 -
static double random()
: 返回带正号的 double 值,该值大于等于 0.0 且小于 1.0。
Math
类中的方法都比较简单,我们一起看下其使用方法:
public static void main(String[] args) {
System.out.println(Math.PI);//3.141592653589793
System.out.println(Math.abs(-3.5));//3.5
System.out.println(Math.ceil(-3.5));//-3.0
System.out.println(Math.floor(3.5));//3.0
System.out.println(Math.round(3.5));//4
System.out.println(Math.round(-3.5));//-3
System.out.println(Math.pow(3,4));//81.0
System.out.println(Math.random());// [0.0-1.0)之间的随机值
}
三、 Random类
当我们在完成类似小游戏之类的程序时经常需要用到随机数的知识,我们可以使用Random类来实现。Random类的实例用于生成伪随机数流。由于实例是通过算法算出来的,并不是真正意义上的随机,故称为伪随机。而算法依赖一个随机种子。
如果有2个随机种子相同的Random实例,其每次随机出来的数字都相同。
构造器:
public Random()
:创建一个新的随机数生成器。public Random(long seed)
:使用单个 long 种子创建一个新的随机数生成器。
成员方法:
public double nextDouble()
: 返回下一个伪随机数,它是取自此随机数生成器序列的、在0.0
和1.0
之间均匀分布的double
值。public float nextFloat()
: 返回下一个伪随机数,它是取自此随机数生成器序列的、在0.0
和1.0
之间均匀分布的float
值。public int nextInt()
: 返回下一个伪随机数,它是此随机数生成器的序列中均匀分布的int
值。public int nextInt(int n)
: 返回一个伪随机数,它是取自此随机数生成器序列的、在 0(包括)和指定值(不包括)之间均匀分布的int
值。public long nextLong()
: 返回下一个伪随机数,它是取自此随机数生成器序列的均匀分布的long
值。
Random
类中的方法都比较简单,我们一起看下其使用方法:
public static void main(String[] args) {
// 创建一个随机对象
Random random = new Random() ;
// 生成一个随机的int整数
System.out.println(random.nextInt());
// 随机生成一个[0,10)范围内的随机数
System.out.println(random.nextInt(10));
// 随机生成一个float类型的值
System.out.println(random.nextFloat());
// 随机生成一个double类型的值
System.out.println(random.nextDouble());
// 随机生成一个long类型的值
System.out.println(random.nextLong());
// 随机生成一个boolean类型的值
System.out.println(random.nextBoolean());
}
四、 日期时间类
4.1 Date类
项目中经常需要使用到日期跟时间的表示,JDK为我们提供了Date类来满足项目中的需要。虽然Date类中的很多方法都已经过时,但由于使用简单方便,我们仍然经常使用。
java.util.Date
类 表示特定的瞬间,精确到毫秒。
常用构造器:
public Date()
:分配Date对象并初始化此对象,以表示分配它的时间(精确到毫秒)。`public Date(long date)
:分配Date对象并初始化此对象,以表示自从标准基准时间(称为“历元(epoch)”,即1970年1月1日00:00:00 GMT)以来的指定毫秒数。
常用方法:
-
public void setTime(long time)
:设置此 Date 对象,以表示 1970 年 1 月 1 日 00:00:00 GMT 以后 time 毫秒的时间点。 -
public long getTime()
:返回自 1970 年 1 月 1 日 00:00:00 GMT 以来此 Date 对象表示的毫秒数。
4.1.2 API
public static void main(String[] args) {
// 创建当前时间对应的Date对象
Date date = new Date();
// 使用Date中重写的toString的格式显示日期
System.out.println(date); // Mon Dec 28 14:29:39 CST 2020
// 自从标准基准时间之间的毫秒数
System.out.println(date.getTime());// 1609137137133
// 创建日期对象,把当前的毫秒值转成日期对象
Date date2 = new Date(0);
System.out.println(date2); // Thu Jan 01 08:00:00 CST 1970
}
tips: 由于我们处于东8区,所以我们的基准时间为1970年1月1日8时0分0秒。
4.2 SimpleDateFormat类
4.2.1 概述
java.text.DateFormat
是日期/时间格式化子类的抽象类,我们通过这个类可以帮我们完成日期和文本之间的转换,也就是可以在Date对象与String对象之间进行来回转换。这里DateFormat是抽象类,故实际中我们使用它的子类java.text.SimpleDateFormat
。
实际开发中我们经常使用的时间是字符串形式,故需要经常将时间在字符串跟Date类型之间转换,把字符串形式的时间转成Date类型称为解析,把Date类型转为字符串类型成为格式化。
常用构造器:
-
public SimpleDateFormat(String pattern)
:用给定的模式和默认语言环境的日期格式符号构造SimpleDateFormat。 参数pattern是一个字符串,代表日期时间的自定义格式。
格式规则:
标识字母(区分大小写) | 含义 |
---|---|
y | 年 |
M | 月 |
d | 日 |
H | 时 |
m | 分 |
s | 秒 |
tips :更详细的格式规则,可以参考SimpleDateFormat类的API文档。
常用方法:
public String format(Date date)
:将Date对象格式化为字符串。public Date parse(String source)
:将字符串解析为Date对象。
4.2.2 API
- 将Date对象转换成自定义的格式输出。
public static void main(String[] args) throws ParseException {
// 定义当前时间点对应的Date对象
Date date = new Date();
SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss") ;
//将日期Date格式化输出
String dateString = format.format(date);
System.out.println(dateString);//2020-12-28 14:57:18
}
- 将字符串格式的日期转成Date类型
public static void main(String[] args) throws ParseException {
SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss") ;
//字符串类型的日期
String d = "20-12-28 14:55:05";
// 字符串类型的日期转成Date对象
Date date = format.parse(d);
System.out.println(date);//Sat Dec 28 14:55:05 CST 20
}
4.3 Calendar类
4.3.1 概述
上面讲解的Date类的大多数方法已经过时,JDK为我们推荐使用的Calendar类,此类表示日历。该类将所有可能用到的时间信息封装为静态成员变量,方便获取。日历类就是方便获取各个时间属性的。
4.3.2 Calendar的获取
由于Calendar类是一个抽象类,不能直接通过new来获取对象。我们需要通过其静态方法getInstance
来获取其对象类。
-
public static Calendar getInstance()
:使用默认时区和语言环境获得一个日历。import java.util.Calendar; public class CalendarDemo { public static void main(String[] args) { Calendar cal = Calendar.getInstance(); } }
4.3.3 API
-
public int get(int field)
:返回给定日历字段的值。Calendar类中提供很多成员常量,代表给定的日历字段:
字段值 含义 YEAR 年 MONTH 月(从0开始,可以+1使用) DAY_OF_MONTH 月中的天(几号) HOUR 时(12小时制) HOUR_OF_DAY 时(24小时制) MINUTE 分 SECOND 秒 DAY_OF_WEEK 周中的天(周几,周日为1,可以-1使用)
代码演示
public static void main(String[] args) {
// 创建当前时间对应的日历类
Calendar cal = Calendar.getInstance();
// 获取日历类中的年份
System.out.println(cal.get(Calendar.YEAR));//2020
// 获取日历类中的月份
System.out.println(cal.get(Calendar.MONTH));//11
// 获取日历类中的几号
System.out.println(cal.get(Calendar.DAY_OF_MONTH));//28
// 获取日历类中的小时,12小时制
System.out.println(cal.get(Calendar.HOUR));//3
// 获取日历类中的小时,24小时制
System.out.println(cal.get(Calendar.HOUR_OF_DAY));// 15
// 获取日历类中的分
System.out.println(cal.get(Calendar.MINUTE));//31
// 获取日历类中的秒
System.out.println(cal.get(Calendar.SECOND));// 36
// 获取日历类中的星期
System.out.println(cal.get(Calendar.DAY_OF_WEEK));//2
}
public void set(int field, int value)
:将给定的日历字段设置为给定值。
代码演示
public static void main(String[] args) {
// 创建当前时间对应的日历类
Calendar cal = Calendar.getInstance();
cal.set(Calendar.YEAR,2012);
cal.set(Calendar.MONTH,11);
cal.set(Calendar.DAY_OF_MONTH,12);
System.out.println(cal.get(Calendar.YEAR)+"年 "+(cal.get(Calendar.MONTH)+1)+"月 "+cal.get(Calendar.DAY_OF_MONTH)+"日");
// 2012年 12月 12日
}
tips: 月份从0开始,故显示时需要+1。星期是从周日开始。
public abstract void add(int field, int amount)
:根据日历的规则,为给定的日历字段添加或减去指定的时间量。
代码演示
public static void main(String[] args) {
Calendar cal = Calendar.getInstance();
System.out.println(cal.get(Calendar.YEAR) + "年" + (cal.get(Calendar.MONTH) + 1) + "月" + cal.get(Calendar.DAY_OF_MONTH) + "日"); // 2018年1月17日
// 2020年12月28日
// 使用add方法,将日增加1
cal.add(Calendar.DAY_OF_MONTH, 1);
// 使用add方法,将年份减去9
cal.add(Calendar.YEAR, -9);
System.out.println(cal.get(Calendar.YEAR) + "年" + (cal.get(Calendar.MONTH) + 1) + "月" + cal.get(Calendar.DAY_OF_MONTH) + "日"); // 2018年1月17日
// 2011年12月29日
}
public final Date getTime()
: 返回一个表示此 Calendar 时间值(从历元至现在的毫秒偏移量)的
Date 对象。public final void setTime(Date date)
: 使用给定的 Date 设置此 Calendar 的时间。
代码演示
// 将日历类对象转成Date对象
public static void main(String[] args) {
Calendar cal = Calendar.getInstance();
Date date = cal.getTime();
System.out.println(date); // Tue Jan 16 16:03:09 CST 2018
}
// 将Date对象转成日历类对象
public static void main(String[] args) {
Calendar cal = Calendar.getInstance();
Date date = new Date();
cal.setTime(date);
System.out.println(cal);
}
五、String类
string类的引用方式,直接采用双引号的这种定义方式,是存在字符串常量池中的,常量池是java虚拟机运行时分配的一块空间。低版本的常量池在方法区中,高版本的在堆中。
代码演示
public static void main(String[] args) {
String name = "haley";
}
方式2
通过new的方式定义,这种定义方式的字符串是存在堆内存中。
代码演示
public static void main(String[] args) {
String name =new String("haley") ;
}
-
public int length()
:返回此字符串的长度。代码演示
String name =new String("haley");
System.out.println(name.length()); //长度为5
-
public boolean equals(Object anObject)
:将此字符串与指定的对象比较。 -
public boolean equalsIgnoreCase(String anotherString)
:将此 String 与另一个 String 比较,不考虑大小写。代码演示
public static void main(String[] args) {
String name =new String("haley") ;
System.out.println(name.equals("Haley")); //false
System.out.println(name.equalsIgnoreCase("Haley")); //true
}
public String toLowerCase()
:使用默认语言环境的规则将此 String 中的所有字符都转换为小写。public String toUpperCase()
:使用默认语言环境的规则将此 String 中的所有字符都转换为大写。`
代码演示
public static void main(String[] args) {
String name =new String("Haley") ;
System.out.println(name.toLowerCase()); //haley
System.out.println(name.toUpperCase()); //HALEY
}
public String concat(String str)
: 将指定字符串连接到此字符串的结尾。
代码演示
public static void main(String[] args) {
String name =new String("hello ") ;
System.out.println(name.concat("helay")); //hello helay
System.out.println("hello "+"helay"); //hello helay
}
tips: +号用在字符串时表示拼接,字符串跟任意类型拼接结果都为字符串。
-
public int indexOf(int ch)
: 返回指定字符在此字符串中第一次出现处的索引。 -
public int indexOf(String value)
: 返回指定子字符串在此字符串中第一次出现处的索引。 -
public int lastIndexOf(int ch)
: 返回指定字符在此字符串中最后一次出现处的索引。 -
public int lastIndexOf(String value)
: 返回指定子字符串在此字符串中最右边出现处的索引。
代码演示
public static void main(String[] args) {
String word ="hello , welcome to bailiban! ";
// 返回字符97第一次出现的位置
System.out.println(word.indexOf(97)); //20
// 返回字符串ba第一次出现的位置
System.out.println(word.indexOf("ba")); //19
// 返回字符97最后一次出现的位置
System.out.println(word.lastIndexOf(97)); //25
// 返回字符串ba最后一次出现的位置
System.out.println(word.lastIndexOf("ba")); //24
}
tips: 索引都是从0开始计算。
public String substring(int index)
: 返回一个新的字符串,它是此字符串的一个子字符串。该子字符串从指定索引处的字符开始,直到此字符串末尾。public String substring(int beginindex,int endindex)
: 返回一个新字符串,它是此字符串的一个子字符串。该子字符串从指定的 beginIndex 处开始,直到索引 endIndex-1 处的字符。因此,该子字符串的长度为 endIndex-beginIndex。
代码演示
@Test
public void testString01() {
String word ="hello , welcome to bailiban! ";
System.out.println(word.substring(8)); //welcome to bailiban!
System.out.println(word.substring(8,15)); //welcome
}
public String trim()
: 返回字符串的副本,忽略前导空白和尾部空白。
代码演示
@Test
public void testString02() {
String word =" hello ";
//去掉两端的空白字符
System.out.println(word.trim()); //hello
}
public String replace(CharSequence target,CharSequence replacement)
: 使用指定的字面值替换序列替换此字符串所有匹配字面值目标序列的子字符串。
代码演示
@Test
public void testString03() {
String word ="hello , welcome to bailiban! ";
//hello子字符串替换为byebye
System.out.println(word.replace("hello","byebye")); //byebye , welcome to bailiban!
}
public char charAt(int index)
: 返回指定索引处的 char 值。索引范围为从 0 到 length() - 1。
代码演示
@Test
public void testString04() {
String word ="hello , welcome to bailiban! ";
//返回索引位置为4的内容
System.out.println(word.charAt(4)); //o
}
public String[] split(String regex)
: 根据给定正则表达式的匹配拆分此字符串。
代码演示
@Test
public void testString05() {
String word ="welcome to bailiban! ";
//以空格字符将字符串分割为数组
String[] attr = word.split(" ");
System.out.println(Arrays.toString(attr)); //[welcome, to, bailiban!]
}
六、 stringBulider和StringBuffer
上面讲的java.lang.String
类用来表示字符串,它是final
类型,故原始内容不能变更。而StringBuffer
跟StringBuilder
又称为可变字符序列,它是一个类似于 String 的字符串缓冲区, 它们可以改变该序列的长度和内容。
StringBuffer
跟StringBuilder
区别主要在于StringBuffer
是线程安全的,而StringBuilder
是线程非安全的。2者的API几乎一样。StringBuffer与StringBuilder官方推荐使用StringBuilder
2.2 构造方法
常用构造方法有2个:
-
public StringBuilder()
: 构造一个其中不带字符的字符串缓冲区。 -
public StringBuilder(String str)
:构造一个字符串缓冲区,并将其内容初始化为指定的字符串内容。
代码演示
@Test
public void testStringBuilder01() {
StringBuilder sb = new StringBuilder();
System.out.println(sb);// 空白
StringBuilder sb2 = new StringBuilder("bailiban");
System.out.println(sb2);// bailiban
}
2.3 常用方法
-
append方法
append方法具有多种重载形式,可以接收任意类型的参数。任何数据作为参数都会将对应的字符串内容添加到StringBuilder中。
代码演示
@Test
public void testStringBuilder02() {
StringBuilder sb = new StringBuilder();
sb = sb.append("hello ").append(" welcome ").append(" to ").append(" bailiban ");
System.out.println(sb);// hello welcome to bailiban
}
public StringBuffer reverse()
: 将字符串内容进行反转。
代码演示
@Test
public void testStringBuilder03() {
StringBuilder sb = new StringBuilder("bailiban");
System.out.println(sb.reverse());// nabiliab
}
tips: 这个方法是String
类所没有的,其它API方法参考String
类。
第3章 包装类
3.1 概述
JDK提供了8中基本数据类型,很多时候基本数据类型存在很多限制,不像引用类型那样提供很多API给我们使用,故JAVA为我们提供了8中基本数据类型对应的引用类型,我们称为包装类。
基本类型 | 对应的包装类 |
---|---|
byte | Byte |
short | Short |
int | Integer |
long | Long |
float | Float |
double | Double |
char | Character |
boolean | Boolean |
这些包装类都位于java.lang
包下,基本数据类型跟对应的包装类型可以自动相互转换,称为自动装箱跟自动拆箱。
-
自动装箱:从基本类型转换为对应的包装类对象。
-
自动拆箱:从包装类对象转换为对应的基本类型。
装箱代码演示
@Test
public void testInteger01(){
//将基本类型的1自动装箱为包装类Integer
Integer i = 1 ;
System.out.println(i);//1
}
拆箱代码演示
@Test
public void testInteger02(){
//定义包装类对象i
Integer i = new Integer(1) ;
//将包装类拆箱成基本类型int
int i2 = i ;
System.out.println(i2);// 1
}
3.2 常用API
8种包装类的用法类似,这里用Integer
为例。
3.2.1 字符串转成进本类型
除了Character类之外,其他包装类都具有parseXXX静态方法用来将字符串参数转换为对应的基本类型:
public static byte parseByte(String s)
:将字符串参数转换为对应的byte基本类型。public static short parseShort(String s)
:将字符串参数转换为对应的short基本类型。public static int parseInt(String s)
:将字符串参数转换为对应的int基本类型。public static long parseLong(String s)
:将字符串参数转换为对应的long基本类型。public static float parseFloat(String s)
:将字符串参数转换为对应的float基本类型。public static double parseDouble(String s)
:将字符串参数转换为对应的double基本类型。public static boolean parseBoolean(String s)
:将字符串参数转换为对应的boolean基本类型。
代码演示
@Test
public void testInteger03(){
// 将字符串类型转成对应的基本类型
int i = Integer.parseInt("99");
System.out.println(i);
}
tips: 如果转换异常会抛出NumberFormatException
异常。
3.2.2 包装类转成基本类型
包装类转成基本类型除了使用自动拆箱的方式外还可以通过类似XxxValue等方法实现。以Integer为例:
public byte byteValue()
: 以byte 类型返回该 Integer 的值。public short shortValue()
: 以 short 类型返回该 Integer 的值。public int intValue()
: 以 int 类型返回该 Integer 的值。public long longValue()
: 以 long 类型返回该 Integer 的值。public float floatValue()
: 以 float 类型返回该 Integer 的值。public double doubleValue()
: 以 double 类型返回该 Integer 的值。
代码演示
@Test
public void testInteger04(){
Integer it = new Integer(100);
// 将包装类转成基本类型
int i = it.intValue();
System.out.println(i);
}
3.2.3 进制的转换
Integer还提供一些API可以将整型类型转成其它进制的表示形式。
public static String toBinaryString(int i)
: 以二进制(基数 2)无符号整数形式返回一个整数参数的字符串表示形式。public static String toOctalString(int i)
: 以八进制(基数 8)无符号整数形式返回一个整数参数的字符串表示形式。public static String toHexString(int i)
: 以十六进制(基数 16)无符号整数形式返回一个整数参数的字符串表示形式。
代码演示
public static void main(String[] args) {
// 获取36的2进制的表示形式
System.out.println( Integer.toBinaryString(36));
// 获取36的8进制的表示形式
System.out.println( Integer.toOctalString(36));
// 获取36的16进制的表示形式
System.out.println( Integer.toHexString(36));
}
第4章 BigInteger类
整型的基本数据最大范围的是long,如果需要超过long类型的范围则需要使用`BigInteger`类。为了提高自动装箱的效率,Integer类的内部提供了一个自动装箱池,将-128到127之间的整数装箱完毕并放入池中,当程序中出现该范围的数据时则直接从池中获取并使用。
BigInteger
类在java.math
包下。
4.1 构造方法
-
public BigInteger(String val)
: 将 BigInteger 的十进制字符串表示形式转换为 BigInteger。重载了很多不同参数类型的构造方法,常用的是字符串类型的参数。
代码演示
@Test
public void testBigInteger01(){
BigInteger bi = new BigInteger("9999999999999999999999999999999999999");
System.out.println(bi);
}
4.2 成员方法
由于不是基本数据类型,不能通过+ - * /
进行运算,只能通过成分方法实现。
public BigInteger add(BigInteger val)
: 返回其值为 (this + val) 的 BigInteger。
代码演示
@Test
public void testBigInteger02(){
BigInteger b1 = new BigInteger("99999999999999999999999999999999999999999");
BigInteger b2 = new BigInteger("99999999999999999999999999999999999999999");
// 将2个BigInteger进行相加运算
System.out.println(b1.add(b2));
}
public BigInteger subtract(BigInteger val)
: 返回其值为 (this - val) 的 BigInteger。
代码演示
@Test
public void testBigInteger03(){
BigInteger b1 = new BigInteger("999999999999999999999999999999999999999999999");
BigInteger b2 = new BigInteger("111111111111111111111111111111111111111111111");
// 将2个BigInteger进行相减运算
System.out.println(b1.subtract(b2));
}
public BigInteger multiply(BigInteger val)
:返回其值为 (this * val) 的 BigInteger。
代码演示
@Test
public void testBigInteger04(){
BigInteger b1 = new BigInteger("999999999999999999999999999999999999999999999");
BigInteger b2 = new BigInteger("111111111111111111111111111111111111111111111");
// 将2个BigInteger进行相乘运算
System.out.println(b1.multiply(b2));
}
public BigInteger divide(BigInteger val)
: 返回其值为 (this / val) 的 BigInteger。
代码演示
@Test
public void testBigInteger05(){
BigInteger b1 = new BigInteger("999999999999999999999999999999999999999999999");
BigInteger b2 = new BigInteger("111111111111111111111111111111111111111111111");
// 将2个BigInteger进行相乘运算
System.out.println(b1.divide(b2)); // 9
}
第5章 BigDecimal类
前面讲过小数不能进行精确的算术运算,比如
public static void main(String[] args) {
System.out.println(0.1 + 0.2); //0.30000000000000004
}
结果并不是我们期待的0.3,而是0.30000000000000004,这是由于计算机是2进制,无法对小数进行精确的算术运算。那对某些业务比如金融需要对小数进行算术运算该怎么办呢?BigDecimal类可以解决这个问题。
BigDecimal
类在java.math
包下。
4.1 构造方法
-
public BigDecimal(String val)
: 将 BigDecimal 的字符串表示形式转换为 BigDecimal。重载了很多不同参数类型的构造方法,常用的是字符串类型的参数。
代码演示
public static void main(String[] args) {
BigDecimal bd1 = new BigDecimal("0.123456789");
}
4.2 成员方法
由于不是基本数据类型,不能通过+ - * /
进行运算,只能通过成分方法实现。
public BigDecimal add(BigDecimal augend)
: 返回一个 BigDecimal,其值为 (this + augend)。其标度为 max(this.scale(), augend.scale())。
代码演示
@Test
public void testBigDecimal02(){
BigDecimal bd1 = new BigDecimal("0.1");
BigDecimal bd2 = new BigDecimal("0.2");
// 对2个小数进行相加运算
System.out.println(bd1.add(bd2));
}
public BigDecimal subtract(BigDecimal subtrahend)
: 返回一个 BigDecimal,其值为 (this - subtrahend),其标度为max(this.scale(), subtrahend.scale())。
代码演示
@Test
public void testBigDecimal03(){
BigDecimal bd1 = new BigDecimal("0.1");
BigDecimal bd2 = new BigDecimal("0.2");
// 对2个小数进行相减运算
System.out.println(bd2.subtract(bd1));
}
public BigDecimal multiply(BigDecimal multiplicand)
:返回一个 BigDecimal,其值为 (this × multiplicand),其标度为(this.scale() + multiplicand.scale())。
代码演示
public static void main(String[] args) {
BigDecimal bd1 = new BigDecimal("0.1");
BigDecimal bd2 = new BigDecimal("0.2");
// 对2个小数进行相乘运算
System.out.println(bd2.multiply(bd1));
}
-
public BigDecimal divide(BigDecimal divisor)
: 返回一个 BigDecimal,其值为 (this / divisor),其首选标度为 (this.scale() divisor.scale());如果无法表示准确的商值(因为它有无穷的十进制扩展),则抛出ArithmeticException。 -
public BigDecimal divide(BigDecimal divisor, int scale, int roundingMode): 返回一个 BigDecimal,其值为 (this / divisor),其标度为指定标度。如果必须执行舍入,以生成具有指定标度的结果,则应用指定的舍入模式。
代码演示
public static void main(String[] args) {
BigDecimal bd1 = new BigDecimal("0.33");
BigDecimal bd2 = new BigDecimal("0.11");
// 对2个小数进行相除运算,如果除不尽则报错
System.out.println(bd1.divide(bd2));
// 对2个小数进行相除运算,如果除不尽则保留3位小数位,末尾采取四舍五入的方式
System.out.println(bd2.divide(bd1,3,BigDecimal.ROUND_HALF_UP));
}
常用的舍入模式
BigDecimal.ROUND_UP
: 始终进位。BigDecimal.ROUND_DOWN
: 始终舍弃。BigDecimal.ROUND_HALF_UP
: 四舍五入模式,如果是5则入。BigDecimal.ROUND_HALF_DOWN
: 四舍五入模式,如果是5则舍。
第6章 DecimalFormat类
java.text.DecimalFormat
是 NumberFormat
的一个具体子类,用于格式化十进制数字。该类设计有各种功能,使其能够解析和格式化任意语言环境中的数,包括对西方语言、阿拉伯语和印度语数字的支持。它还支持不同类型的数,包括整数 (123)、定点数 (123.4)、科学记数法表示的数 (1.23E4)、百分数 (12%) 和金额 ($123)。所有这些内容都可以本地化。
用法比较简单,这里举些实例。
代码演示
public static void main(String[] args) {
double pi = Math.PI;//圆周率
//取一位整数
System.out.println(new DecimalFormat("0").format(pi));//3
//取一位整数和两位小数
System.out.println(new DecimalFormat("0.00").format(pi));//3.14
//取两位整数和三位小数,整数不足部分以0填补。
System.out.println(new DecimalFormat("00.000").format(pi));// 03.142
//取所有整数部分
System.out.println(new DecimalFormat("#").format(pi));//3
//以百分比方式计数,并取两位小数
System.out.println(new DecimalFormat("#.##%").format(pi));//314.16%
long c =299792458;//光速
//显示为科学计数法,并取五位小数
System.out.println(new DecimalFormat("#.#####E0").format(c));//2.99792E8
//显示为两位整数的科学计数法,并取四位小数
System.out.println(new DecimalFormat("00.####E0").format(c));//29.9792E7
//每三位以逗号进行分隔。
System.out.println(new DecimalFormat(",###").format(c));//299,792,458
//将格式嵌入文本
System.out.println(new DecimalFormat("光速大小为每秒,###米。").format(c));
}
第7章 Enum类
7.1 概述
在开发过程中我们经常需要用到一系列有限对象个数的数据,比如星期只有周一到周日,月份只有1月到12月等等 。在JDK1.5之前主要通过一系列的静态常量完成。但是问题是这种用法操作麻烦,在1.5之后提供枚举类型来实现。
7.2 枚举的使用
-
语法定义
enum 枚举名称{ 枚举常量,枚举常量,枚举常量.... }
代码演示
public enum Genders { MALE , FEMALE ; }
tips: MALE跟FEMALE不需要指定类型,默认为当前Genders类型。
-
枚举的使用
枚举名称 变量 = 枚举名称.常量;
代码演示
@Test public void testEnum01(){ Genders person = Genders.MALE ; System.out.println(person); }
枚举中除了可以定义枚举值以外,还可以定义其它一个类可以定义的所有内容,比如属性、构造方法、成员方法等等。使用起来简单方便,但同时也需要遵守相关规则:
- 枚举是有构造方法的,默认且必须是private修饰的无参构造方法
- 构造方法可以进行重载,如果定义了构造方法则不会默认创建
- 枚举默认继承Enum类,故不能再继承其它类
- 枚举可以实现其它接口
- 枚举值的定义必须在最前面
## 7.3 常用API
由于枚举都默认继承Enum类,故所有的枚举都可以使用Enum类中的方法。
- `public final String name()`: 回此枚举常量的名称,在其枚举声明中对其进行声明。
- `public final int ordinal()`: 返回枚举常量的序数,从0开始。
- ` valueOf (Class<T> enumType, String name)` : 返回带指定名称的指定枚举类型的枚举常量。
**代码演示**
```java
@Test
public void testEnum02(){
Genders person = Genders.FEMALE ;
System.out.println(person.name());//FEMALE
System.out.println(person.ordinal());//1
Genders p1 = Enum.valueOf(Genders.class, "MALE");
System.out.println(p1.name());//MALE
System.out.println(p1.ordinal());//0
}
7.4 枚举在switch中的使用
枚举可以跟switch结合使用,此时枚举类型可以不写。
代码演示
enum Weeks {
//七个星期常量
MON,TUE,WES,THU,FRI,SAT,SUN
}
public class Demo09Enum02 {
@Test
public void testWeek(){
//定义枚举变量并赋值
Weeks week = Weeks.SAT;
//使用switch判断枚举变量
switch(week){
case MON:
System.out.println("星期一吃鱼香茄子");
break;
case TUE:
System.out.println("星期二吃蛋炒饭");
break;
case WES:
System.out.println("星期三吃小牛肉");
break;
case THU:
System.out.println("星期四吃热干面");
break;
case FRI:
System.out.println("星期五吃黄焖鸡");
break;
case SAT:
System.out.println("星期六吃泡面");
break;
case SUN:
System.out.println("星期天吃青椒肉丝");
break;
}
}
}