【Java 基础编程】Java 常用类速查:包装类、String/StringBuilder、Math、日期类一篇搞定

常用类是 Java 开发中频繁使用的工具类,掌握这些类的使用方法和特点能够提高开发效率,编写更加规范的代码。

⚡ 快速参考

  • 包装类:将基本类型封装成对象,支持自动装箱和拆箱
  • String 类:不可变字符串,使用 + 拼接会创建新对象
  • StringBuffer:可变字符串,线程安全,适合多线程环境
  • StringBuilder:可变字符串,线程不安全,性能更高,推荐使用
  • Math 类:提供数学运算的静态方法
  • 日期类:Date、Calendar、LocalDateTime(Java 8+)

📚 学习目标

  1. 理解包装类的概念和自动装箱拆箱机制
  2. 掌握 String 类的常用方法和不可变性
  3. 理解 String、StringBuffer、StringBuilder 的区别
  4. 掌握 Math 类的常用方法
  5. 掌握日期类的使用和格式化

一、常用类概述

1.1 什么是常用类?

常用类: Java 提供的一系列工具类,包括包装类、字符串类、数学类、日期类等,用于处理常见的编程任务。

核心类:

  • 包装类:将基本类型封装成对象
  • String 类:处理字符串
  • StringBuffer/StringBuilder:处理可变字符串
  • Math 类:数学运算
  • 日期类:处理日期和时间

二、包装类

2.1 包装类的概念

包装类(Wrapper Class): 将基本数据类型封装成对象。

为什么需要包装类?

  • 基本类型不是对象,无法调用方法
  • 泛型不支持基本类型
  • 需要 null 值表示"无"

2.2 八大包装类

基本类型 包装类 父类
byte Byte Number
short Short Number
int Integer Number
long Long Number
float Float Number
double Double Number
char Character Object
boolean Boolean Object

2.3 装箱和拆箱

装箱: 基本类型 → 包装类
拆箱: 包装类 → 基本类型

手动装箱拆箱(JDK 5之前):

java 复制代码
// 手动装箱
int n1 = 100;
Integer integer1 = new Integer(n1);      // 方式1
Integer integer2 = Integer.valueOf(n1);  // 方式2(推荐)

// 手动拆箱
int n2 = integer1.intValue();

自动装箱拆箱(JDK 5之后,推荐):

java 复制代码
// 自动装箱
int n1 = 100;
Integer integer = n1;  // 底层:Integer.valueOf(n1)

// 自动拆箱
int n2 = integer;  // 底层:integer.intValue()

1.4 包装类型转换

包装类 ↔ String:

java 复制代码
// Integer → String
Integer i = 100;
String s1 = i + "";                // 方式1
String s2 = i.toString();          // 方式2
String s3 = String.valueOf(i);     // 方式3(推荐)

// String → Integer
String s = "123";
Integer i1 = Integer.parseInt(s);  // 方式1(自动装箱)
Integer i2 = new Integer(s);       // 方式2

1.5 Integer 常用方法

java 复制代码
// 常量
System.out.println(Integer.MIN_VALUE);  // -2147483648
System.out.println(Integer.MAX_VALUE);  // 2147483647

// 方法
Integer.parseInt("123");      // 字符串转int
Integer.valueOf("123");       // 字符串转Integer
Integer.toBinaryString(10);   // 十进制转二进制字符串
Integer.toHexString(255);     // 十进制转十六进制字符串

1.6 Character 常用方法

java 复制代码
Character.isDigit('5');       // 判断是否是数字
Character.isLetter('a');      // 判断是否是字母
Character.isUpperCase('A');   // 判断是否是大写
Character.isLowerCase('a');   // 判断是否是小写
Character.isWhitespace(' ');  // 判断是否是空白字符
Character.toUpperCase('a');   // 转大写
Character.toLowerCase('A');   // 转小写

1.7 包装类的缓存机制

Integer 缓存: -128 ~ 127

java 复制代码
Integer a = 127;
Integer b = 127;
System.out.println(a == b);  // true(使用缓存)

Integer c = 128;
Integer d = 128;
System.out.println(c == d);  // false(超出缓存范围,创建新对象)

// 建议:包装类比较使用 equals()
System.out.println(c.equals(d));  // true

三、String类

2.1 String 的特点

特点:

  1. String 对象用于保存字符串(字符序列)
  2. 字符串使用 Unicode 编码,一个字符占 2 个字节
  3. String 是 final 类,不能被继承
  4. String 实现了 Serializable(可序列化)、Comparable(可比较)接口
  5. 底层是 char[] value(JDK 8)或 byte[] value(JDK 9+)
  6. String 是不可变的(value 数组是 final 的)

