Java中的常用类及包装类¶
约 4628 个字 554 行代码 5 张图片 预计阅读时间 22 分钟
Math
类¶
在Java中,如果想使用一些数学方法,则可以使用Math
类中的方法,Java的Math
类具有构造方法私有及方法静态的特点,所以使用Math
类不可以创建对象,调用对应方法只需要使用类名即可调用
在Java中,Math
在java.lang
包下,所以可以不引包
Math
类常用方法¶
- 求绝对值:
static int abs(int a)
- 向上取整:
static double ceil(double a)
- 向下取整:
static double floor(double a)
- 四舍五入:
static long round(double a)
- 求两个数之间的最小值:
static int max(int a, int b)
- 求两个数之间的最大值:
static int min(int a, int b)
使用实例如下:
Java | |
---|---|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
|
需要注意,在Java中没有求三个数之间的最小值和最大值的方法,但是可以通过嵌套实现:
Java | |
---|---|
1 2 3 4 5 6 7 8 9 10 11 |
|
BigInteger
类¶
在Java中,如果遇到了一个数值的长度超过了long
类型的最大长度,则此时再进行计算会出现溢出问题,为了解决这个问题,可以使用BigInterger
类进行特别大的整数运算,常用的计算方法有加减乘除
创建BigInteger
类对象¶
使用字符串形式的数值创建BigInteger
对象:BigInteger(String val)
例如:
Java | |
---|---|
1 2 3 4 5 6 7 8 9 |
|
常用方法¶
- 加法:
BigInteger add(BigInteger val)
,调用对象数值+参数数值 - 减法:
BigInteger subtract(BigInteger val)
,调用对象数值-参数数值 - 乘法:
BigInteger multiply(BigInteger val)
,调用对象数值 * 参数数值 - 除法:
BigInteger divide(BigInteger val)
,调用对象数值 / 参数数值
使用实例如下:
Java | |
---|---|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
|
Note
BigInteger
上限:42亿的21亿次方,内存根本扛不住,所以我们可以认为BigInteger
无上限
BigDecimal
类¶
在使用float
类型和double
类型计算时,有时会出现误差,例如下面的代码:
Java | |
---|---|
1 2 3 4 5 6 7 8 9 10 |
|
当数据非常重要时,这种计算会导致资源损失,为了解决这个问题,可以使用BigDecimal
类进行相应的计算
创建BigDecimal
类对象¶
使用String
类型的数值创建对象:BigDecimal(String val)
Note
需要注意,实际上BigDecimal
类还支持使用double
类型的数值进行构造,但是根据官方文档描述,该构造方式存在不可预测性,可能转换出的结果并不完全等于输入的double
数值,所以需要考虑使用对应的方法
常用方法¶
- 将
double
类型转换为BigDecimal
类对象:static BigDecimal valueOf(double val)
- 加法:
BigDecimal add(BigDecimal val)
,调用对象数值+参数数值 - 减法:
BigDecimal subtract(BigDecimal val)
,调用对象数值-参数数值 - 乘法:
BigDecimal multiply(BigDecimal val)
,调用对象数值 * 参数数值 - 除法:
BigDecimal divide(BigDecimal val)
,调用对象数值 / 参数数值,注意,本方法在除不尽时会抛出ArithmeticException
,此时需要使用第6种除法考虑小数点后的保留部分 - 保留除法:
divide(BigDecimal divisor, int scale, RoundingMode roundingMode)
,调用对象数值 / 参数数值,第一个参数为除数,第二个参数为保留小数个数,第三个参数为保留模式,一般有DOWN
(直接截断多余部分)、UP
(保留的最后一位小数+1,其余部分截断)和HALF_UP
(四舍五入)
Note
对于第6种方法来说,有一个对应的过时方法:BigDecimal divide(BigDecimal divisor, int scale, int roundingMode)
,与推荐的方法不同的是,推荐的方法第三个参数是一个枚举类型,而过时的方法使用int
类型,对于过时的方法会存在一个注解@Deprecated
过时的方法也可以使用,只是不推荐使用,在IDEA中,使用过时的方法会看到方法上存在删除线
基本使用实例:
Java | |
---|---|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 |
|
Date
日期类¶
在Java中,存在日期类Date
,该类可以表示指定的时间,精确到毫秒(1000毫秒=1秒)
创建Date
类对象¶
Note
Date
类在util
包下,需要进行引包
一共有两个常用构造方法创建Date类对象:
- 无参构造:
Date()
,返回当前系统时间和日期 - 使用毫秒构造:
Date(long time)
,该方法会从在时间原点的基础上进行加法计算,但是会根据系统所在的时区进行相应调整
Note
时间原点:1970年1月1日 0时0分0秒(UNIX系统起始时间),叫做格林威治时间。
中国北京所在时区相对原点为1970年1月1日 8时0分0秒(差8个小时)
基本使用实例:
Java | |
---|---|
1 2 3 4 5 6 7 8 9 10 |
|
常用方法¶
- 设置时间:
void setTime(long time)
,参数是毫秒,根据时区在时间原点上加1秒 - 获取时间:
long getTime()
,返回的是毫秒值
基本使用实例:
Java | |
---|---|
1 2 3 4 5 6 7 8 9 10 11 12 |
|
Calendar
类¶
与Date
类基本一致,Calendar
类主要用于获取当前系统的年、月和日
获取Calendar
类实例¶
Note
Calendar
类在util
包下,使用前需要引包
因为Calendar
类为抽象类,所以不可以直接创建Calendar
类对象,但是提供了一个获取实例的静态方法:static Calendar getInstance()
使用如下:
Java | |
---|---|
1 2 3 4 5 6 7 8 9 |
|
上面的输出结果中:
YEAR
:表示当前年份
MONTH
:表示当前月份,需要注意,Calendar
类中的月是从0开始计算的,所以0月实际上是现实生活的1月,以此类推Calendar
类中的11月表示实际生活中的12月
DAY_OF_MONTH
:表示当前的日,例如当前是9月10日,DAY_OF_MONTH
表示的就是「10日」中的「10」
DAYE_OF_WEEK
:表示星期几,需要注意,默认情况下Java中的一周第一天为星期日,所以实际上星期日为1,星期一为2,以此类推星期六为7,所以星期二为3
HOUR_OF_DAY
:表示当前时间的小时
MINUTE
:表示当前时间的分钟
SECOND
:表示当前时间的秒数
MILLISECOND
:表示当前时间的毫秒数
Note
实际输出还存在其他内容,但是当前情况下不考虑
常用方法¶
- 返回指定字段的值:
int get(int field)
,参数可以为前面实例出现的任一字段 - 将指定字段设置为指定的数值:
void set(int field, int value)
,需要注意,如果field
为月份时,value
如果超过11,则结果为value % 12
的值 - 将指定字段减少或增加指定值:
void add(int field, int amount)
,当第二个参数为正数时,增加对应字段的值,否则减少对应字段的值 - 将
Calendar
实例转换为Date
对象:Date getTime()
- 设置具体的年月日:
void set(int year, int month, int date)
Note
上面的field
表示的字段都是Calendar
类中的静态字段,例如年是Calendar.YEAR
基本使用实例:
Java | |
---|---|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 |
|
SimpleDateFormat
类¶
使用SimpleDateFormat
类可以改变Date
类的日期时间输出显示格式
创建SimpleDateFormat
类对象¶
使用内容为指定日期时间格式的字符串进行构造:SimpleDateFormat(String pattern)
指定日期时间格式的对应部分代号如下:
时间字母表示 | 说明 |
---|---|
y | 年 |
M | 月 |
d | 日 |
H | 时 |
m | 分 |
s | 秒 |
Note
注意,代号不可以随便修改,也不可以随便更改大小写,但是可以修改个数
例如"yyyy-MM-dd HH:mm:ss"
表示「年-月-日 时:分:秒」
常用方法¶
- 将
Date
类对象按照SimpleDateFormat
类对象中的格式转换为字符串:String format(Date date)
- 将满足
SimpleDateFormat
类对象中的格式的日期时间字符串转换为Date
类对象:Date parse(String source)
,注意本方法存在转换失败异常ParseException
基本使用如下:
Java | |
---|---|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
|
JDK8新日期类¶
在JDK8中新增了两个日期类、两个日期差值计算类和一个日期格式化类,分别是LocalDate
类和LocalDateTime
类、Period
类和Duration
类与DateTimeFormatter
类
Note
这些类均在time
包下,使用前需要进行引包
LocalDate
类与LocalDateTime
类¶
LocalDate
类和LocalDateTime
类都属于不可变的日期对象,LocalDate
更侧重于年月日,而LocalDateTime
更侧重于年月日时分秒
Note
与Calendar
类不同的是,LocalDate
类和LocalDateTime
类获取到的月份与现实中的月份一一对应
因为LocalDate
类和LocalDateTime
类都属于不可变的日期类对象,所以对于修改已经创建的两种日期类对象中内容的方法实际上都是在修改一个副本,并且对应方法会返回一个同类的新对象,新对象中是原日期内容修改后的内容
获取对应类的对象¶
对于LocalDate
类来说,共有两种方式获取对象:
- 通过当前时间创建对象:
static LocalDate now()
- 通过设置指定的年月日创建对象:
static LocalDate of(int year, int month, int dayOfMonth)
基本使用如下:
Java | |
---|---|
1 2 3 4 5 6 7 8 9 10 11 12 |
|
对于LocalDateTime
类来说,与LocalDate
类基本一致,存在两个方法获取对象:
- 通过当前时间创建对象:
static LocalDateTime now()
- 通过设置指定的年月日,时分秒创建对象:
static LocalDateTime of(int year, Month month, int dayOfMonth, int hour, int minute, int second)
基本使用如下:
Java | |
---|---|
1 2 3 4 5 6 7 8 9 10 11 12 |
|
获取日期字段方法(get
方法)¶
Note
下面的方法在LocalDate
类和LocalDateTime
类中均存在,并且使用方式相同
- 获取年份:
int getYear()
- 获取月份:
int getMonthValue()
- 获取月份的第几天:
int getDayOfMonth()
基本使用代码如下:
Note
以LocalDate
类为例
Java | |
---|---|
1 2 3 4 5 6 7 8 9 10 11 12 13 |
|
设置日期字段方法(with
方法)¶
Note
下面的方法在LocalDate
类和LocalDateTime
类中均存在,并且使用方式相同
- 设置年份:
int withYear(int year)
- 设置月份:
int withMonthValue(int month)
- 设置月份的第几天:
int withDayOfMonth(int day)
基本使用代码如下:
Note
以LocalDate
类为例
Java | |
---|---|
1 2 3 4 5 6 7 8 9 10 |
|
Note
LocalDate
类和LocalDateTime
类均重写了toString()
方法
日期字段偏移¶
- 日期数值增加:
plus
系列,例如LocalDate plusYears(long yearsToAdd)
和LocalDateTime plusYears(long years)
- 日期数值减少:
minus
系列,例如LocalDate minusYears(long yearsToSubtract)
和LocalDateTime minusYears(long years)
Note
上面的函数参数都是long
类型,为了避免出现隐式类型转换,在传递参数时尽量在数值尾部加上L
基本使用如下:
Note
以LocalDate
为例
Java | |
---|---|
1 2 3 4 5 6 7 8 9 10 11 12 |
|
Period
和Duration
类¶
Period
类和Duration
类都是计算不同日期之间的差值
Text Only | |
---|---|
1 2 |
|
Note
需要注意,对于Duration
类来说,Temporal
是LocalDate
和LocalDateTime
类实现的接口,所以Duration
类计算差值的方法可以传递LocalDate
类和LocalDateTime
类对象,但是因为Duration
类计算精确时间偏差,所以需要传递能操作精确时间的 LocalDateTime
类对象
在计算日期差值时,两个方法的计算结果有些不同:Period
类的计算结果是返回相差xx年xx月xx日,而Duration
类的计算返回相差天数
计算差值后,需要使用对应的方法获取到对应的差值:
对于Period
类来说:
- 获取年差值:
int getYears()
- 获取月差值:
int getMonths()
- 获取日差值:
int getDays()
对于Duration
类来说:
- 获取天差值:
long toDays()
- 获取小时差值:
long toHours()
- 获取分钟差值:
long toMinutes()
- 获取毫秒差值:
long toMillis()
基本使用代码如下:
Java | |
---|---|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 |
|
DateTimeFormatter
类¶
Note
基本思路与SimpleDateFormat
类类似
获取对象¶
根据String
字符串中的格式设置日期时间格式static DateTimeFormatter ofPattern(String pattern)
常用方法¶
- 根据指定格式,将日期时间返回为一个
String
对象:String format(TemporalAccessor temporal)
- 将满足格式的日期时间
String
字符串转换为TemporalAccessor
对象:TemporalAccessor parse(CharSequence text)
- 将
TemporalAccessor
对象转换成LocalDate
类或者LocalDateTime
对象:static LocalDateTime from(TemporalAccessor temporal)
,这个方法属于LocalDateTime
类
Note
方法中的TemporalAccessor
是Temporal
接口继承的接口,而Temporal
类是LocalDate
类和LocalDateTime
类实现的接口,所以可以直接使用LocalDate
类和LocalDateTime
类对象
方法中的CharSequence
是String
类实现的接口,可以传递String
类对象
注意,第三种方法不可以使用向下转型代替,因为TemporalAccessor
接口不止被一个类实现
基本使用如下:
Java | |
---|---|
1 2 3 4 5 6 7 8 9 10 11 12 13 |
|
System类¶
System
类是系统相关类,是一个工具类,所以满足构造私有化和方法静态的特点
常用方法¶
- 返回以毫秒为单位的当前时间,可以测代码运行效率:
static long currentTimeMillis()
- 终止当前正在运行的 Java 虚拟机:
static void exit(int status)
,当status
为0表示正常终止,非零状态码表示异常终止 - 数组拷贝:
static void arraycopy(Object src, int srcPos, Object dest, int destPos, int length)
,其中第一个参数代表源数组,第二个参数代表拷贝起始位置(包括),第三个参数代表目标数组,第四个参数代表目标数组起始位置(包括),第四个参数表示拷贝个数(包括起始位置的数据)
基本使用代码(只使用arraycopy
方法):
Java | |
---|---|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 |
|
二维数组使用arraycopy
的浅拷贝问题与解决方案¶
需要注意,使用arraycopy
方法拷贝二维数组时需要进行深拷贝,直接使用arraycopy
方法拷贝会导致拷贝后的二维数组中的一维数组仍是原来的一维数组,例如下面的代码:
Java | |
---|---|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 |
|
出现上面的原因示意图如下:
所以实际上拷贝的方式应该是拷贝每一行每一列的数据到新二维数组每一个一维数组中:
Java | |
---|---|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 |
|
Arrays
数组工具类¶
Arrays
类是数组相关类,是一个工具类,所以满足构造私有化和方法静态的特点
常用方法¶
- 格式化打印数组:
static String toString(int[] a)
,格式:[元素1, 元素2, ...]
- 数组排序:
static void sort(int[] a)
,默认升序 - 二分查找:
static int binarySearch(int[] a, int key)
,必须保证数组升序 - 数组扩容:
static int[] copyOf(int[] original, int newLength)
- 以类似数组的创建方式将元素依次插入到
list
接口对应的实现类ArrayList
中:static <T> List<T> asList(T...a)
基本使用如下:
Java | |
---|---|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 |
|
包装类¶
包装类介绍¶
包装类是所有基本数据类型对应的类,将基本数据类型转成包装类,从而让基本数据类型可以使用成员等类的特点,需要注意的是,基本数据类型的包装类不可以使用+
、-
、*
、/
进行运算
基本类型 | 包装类 |
---|---|
byte | Byte |
short | Short |
int | Integer |
long | Long |
float | Float |
double | Double |
char | Charactor |
boolean | Boolean |
Note
因为包装类具有的属性和方法基本一致,下面以Integer
包装类为例介绍
Integer
包装类¶
Integer
是int
的包装类,现在推荐使用的构造方法如下:
Java | |
---|---|
1 |
|
过时的两种构造方法如下:
- 使用
int
类型的value
进行构造:Integer(int value)
- 使用
String
类型的数值进行构造:Integer(String s)
使用方式如下:
Java | |
---|---|
1 2 3 4 5 6 7 8 9 10 |
|
需要注意一个比较特殊的类型Boolean
构造包装类对象:
Java | |
---|---|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
|
之所以不需要考虑大小写是因为底层源码使用了忽略大小写的方式:
装箱与拆箱¶
装箱:将基本数据类型包装为包装类对象
拆箱:将包装类对象转换为基本数据类型
装箱使用到的方法如下:
- 使用包装类对应的基本数据类型构造:
static Integer valueOf(int i)
- 使用数值字符串构造:
static Integer valueOf(String s)
拆箱使用到的方法:int intValue()
Note
拆箱方法名巧记:转成什么类型,方法开头就是什么类型
基本使用代码如下:
Java | |
---|---|
1 2 3 4 5 6 7 8 9 10 |
|
自动拆箱与装箱¶
在现在的JDK中,拆箱和装箱基本都是自动完成的,但是底层调用的还是装箱和拆箱的方法
Java | |
---|---|
1 2 3 4 5 6 7 8 9 10 |
|
源码如下:
包装面试题¶
思考下面的代码运行结果:
Java | |
---|---|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
|
源码如下:
如果转换的基本数据类型值在-128
到127
之间,根据源码会直接返回数组中的数值,而对于100来说,因为在-128到127之间,所以返回数组中对应的-27
,因为是数组中同一下标对应的数值,所以valueof
函数返回的Integer
对象也是同样的对象,所以i1
和i2
的地址相同
但是对于在-128到127之外的部分,因为涉及到了new
,所以不同的调用,返回的对象都不会相同,所以使用128装箱会导致i3
和i4
地址并不相等
需要注意,并不是所有的包装类都有缓冲数组,具体见下表:
包装类 | 缓存对象 |
---|---|
Byte | -128~127 |
Short | -128~127 |
Integer | -128~127 |
Long | -128~127 |
Float | 无 |
Double | 无 |
Character | 0~127 |
Boolean | true 和false |
基本数据类型与String
类型的转换¶
基本数据类型转换String
¶
一共两种方式:
- 使用「基本数据类型+"字符串"」拼接
- 使用
String
类中的valueOf
:static String valueOf(int i)
Java | |
---|---|
1 2 3 4 5 6 7 8 9 10 |
|
String
转基本数据类型(parse
方法)¶
位置 | 方法 | 说明 |
---|---|---|
Byte | static byte parseByte(String s) | 将String 转byte 类型 |
Short | static short parseShort(String s) | 将String 转成short 类型 |
Integer | static int parseInt(String s) | 将String 转成int 类型 |
Long | static long parseLong(String s) | 将String 转成long 类型 |
Float | static float parseFloat(String s) | 将String 转成float 类型 |
Double | static double parseDouble(String s) | 将String 转成double 类型 |
Boolean | static boolean parseBoolean(String s) | 将String 转成boolean 类型 |
Note
以String
转Integer
为例
Java | |
---|---|
1 2 3 4 5 6 7 |
|
基本数据类型与String
类型转换图(以int
和String
为例)¶
标准Javabean
升级¶
前面的Javabean
中的基本数据类型可以用对应的包装类代替,例如:
Java | |
---|---|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 |
|
转换原因:
如果uid
为Integer
型,则因为引用数据类型为null
,所以Integer
默认值是null
。将来Javabean
中的数据都是和数据库表联系起来的,可以将Javabean
中的数据添加到表中,如果表中的uid
为主键自增的,此时添加语句时uid
中的数据就不用单独维护赋值了,添加语句的SQL
语句就可以这样写:insert into user(uid,username,password) values (NULL,'金莲','36666');
,后面只需要将Javabean
中封装的数据获取出来放到SQL
语句中,如果uid
为主键自增,而且Javabean
中的uid
为包装类型,默认值为null
,这样就不用单独维护uid
的值了,也不用先给Javabean
中的uid
赋值,然后在保存到数据库中了,咱们就可以直接使用uid
的默认值,将默认值放到SQL
语句的uid
列中,其次将Javabean
中的属性变成包装类,还可以使用包装类中的方法去操作此属性值