30天学会Java-11:常用类(二)
在上一章中,我们学习了 String、StringBuilder、StringBuffer、Math、System 以及 Date 和 SimpleDateFormat 等常用类。本章将继续深入探讨 Java 中其他重要的常用类,包括 Calendar 类、基本数据类型的包装类、用于高精度计算的 BigInteger 和 BigDecimal,以及生成随机数的 Random 类。
掌握这些类将进一步提升你处理各种编程任务的能力。
1. Calendar 类
java.util.Calendar 是一个抽象基类,用于在日期和时间之间进行转换,以及操作日历字段(如年、月、日、小时等)。它提供了比 Date 类更强大的日期时间操作功能,并且支持国际化。
由于 Calendar 是一个抽象类,我们通常通过其静态方法 getInstance() 来获取其实例,该方法会返回一个 GregorianCalendar 对象,这是 Calendar 的一个具体子类。
1.1 获取 Calendar 实例
import java.util.Calendar;
public class CalendarDemo {
public static void main(String[] args) {
// 获取当前时间的 Calendar 实例
Calendar calendar = Calendar.getInstance();
System.out.println("当前 Calendar 实例: " + calendar);
}
}
1.2 获取日期时间信息
Calendar 类提供了 get(int field) 方法来获取特定日历字段的值。field 参数是 Calendar 类中定义的常量,例如 Calendar.YEAR、Calendar.MONTH、Calendar.DAY_OF_MONTH 等。
注意:
Calendar.MONTH的值是从 0 开始的,即 0 表示 1 月,11 表示 12 月。Calendar.DAY_OF_WEEK的值表示星期几,通常 1 表示星期日,2 表示星期一,以此类推。
import java.util.Calendar;
public class CalendarGetInfo {
public static void main(String[] args) {
Calendar calendar = Calendar.getInstance();
int year = calendar.get(Calendar.YEAR);
// 月份从0开始,所以需要加1
int month = calendar.get(Calendar.MONTH) + 1;
int day = calendar.get(Calendar.DAY_OF_MONTH);
int hour = calendar.get(Calendar.HOUR_OF_DAY); // 24小时制
int minute = calendar.get(Calendar.MINUTE);
int second = calendar.get(Calendar.SECOND);
int dayOfWeek = calendar.get(Calendar.DAY_OF_WEEK); // 1=Sunday, 2=Monday...
System.out.println("当前时间: ");
System.out.println("年: " + year);
System.out.println("月: " + month);
System.out.println("日: " + day);
System.out.println("时: " + hour);
System.out.println("分: " + minute);
System.out.println("秒: " + second);
System.out.println("星期: " + dayOfWeek);
}
}
1.3 设置日期时间信息
Calendar 类提供了 set() 方法来设置日历字段的值,以及 add() 方法来增加或减少日历字段的值。
import java.util.Calendar;
public class CalendarSetInfo {
public static void main(String[] args) {
Calendar calendar = Calendar.getInstance();
System.out.println("初始时间: " + calendar.getTime());
// 设置年份为2025
calendar.set(Calendar.YEAR, 2025);
// 设置月份为10月 (注意:月份从0开始,所以10表示11月)
calendar.set(Calendar.MONTH, Calendar.OCTOBER);
// 设置日期为15日
calendar.set(Calendar.DAY_OF_MONTH, 15);
System.out.println("设置后的时间: " + calendar.getTime());
// 增加5天
calendar.add(Calendar.DAY_OF_MONTH, 5);
System.out.println("增加5天后的时间: " + calendar.getTime());
// 减少2小时
calendar.add(Calendar.HOUR_OF_DAY, -2);
System.out.println("减少2小时后的时间: " + calendar.getTime());
}
}
1.4 Calendar 与 Date 的转换
Calendar 和 Date 对象可以相互转换。
- 从
Calendar到Date:使用calendar.getTime()方法。 - 从
Date到Calendar:使用calendar.setTime(date)方法。
import java.util.Calendar;
import java.util.Date;
public class CalendarDateConversion {
public static void main(String[] args) {
// Date 转 Calendar
Date date = new Date();
Calendar calendar = Calendar.getInstance();
calendar.setTime(date);
System.out.println("Date 转 Calendar: " + calendar.getTime());
// Calendar 转 Date
Calendar newCalendar = Calendar.getInstance();
newCalendar.set(2023, Calendar.DECEMBER, 25, 10, 30, 0);
Date newDate = newCalendar.getTime();
System.out.println("Calendar 转 Date: " + newDate);
}
}
2. 基本数据类型的包装类
Java 为每种基本数据类型都提供了一个对应的包装类(Wrapper Class),它们都位于 java.lang 包中。包装类使得基本数据类型可以被当作对象来处理,这在集合框架中尤其重要,因为集合只能存储对象。
| 基本数据类型 | 包装类 |
|---|---|
byte | Byte |
short | Short |
int | Integer |
long | Long |
float | Float |
double | Double |
char | Character |
boolean | Boolean |
2.1 装箱与拆箱
- 装箱(Boxing):将基本数据类型转换为对应的包装类对象。
- 拆箱(Unboxing):将包装类对象转换为对应的基本数据类型。
Java 5 引入了自动装箱(Autoboxing)和自动拆箱(Auto-unboxing)机制,使得基本类型和包装类型之间的转换更加方便。
public class WrapperClassDemo {
public static void main(String[] args) {
// 手动装箱
Integer intObj1 = new Integer(100);
Boolean boolObj1 = new Boolean(true);
// 自动装箱
Integer intObj2 = 200; // 编译器自动转换为 Integer.valueOf(200);
Boolean boolObj2 = false;
System.out.println("自动装箱 intObj2: " + intObj2);
System.out.println("自动装箱 boolObj2: " + boolObj2);
// 手动拆箱
int intValue1 = intObj1.intValue();
boolean boolValue1 = boolObj1.booleanValue();
// 自动拆箱
int intValue2 = intObj2; // 编译器自动转换为 intObj2.intValue();
boolean boolValue2 = boolObj2;
System.out.println("自动拆箱 intValue2: " + intValue2);
System.out.println("自动拆箱 boolValue2: " + boolValue2);
// 包装类的常用方法
// 字符串转基本类型
String strNum = "123";
int parsedInt = Integer.parseInt(strNum);
System.out.println("字符串转int: " + parsedInt);
// 基本类型转字符串
String intToStr = String.valueOf(456);
System.out.println("int转字符串: " + intToStr);
// 比较
Integer a = 100;
Integer b = 100;
Integer c = 200;
Integer d = 200;
System.out.println("a == b: " + (a == b)); // true (在-128到127之间,Integer会缓存)
System.out.println("c == d: " + (c == d)); // false (超出缓存范围,是两个不同的对象)
System.out.println("c.equals(d): " + c.equals(d)); // true (equals方法比较的是值)
}
}
注意:
- 包装类的对象是不可变的。
Integer等包装类在-128到127之间有缓存,所以在这个范围内的相同值对象引用是相同的,超出这个范围则不是。- 进行对象比较时,应优先使用
equals()方法而不是==运算符。
3. BigInteger 和 BigDecimal
在 Java 中,int 和 long 类型能够表示的整数范围是有限的,float 和 double 类型在进行浮点数运算时可能存在精度问题。为了解决这些问题,Java 提供了 BigInteger 和 BigDecimal 类,用于支持任意精度的整数运算和高精度的浮点数运算。
3.1 BigInteger
java.math.BigInteger 支持任意大小的整数运算,可以处理超过 long 类型范围的整数。
import java.math.BigInteger;
public class BigIntegerDemo {
public static void main(String[] args) {
BigInteger num1 = new BigInteger("12345678901234567890");
BigInteger num2 = new BigInteger("98765432109876543210");
// 加法
BigInteger sum = num1.add(num2);
System.out.println("和: " + sum);
// 乘法
BigInteger product = num1.multiply(num2);
System.out.println("积: " + product);
// 除法
BigInteger quotient = num2.divide(num1);
System.out.println("商: " + quotient);
// 幂运算
BigInteger power = num1.pow(2);
System.out.println("num1的平方: " + power);
// 比较
System.out.println("num1 > num2: " + (num1.compareTo(num2) > 0));
}
}
3.2 BigDecimal
java.math.BigDecimal 支持任意精度的浮点数运算,主要用于商业计算等对精度要求非常高的场景,可以避免 float 和 double 带来的精度损失。
import java.math.BigDecimal;
import java.math.RoundingMode;
public class BigDecimalDemo {
public static void main(String[] args) {
// 推荐使用字符串构造BigDecimal,避免浮点数精度问题
BigDecimal num1 = new BigDecimal("0.1");
BigDecimal num2 = new BigDecimal("0.2");
// 加法
BigDecimal sum = num1.add(num2);
System.out.println("和: " + sum); // 0.3
// 减法
BigDecimal subtract = num2.subtract(num1);
System.out.println("差: " + subtract); // 0.1
// 乘法
BigDecimal product = num1.multiply(num2);
System.out.println("积: " + product); // 0.02
// 除法 (需要指定精度和舍入模式)
BigDecimal divide = new BigDecimal("10").divide(new BigDecimal("3"), 2, RoundingMode.HALF_UP);
System.out.println("商 (保留两位小数,四舍五入): " + divide); // 3.33
// 比较
BigDecimal bd1 = new BigDecimal("1.0");
BigDecimal bd2 = new BigDecimal("1.00");
System.out.println("bd1 == bd2 (equals): " + bd1.equals(bd2)); // false (equals会比较值和精度)
System.out.println("bd1 == bd2 (compareTo): " + (bd1.compareTo(bd2) == 0)); // true (compareTo只比较值)
}
}
注意:
BigDecimal的构造方法推荐使用字符串作为参数,以避免浮点数本身的精度问题。- 进行除法运算时,必须指定精度和舍入模式,否则可能会抛出
ArithmeticException。 equals()方法会比较值和精度,而compareTo()方法只比较值。
4. Random 类
java.util.Random 类用于生成伪随机数。它提供了多种方法来生成不同类型的随机数(如 int、long、float、double 等)。
4.1 创建 Random 实例
- 无参构造函数:
new Random(),使用当前时间的毫秒数作为种子,每次运行程序生成的随机数序列可能不同。 - 有参构造函数:
new Random(long seed),使用固定的种子,每次运行程序生成的随机数序列是相同的(伪随机)。
import java.util.Random;
public class RandomDemo {
public static void main(String[] args) {
// 无参构造函数:每次运行结果可能不同
Random random1 = new Random();
System.out.println("随机数1 (无参): " + random1.nextInt(100)); // 生成0到99之间的随机整数
// 有参构造函数:每次运行结果相同 (伪随机)
Random random2 = new Random(123L); // 使用固定种子
System.out.println("随机数2 (有参,种子123): " + random2.nextInt(100));
Random random3 = new Random(123L); // 相同的种子
System.out.println("随机数3 (有参,种子123): " + random3.nextInt(100));
}
}
4.2 生成随机数
Random 类提供了以下常用方法来生成随机数:
nextInt():生成一个随机的int整数(范围是所有int值)。nextInt(int bound):生成一个0(包括)到bound(不包括)之间的随机int整数。nextLong():生成一个随机的long整数。nextFloat():生成一个0.0f(包括)到1.0f(不包括)之间的随机float浮点数。nextDouble():生成一个0.0d(包括)到1.0d(不包括)之间的随机double浮点数。nextBoolean():生成一个随机的boolean值。
import java.util.Random;
public class RandomNumberGeneration {
public static void main(String[] args) {
Random random = new Random();
// 生成一个随机整数
int randInt = random.nextInt();
System.out.println("随机整数: " + randInt);
// 生成0到99之间的随机整数
int randIntBounded = random.nextInt(100);
System.out.println("0-99随机整数: " + randIntBounded);
// 生成一个随机长整数
long randLong = random.nextLong();
System.out.println("随机长整数: " + randLong);
// 生成一个随机浮点数 (0.0f 到 1.0f)
float randFloat = random.nextFloat();
System.out.println("随机浮点数: " + randFloat);
// 生成一个随机双精度浮点数 (0.0d 到 1.0d)
double randDouble = random.nextDouble();
System.out.println("随机双精度浮点数: " + randDouble);
// 生成一个随机布尔值
boolean randBoolean = random.nextBoolean();
System.out.println("随机布尔值: " + randBoolean);
// 生成指定范围的随机数 (例如:10到20之间)
// 公式:min + random.nextInt(max - min + 1)
int min = 10;
int max = 20;
int randInRange = min + random.nextInt(max - min + 1);
System.out.println(min + "到" + max + "之间的随机整数: " + randInRange);
}
}
总结
本章我们深入学习了 Java 中几个重要的常用类:
Calendar类:提供了强大的日期时间操作功能,支持获取、设置和修改日期时间字段,并能与Date对象进行转换。- 基本数据类型的包装类:实现了基本数据类型与对象之间的转换(装箱与拆箱),使得基本类型可以在需要对象的地方使用,并提供了类型转换等实用方法。
BigInteger和BigDecimal:解决了int/long的整数范围限制和float/double的浮点数精度问题,适用于需要高精度计算的场景。Random类:用于生成伪随机数,可以生成各种类型的随机数,并支持通过种子控制随机数序列的重复性。
掌握这些常用类将极大地提升你在 Java 编程中处理各种数据和业务逻辑的能力。在实际开发中,它们是不可或缺的工具。
&spm=1001.2101.3001.5002&articleId=149727190&d=1&t=3&u=a3c2aefad99c49a89204f05d31351a0c)
1059

被折叠的 条评论
为什么被折叠?