2.2 String 的创建方式

方式一:直接赋值(推荐)

java 复制代码
String s1 = "hello";  // 指向常量池
String s2 = "hello";  // 复用常量池中的对象
System.out.println(s1 == s2);  // true

方式二:使用构造器

java 复制代码
String s3 = new String("hello");  // 在堆中创建对象
String s4 = new String("hello");  // 在堆中创建新对象
System.out.println(s3 == s4);     // false

内存分析:

复制代码
栈         常量池        堆
s1 ────→  "hello"
s2 ────→    ↑
s3 ────────────────→ String对象 ──→ "hello"
s4 ────────────────→ String对象 ──→ "hello"

2.3 String 的拼接

规则:

  1. 常量相加:在常量池
  2. 变量相加:在堆中(通过 StringBuilder 实现)
java 复制代码
// 1. 常量相加
String s1 = "hello" + "world";  // 编译优化为 "helloworld",在常量池

// 2. 变量相加
String a = "hello";
String b = "world";
String s2 = a + b;  // 在堆中创建新对象

// 底层实现:
// StringBuilder sb = new StringBuilder();
// sb.append(a);
// sb.append(b);
// String s2 = sb.toString();

System.out.println(s1 == s2);  // false

2.4 String 常用方法

判断类:

java 复制代码
String s = "Hello World";

s.equals("hello");          // false(比较内容,区分大小写)
s.equalsIgnoreCase("hello");// true(忽略大小写)
s.isEmpty();                // false(判断是否为空)
s.startsWith("He");         // true(是否以指定字符串开头)
s.endsWith("ld");           // true(是否以指定字符串结尾)
s.contains("lo");           // true(是否包含)

查找类:

java 复制代码
String s = "hello world";

s.length();                 // 11(字符串长度)
s.charAt(0);                // 'h'(获取指定索引的字符)
s.indexOf('o');             // 4(第一次出现的索引)
s.lastIndexOf('o');         // 7(最后一次出现的索引)

提取类:

java 复制代码
String s = "Hello World";

s.substring(6);             // "World"(从索引6到末尾)
s.substring(0, 5);          // "Hello"(从索引0到5,不含5)

转换类:

java 复制代码
String s = "Hello World";

s.toUpperCase();            // "HELLO WORLD"(转大写)
s.toLowerCase();            // "hello world"(转小写)
s.trim();                   // 去除前后空格
s.replace('l', 'L');        // "HeLLo WorLd"(替换字符)
s.replace("World", "Java"); // "Hello Java"(替换字符串)

分割类:

java 复制代码
String s = "apple,banana,orange";
String[] arr = s.split(",");  // ["apple", "banana", "orange"]

// 特殊字符需要转义
String s2 = "a|b|c";
String[] arr2 = s2.split("\\|");  // ["a", "b", "c"]

转换为字符数组:

java 复制代码
String s = "hello";
char[] chars = s.toCharArray();  // ['h', 'e', 'l', 'l', 'o']

格式化字符串:

java 复制代码
String name = "张三";
int age = 20;
double score = 95.5;

String info = String.format("姓名:%s,年龄:%d,成绩:%.2f", name, age, score);
System.out.println(info);  // 姓名:张三,年龄:20,成绩:95.50

2.5 String 常见面试题

题目1:创建了几个对象?

java 复制代码
String s = new String("hello");

答案: 2个

  • 常量池中的 "hello"
  • 堆中的 String 对象

题目2:下面代码的输出?

java 复制代码
String s1 = "hello";
String s2 = "hello";
String s3 = new String("hello");

System.out.println(s1 == s2);      // ?
System.out.println(s1 == s3);      // ?
System.out.println(s1.equals(s3)); // ?

答案:

  • s1 == s2:true(指向同一个常量池对象)
  • s1 == s3:false(s3 在堆中)
  • s1.equals(s3):true(内容相同)

四、StringBuffer类

3.1 StringBuffer 的特点

特点:

  1. 代表可变的字符序列
  2. 线程安全(方法加了 synchronized)
  3. 效率比 String 高(修改时不创建新对象)
  4. 底层:char[] value(可变数组)
  5. 是 final 类,不能被继承

3.2 String vs StringBuffer

特性 String StringBuffer
可变性 不可变 可变
线程安全 安全 安全
效率 低(频繁创建对象)
使用场景 字符串不变 频繁修改

