更好的阅读体验:点这里 ( www.doubibiji.com
)
下面介绍一下在开发中,比较常用的类。
因为字符串创建后就无法改变了,所以在进行字符串拼接的时候,建议使用 StringBuffer
和 StringBuilder
。
使用举例:
public class StringTest {
public static void main(String[] args) {
// 创建StringBuilder
StringBuilder stringBuilder = new StringBuilder();
stringBuilder.append("Hello ");
stringBuilder.append("World");
stringBuilder.append("!");
String result1 = stringBuilder.toString(); // 将StringBuilder转换为String
System.out.println(result1); // 输出: Hello World!
// 创建StringBuilder
StringBuffer stringBuffer = new StringBuffer();
stringBuffer.append("Hello ");
stringBuffer.append("World");
stringBuffer.append("!");
String result2 = stringBuffer.toString(); // 将StringBuilder转换为String
System.out.println(result2); // 输出: Hello World!
}
}
StringBuffer 和 StringBuilder 的用法是一样的,他们的区别是 StringBuffer 是线程安全的,效率低,StringBuilder 是非线程安全的,效率高。如果是全局多线程共享数据,使用 StringBuffer。
StringBuffer
和 StringBuilder
也提供了一些其他的方法,例如插入、反转等,查一下 Java API 就可以知道了。
Java 中的 Math
类是一个提供数学函数和常量的工具类。这个类包含了执行基本数学运算的方法,例如三角函数、指数函数、对数函数、舍入函数以及生成随机数的方法等。Math
类中的方法都是静态的,因此可以直接通过类名来调用,而不需要创建 Math
类的实例。
public class MathTest {
public static void main(String[] args) {
// 返回参数的绝对值。
int absValue = Math.abs(-10); // 返回 10
// 返回两个参数中的最大值
int maxVal = Math.max(5, 10); // 返回 10
// 返回两个参数中的最小值。
int minVal = Math.min(5, 10); // 返回 5
// 将角度转换为弧度
double radians = Math.toRadians(45);
// 计算正弦值
double sinValue = Math.sin(radians);
// 计算平方根
double sqrtValue = Math.sqrt(9); // 返回 9 的平方根,应为 3.0
// 计算幂
double powValue = Math.pow(2, 3); // 返回 2 的 3 次幂,应为 8.0
// 向上取整
double ceilValue = Math.ceil(10.1); // 返回 11.0
// 向下取整
double floorValue = Math.floor(10.9); // 返回 10.0
// 四舍五入
long roundedValue = Math.round(10.75); // 返回 11
}
}
关于日期和时间的 API,只介绍 JDK8 之后的版本,之前的版本就不介绍了,自己去百度查一下 Date 和 Calendar 类的使用。
Java中的日期和时间相关的API在Java 8及其之后的版本中有了显著改进,提供了更强大、更灵活且线程安全的工具来处理日期和时间。这些新的API主要位于java.time
包中,包括了一系列类和方法,用于创建、解析、格式化、操作和比较日期和时间。
最常用的是如下几个类:
LocalDate
:表示没有时区的日期,例如:2023-03-15。LocalTime
:表示没有日期的时间,例如:10:15:30。LocalDateTime
:表示日期和时间,没有时区信息,例如:2023-03-15T10:15:30。DateTimeFormatter
:用于解析和格式化日期和时间的类。Instant
:表示从1970年01月01日0时0分0秒开始的秒数和纳秒数的精确时间。ZonedDateTime
:表示日期、时间和时区,例如2023-03-15T10:15:30+08:00[Asia/Shanghai]。主要包括创建时间、获取时间、修改时间等操作,比 JDK1.8之前的版本确实简单方便了很多。
举个栗子:
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
public class DateTest {
public static void main(String[] args) {
// 创建LocalDate
LocalDate date = LocalDate.now(); // 获取当前日期
LocalDate specificDate = LocalDate.of(2024, 4, 15); // 获取指定日期
System.out.println("日期: " + date);
System.out.println("日期: " + specificDate);
// 创建LocalTime
LocalTime time = LocalTime.now(); // 获取当前时间
LocalTime specificTime = LocalTime.of(10, 15, 30); // 获取指定时间
System.out.println("时间: " + time);
System.out.println("时间: " + specificTime);
// 创建LocalDateTime,这个类是用到最多的
LocalDateTime dateTime = LocalDateTime.now(); // 获取当前日期和时间
LocalDateTime specificDateTime = LocalDateTime.of(2024, 4, 15, 10, 15, 30); // 获取指定日期和时间
System.out.println("时间和日期: " + dateTime);
System.out.println("时间和日期: " + specificDateTime);
// 获取每个时间单位,以LocalDateTime为例
// 获取年
System.out.println(dateTime.getYear());
// 获取月
System.out.println(dateTime.getMonthValue());
// 获取日
System.out.println(dateTime.getDayOfMonth());
// 获取时
System.out.println(dateTime.getHour());
// 获取分
System.out.println(dateTime.getMinute());
// 获取秒
System.out.println(dateTime.getSecond());
// 修改时间,可以单独修改每个时间单位
LocalDateTime newDateTime = dateTime.withDayOfMonth(30); // 修改时间的月份,不是修改原对象,而是得到一个新的对象
System.out.println(newDateTime);
// 增减或减少时间
LocalDateTime newDateTime2 = dateTime.plusMonths(3); // 加3个月
System.out.println(newDateTime2);
LocalDateTime newDateTime3 = dateTime.minusYears(1); // 减一年
System.out.println(newDateTime3);
}
}
对 LocalDateTime 对象修改的时候,是得到一个新的对象,而不是修改原对象。
Instant 表示时间线上的一个瞬时点,不依赖于任何特定的时区。表示从1970年01月01日0时0分0秒开始的秒或毫秒数,也称之为时间戳,在 Java8 之前的版本中,可以通过 System.currentTimeMillis()
获取时间戳。
举个栗子:
import java.time.Instant;
import java.time.OffsetDateTime;
import java.time.ZoneOffset;
public class InstantTest {
public static void main(String[] args) {
Instant instant = Instant.now();
// 打印的时间是0时区的时间,我们是东八区,所以显示的时候看上去少了8个小时
System.out.println("当前时间: " + instant);
// 设置时区
OffsetDateTime offsetDateTime = instant.atOffset(ZoneOffset.ofHours(8)); //东八区,加了8个小时
System.out.println(offsetDateTime);
// 获取当前时间的毫秒数
long epochMilli = instant.toEpochMilli();
System.out.println("自1970-01-01T00:00:00Z以来的毫秒数: " + epochMilli);
// 通过毫秒数获取Instant
Instant newInstant = Instant.ofEpochMilli(epochMilli);
System.out.println("当前时间: " + newInstant);
}
}
需要注意,不论在哪个时区,时间戳的毫秒数是一样的,和时区没关系,只是显示时间的时候,需要指定以哪个时区的时间来显示。
因为 LocalDateTime 是没有时区信息的,如果只是时间 2024-04-15 10:10:10
,我们是没法知道它是哪里的时间,不同时区的 LocalDateTime 转换得到的 Instant 结果是不一样的,所以转换的时候,需要指定时区。
import java.time.Instant;
import java.time.LocalDateTime;
import java.time.OffsetDateTime;
import java.time.ZoneOffset;
public class DateTest {
public static void main(String[] args) {
// 创建一个 LocalDateTime 对象
LocalDateTime localDateTime = LocalDateTime.now();
// 创建一个 ZoneOffset 对象,指定LocalDateTime的时区
ZoneOffset offset = ZoneOffset.ofHours(8);
// 将 LocalDateTime 转换为 Instant,使用指定的偏移量
Instant instant = localDateTime.toInstant(offset);
// 输出显示为当前的时区
OffsetDateTime offsetDateTime = instant.atOffset(offset);
System.out.println("Instant: " + offsetDateTime);
}
}
将 Instant
转化为 LocalDateTime
需要一个时区信息。
import java.time.Instant;
import java.time.LocalDateTime;
import java.time.OffsetDateTime;
import java.time.ZoneOffset;
public class DateTest {
public static void main(String[] args) {
// 获取当前的Instant
Instant instant = Instant.now();
// 设置固定时区偏移量为UTC+8
ZoneOffset offset = ZoneOffset.ofHours(8);
// 将Instant和时区偏移量结合成ZonedDateTime
OffsetDateTime offsetDateTime = instant.atOffset(offset);
// 将OffsetDateTime转换为LocalDateTime
LocalDateTime localDateTime = offsetDateTime.toLocalDateTime();
// 输出结果
System.out.println("Instant: " + instant);
System.out.println("LocalDateTime: " + localDateTime);
}
}
在实际的开发中,经常会用到日期转换,因为将日期显示在页面上,肯定输入和显示日期的时候肯定是字符串格式的,所以就涉及到字符串和日期的相互转换。
日期格式化需要使用 java.time.format.DateTimeFormatter
类,用来指定转换的时候的字符串格式。
使用 DateTimeFormatter 定义字符的格式。
package com.doubibiji;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
public class DateTest {
// 创建一个DateTimeFormatter对象,定义输出格式
public static final DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
public static void main(String[] args) {
// 创建一个LocalDateTime对象
LocalDateTime dateTime = LocalDateTime.now();
// 将时间转换为字符串
String dateTimeString = dateTime.format(formatter);
System.out.println(dateTimeString);
}
}
yyyy-MM-dd HH:mm:ss
中 yyyy
表示年,MM
表示月,dd
表示天,后面是时分秒。
同样也是需要指定字符串的格式的,这样才知道怎么解析字符串。
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
public class DateTest {
// 创建一个DateTimeFormatter对象,定义输出格式
public static final DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
public static void main(String[] args) {
// 定义一个包含日期和时间的字符串
String dateTimeString = "2024-05-15 14:30:45";
// 将字符串转换为时间
LocalDateTime dateTime = LocalDateTime.parse(dateTimeString, formatter);
// 输出结果
System.out.println(dateTime);
}
}
旧版本时间使用的是 Date 类。
举个栗子:
import java.util.Date;
public class DateTest {
public static void main(String[] args) {
// 获取时间戳,返回当前时间与1970年1月1日0时0分0秒之间以毫秒为单位的时间差
long time = System.currentTimeMillis();
System.out.println(time);
// 创建date对象
Date date1 = new Date();
// 也可以获取时间戳
System.out.println(date1.getTime());
// 可以通过时间戳创建对象,在当前时间戳上添加60秒
Date date2 = new Date(time + 60 * 1000);
System.out.println(date2);
}
}
时间与字符的格式转换:
package com.doubibiji.hellomaven;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
public class DateTest {
public static SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
public static void main(String[] args) throws ParseException {
// 创建date对象
Date date1 = new Date();
// 1.将时间转换为字符串
String format = sdf.format(date1);
System.out.println(format);
// 2.将字符串转换为时间
String str = "2024-04-27 15:28:05";
Date date2 = sdf.parse(str);
System.out.println(date2);
}
}
其他的一些方法,可以百度一下,这里就不介绍了。
在旧版本中,如果要完成日期单位的操作,可以使用 Calendar
。
举个栗子:
package com.doubibiji.hellomaven;
import java.util.Calendar;
public class CalendarTest {
public static void main(String[] args) {
Calendar calendar = Calendar.getInstance();
// 获取年份
int year = calendar.get(Calendar.YEAR);
// 获取月份(注意月份是从0开始的)
int month = calendar.get(Calendar.MONTH) + 1;
// 获取日期
int day = calendar.get(Calendar.DAY_OF_MONTH);
System.out.println("年: " + year);
System.out.println("月: " + month);
System.out.println("日: " + day);
// 设置日期和时间
calendar.set(Calendar.YEAR, 2025);
calendar.set(Calendar.MONTH, 5); // 6月,因为月份从0开始
calendar.set(Calendar.DAY_OF_MONTH, 10);
System.out.println("设置后的日期: " + calendar.getTime());
// 在当前日期上添加5天
calendar.add(Calendar.DAY_OF_MONTH, 5);
// 在当前日期上减去2个月
calendar.add(Calendar.MONTH, -2);
// 在当前日期上减去2个月
System.out.println("设置后的日期: " + calendar.getTime());
}
}
基本数据类型(如 int
、long
)都有固定的数据表示范围,例如 long 存储的范围是 -263 到 263-1,也就是 -9223372036854775808 ~ 9223372036854775807
,超出这个范围的整数就无法表示了。而 BigInteger
则没有这样的限制,它可以处理任意大小的整数。
举个栗子:
import java.math.BigInteger;
public class BigIntegerTest {
public static void main(String[] args) {
// 创建 BigInteger 对象
BigInteger bigNum1 = new BigInteger("12345678901234567890");
BigInteger bigNum2 = new BigInteger("98765432109876543210");
// 加法
BigInteger sum = bigNum1.add(bigNum2);
System.out.println("和: " + sum);
// 减法
BigInteger difference = bigNum2.subtract(bigNum1);
System.out.println("差: " + difference);
// 乘法
BigInteger product = bigNum1.multiply(bigNum2);
System.out.println("积: " + product);
// 除法
BigInteger quotient = bigNum2.divide(bigNum1);
System.out.println("商: " + quotient);
// 模运算(取余)
BigInteger remainder = bigNum2.mod(bigNum1);
System.out.println("模: " + remainder);
}
}
在计算机中,浮点数(如 double
类型)的存储和计算是基于 IEEE 754 标准进行的,它使用二进制形式来表示小数。然而,并不是所有的十进制小数都可以精确地转换为二进制小数,这会导致精度损失和舍入误差。
举个栗子:
将 0.1
加 0.2
应该等于 0.3
。然而,由于 double
类型的精度限制,实际输出可能是类似于 0.30000000000000004
的值。
public class BigDecimalTest {
public static void main(String[] args) {
double amount1 = 0.1;
double amount2 = 0.2;
double sum = amount1 + amount2;
System.out.printf("查看小数后面的20位 sum: %.20f%n", sum); // 查看小数后面的20位 sum: 0.30000000000000004000
}
}
BigDecimal
类用于表示具有任意精度的、不可变的、任意精度的有符号十进制数。它提供了对浮点数的精确控制,特别适用于金融计算等需要高精度的场合。
举个栗子:
import java.math.BigDecimal;
import java.math.RoundingMode;
public class BigDecimalTest {
public static void main(String[] args) {
// 创建 BigDecimal 对象
BigDecimal decimal1 = new BigDecimal("123.456");
BigDecimal decimal2 = new BigDecimal("78.901");
// 加法
BigDecimal sum = decimal1.add(decimal2);
System.out.println("和: " + sum); // 和: 202.357
// 减法
BigDecimal difference = decimal1.subtract(decimal2);
System.out.println("差: " + difference); // 差: 44.555
// 乘法
BigDecimal product = decimal1.multiply(decimal2);
System.out.println("积: " + product); // 积: 9740.801856
// 除法
BigDecimal quotient = decimal1.divide(decimal2, 2, RoundingMode.HALF_UP); // 指定精度和舍入模式
System.out.println("商: " + quotient); // 商: 1.56
// 设置精度和舍入模式
BigDecimal roundedDecimal = new BigDecimal("123.456789").setScale(2, RoundingMode.HALF_UP);
System.out.println("四舍五入: " + roundedDecimal);
}
}