30天学会Java-11:常用类(二)

30天学会Java-11:常用类(二)

在上一章中,我们学习了 StringStringBuilderStringBufferMathSystem 以及 DateSimpleDateFormat 等常用类。本章将继续深入探讨 Java 中其他重要的常用类,包括 Calendar 类、基本数据类型的包装类、用于高精度计算的 BigIntegerBigDecimal,以及生成随机数的 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.YEARCalendar.MONTHCalendar.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 CalendarDate 的转换

CalendarDate 对象可以相互转换。

  • CalendarDate:使用 calendar.getTime() 方法。
  • DateCalendar:使用 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 包中。包装类使得基本数据类型可以被当作对象来处理,这在集合框架中尤其重要,因为集合只能存储对象。

基本数据类型包装类
byteByte
shortShort
intInteger
longLong
floatFloat
doubleDouble
charCharacter
booleanBoolean

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 等包装类在 -128127 之间有缓存,所以在这个范围内的相同值对象引用是相同的,超出这个范围则不是。
  • 进行对象比较时,应优先使用 equals() 方法而不是 == 运算符。

3. BigIntegerBigDecimal

在 Java 中,intlong 类型能够表示的整数范围是有限的,floatdouble 类型在进行浮点数运算时可能存在精度问题。为了解决这些问题,Java 提供了 BigIntegerBigDecimal 类,用于支持任意精度的整数运算和高精度的浮点数运算。

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 支持任意精度的浮点数运算,主要用于商业计算等对精度要求非常高的场景,可以避免 floatdouble 带来的精度损失。

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 类用于生成伪随机数。它提供了多种方法来生成不同类型的随机数(如 intlongfloatdouble 等)。

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 对象进行转换。
  • 基本数据类型的包装类:实现了基本数据类型与对象之间的转换(装箱与拆箱),使得基本类型可以在需要对象的地方使用,并提供了类型转换等实用方法。
  • BigIntegerBigDecimal:解决了 int/long 的整数范围限制和 float/double 的浮点数精度问题,适用于需要高精度计算的场景。
  • Random:用于生成伪随机数,可以生成各种类型的随机数,并支持通过种子控制随机数序列的重复性。

掌握这些常用类将极大地提升你在 Java 编程中处理各种数据和业务逻辑的能力。在实际开发中,它们是不可或缺的工具。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

明似水

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值