3.3 StringBuffer 的创建

java 复制代码
// 方式1:无参构造器(初始容量16)
StringBuffer sb1 = new StringBuffer();

// 方式2:指定容量
StringBuffer sb2 = new StringBuffer(100);

// 方式3:通过字符串创建
StringBuffer sb3 = new StringBuffer("hello");

3.4 String 和 StringBuffer 的转换

String → StringBuffer:

java 复制代码
String str = "hello";

// 方式1:使用构造器
StringBuffer sb1 = new StringBuffer(str);

// 方式2:使用 append()
StringBuffer sb2 = new StringBuffer();
sb2.append(str);

StringBuffer → String:

java 复制代码
StringBuffer sb = new StringBuffer("hello");

// 方式1:使用 toString()(推荐)
String s1 = sb.toString();

// 方式2:使用构造器
String s2 = new String(sb);

3.5 StringBuffer 常用方法

java 复制代码
StringBuffer sb = new StringBuffer("hello");

// 1. append():追加
sb.append(" world");      // "hello world"
sb.append(123);           // "hello world123"

// 2. delete():删除
sb.delete(5, 11);         // "hello123"(删除索引5到11,不含11)

// 3. replace():替换
sb.replace(0, 5, "hi");   // "hi123"(替换索引0到5)

// 4. indexOf():查找
int index = sb.indexOf("123");  // 2

// 5. insert():插入
sb.insert(2, "aaa");      // "hiaa123"(在索引2处插入)

// 6. length():获取长度
int len = sb.length();    // 7

// 7. reverse():反转
sb.reverse();             // "321aahi"

五、StringBuilder类

4.1 StringBuilder 的特点

特点:

  1. 代表可变的字符序列
  2. 线程不安全(方法没有 synchronized)
  3. 效率最高
  4. 底层:char[] value(可变数组)
  5. 与 StringBuffer 方法完全相同

4.2 三者对比

特性 String StringBuffer StringBuilder
可变性 不可变 可变 可变
线程安全 安全 安全 不安全
效率 较高 最高
使用场景 少量修改 多线程频繁修改 单线程频繁修改

效率测试:

java 复制代码
long start = System.currentTimeMillis();

// String:最慢
String s = "";
for (int i = 0; i < 100000; i++) {
    s += i;
}

// StringBuffer:较快
StringBuffer sb = new StringBuffer();
for (int i = 0; i < 100000; i++) {
    sb.append(i);
}

// StringBuilder:最快
StringBuilder sbd = new StringBuilder();
for (int i = 0; i < 100000; i++) {
    sbd.append(i);
}

long end = System.currentTimeMillis();

效率: StringBuilder > StringBuffer > String

4.3 使用原则

选择建议:

  1. 字符串很少修改 → String
  2. 单线程大量修改 → StringBuilder(推荐)
  3. 多线程大量修改 → StringBuffer

六、Math类

5.1 Math 常用方法

java 复制代码
// 1. abs():绝对值
Math.abs(-10);          // 10

// 2. pow():幂运算
Math.pow(2, 3);         // 8.0(2的3次方)

// 3. sqrt():平方根
Math.sqrt(16);          // 4.0

// 4. ceil():向上取整
Math.ceil(3.1);         // 4.0

// 5. floor():向下取整
Math.floor(3.9);        // 3.0

// 6. round():四舍五入
Math.round(3.5);        // 4
Math.round(3.4);        // 3

// 7. random():随机数 [0, 1)
Math.random();          // 0.xxxx

// 8. max()、min():最大最小值
Math.max(10, 20);       // 20
Math.min(10, 20);       // 10

// 9. PI、E常量
Math.PI;                // 3.141592653589793
Math.E;                 // 2.718281828459045

5.2 生成随机数

生成 [a, b] 范围的随机整数:

java 复制代码
// 公式:(int)(Math.random() * (b - a + 1)) + a

// 示例:生成 [10, 20] 的随机数
int num = (int)(Math.random() * 11) + 10;

七、日期类

6.1 Date 类(第一代)

java 复制代码
import java.util.Date;
import java.text.SimpleDateFormat;

// 1. 获取当前时间
Date date = new Date();
System.out.println(date);  // Thu Jan 18 18:30:00 CST 2025

// 2. 格式化日期
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
String dateStr = sdf.format(date);
System.out.println(dateStr);  // 2025-01-18 18:30:00

// 3. 字符串 → Date
String str = "2025-01-18 18:30:00";
Date date2 = sdf.parse(str);

6.2 Calendar 类(第二代)

java 复制代码
import java.util.Calendar;

// 1. 获取Calendar实例
Calendar cal = Calendar.getInstance();

// 2. 获取日期信息
int year = cal.get(Calendar.YEAR);
int month = cal.get(Calendar.MONTH) + 1;  // 月份从0开始,要+1
int day = cal.get(Calendar.DAY_OF_MONTH);
int hour = cal.get(Calendar.HOUR_OF_DAY);  // 24小时制
int minute = cal.get(Calendar.MINUTE);
int second = cal.get(Calendar.SECOND);

// 3. 设置日期
cal.set(2025, 0, 18);  // 设置为2025年1月18日

// 4. 日期计算
cal.add(Calendar.DAY_OF_MONTH, 10);  // 加10天

6.3 LocalDateTime 类(第三代,JDK 8+,推荐)

java 复制代码
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;

// 1. 获取当前时间
LocalDateTime now = LocalDateTime.now();
System.out.println(now);  // 2025-01-18T18:30:00

// 2. 获取日期信息
int year = now.getYear();
int month = now.getMonthValue();
int day = now.getDayOfMonth();
int hour = now.getHour();
int minute = now.getMinute();
int second = now.getSecond();

// 3. 格式化
DateTimeFormatter dtf = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
String dateStr = now.format(dtf);
System.out.println(dateStr);  // 2025-01-18 18:30:00

// 4. 字符串 → LocalDateTime
String str = "2025-01-18 18:30:00";
LocalDateTime ldt = LocalDateTime.parse(str, dtf);

// 5. 日期计算
LocalDateTime future = now.plusDays(10);   // 加10天
LocalDateTime past = now.minusMonths(2);   // 减2个月

八、面试常见问题

Q1: String 为什么设计成不可变的?

答案:

  1. 安全性:String 常用于网络传输、文件路径、参数传递
  2. 线程安全:不可变对象天然线程安全
  3. 常量池优化:可以复用对象,节省内存
  4. hashCode 缓存:不可变,hashCode 只需计算一次

Q2: String、StringBuffer、StringBuilder 的区别?

答案:

特性 String StringBuffer StringBuilder
可变性 不可变 可变 可变
线程安全 安全 安全 不安全
效率 较高 最高

选择建议:

  • 少量修改 → String
  • 单线程频繁修改 → StringBuilder
  • 多线程频繁修改 → StringBuffer

Q3: == 和 equals() 对于 String 的区别?

答案:

  • ==:比较引用(地址)
  • equals():比较内容
java 复制代码
String s1 = "hello";
String s2 = "hello";
String s3 = new String("hello");

s1 == s2;        // true(指向同一个常量池对象)
s1 == s3;        // false(s3 在堆中)
s1.equals(s3);   // true(内容相同)

Q4: String s = new String("hello") 创建了几个对象?

答案: 2个

  1. 常量池中的 "hello"
  2. 堆中的 String 对象

Q5: String 的 intern() 方法的作用?

答案:

intern() 方法会在常量池中查找是否有相同内容的字符串:

  • 如果有,返回常量池中的引用
  • 如果没有,将字符串添加到常量池,并返回引用
java 复制代码
String s1 = "hello";
String s2 = new String("hello");

System.out.println(s1 == s2);          // false
System.out.println(s1 == s2.intern()); // true
相关推荐
寒秋花开曾相惜2 小时前
(学习笔记)2.2 整数表示(2.2.6 扩展一个数字的位表示)
c语言·开发语言·笔记·学习
weixin_440401692 小时前
Python数据分析(Series+DataFrame+部分运算+groupby)
开发语言·python·数据分析
宇木灵2 小时前
C语言基础-八、结构体和共同(用)体
c语言·开发语言·数据结构·笔记·学习·算法
拳里剑气2 小时前
C++ 11
开发语言·c++·学习方法
盖头盖2 小时前
【Java反序列化之tabby半自动化挖掘新URLDNS链】
java
孞㐑¥2 小时前
算法—穷举,爆搜,深搜,回溯,剪枝
开发语言·c++·经验分享·笔记·算法
2401_828890642 小时前
通用唤醒词识别模型 - Wav2Vec2
人工智能·python·深度学习·audiolm
黄昏晓x2 小时前
C++----异常
android·java·c++
nita张2 小时前
2026年2月实战案例分享:合肥战略定位成果解析
人工智能·python