Java核心类库深度解析与实战:从字符串处理到计算器开发
一、字符串处理三剑客详解
1.1 String类的特性与陷阱
// 字符串常量池特性演示
String s1 = "hello";
String s2 = new String("hello");
System.out.println(s1 == s2); // false
System.out.println(s1.equals(s2)); // true// 不可变性带来的问题
String str = "a";
for(int i=0; i<10000; i++) {str += "b"; // 每次生成新对象
}
1.2 StringBuilder与StringBuffer
// 性能对比测试
public class StringPerformanceTest {public static void main(String[] args) {long startTime = System.currentTimeMillis();concatWithStringBuilder();System.out.println("StringBuilder耗时:" + (System.currentTimeMillis() - startTime));startTime = System.currentTimeMillis();concatWithStringBuffer();System.out.println("StringBuffer耗时:" + (System.currentTimeMillis() - startTime));}private static void concatWithStringBuilder() {StringBuilder sb = new StringBuilder();for(int i=0; i<100000; i++) {sb.append("test");}}private static void concatWithStringBuffer() {StringBuffer sb = new StringBuffer();for(int i=0; i<100000; i++) {sb.append("test");}}
}
1.3 选择策略
场景 | 推荐类 | 原因 |
---|---|---|
单线程字符串拼接 | StringBuilder | 非线程安全但性能最优 |
多线程环境 | StringBuffer | 线程安全 |
少量字符串操作 | String | 利用常量池优化 |
二、新一代日期时间API(Java 8+)
2.1 LocalDateTime核心用法
// 创建日期时间对象
LocalDateTime now = LocalDateTime.now();
LocalDateTime specificDate = LocalDateTime.of(2025, 7, 15, 10, 30);// 格式化输出
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
System.out.println(now.format(formatter)); // 2025-07-15 14:30:45// 时间计算
LocalDateTime tomorrow = now.plusDays(1);
LocalDateTime twoHoursLater = now.plusHours(2);// 时间比较
boolean isAfter = now.isAfter(specificDate);
2.2 常见问题处理
// 时区处理
ZonedDateTime zdt = ZonedDateTime.now(ZoneId.of("Asia/Shanghai"));// 时间间隔计算
Duration duration = Duration.between(now, tomorrow);
System.out.println("间隔秒数:" + duration.getSeconds());// 自定义格式化器
DateTimeFormatter customFormatter = new DateTimeFormatterBuilder().appendPattern("yyyy/MM/dd").parseDefaulting(ChronoField.HOUR_OF_DAY, 0).toFormatter();
三、实战项目:简易计算器开发
3.1 需求分析
- 支持加减乘除四则运算
- 支持连续运算(如:3+5*6-2)
- 错误处理(除零错误、非法输入)
- 显示运算历史记录
3.2 核心代码实现
import java.util.Scanner;
import java.util.Stack;public class SimpleCalculator {public static void main(String[] args) {Scanner scanner = new Scanner(System.in);Stack<Double> numbers = new Stack<>();Stack<Character> operators = new Stack<>();System.out.println("简易计算器(输入'exit'退出)");while (true) {System.out.print("请输入表达式:");String input = scanner.nextLine().replaceAll(" ", "");if ("exit".equalsIgnoreCase(input)) {break;}try {double result = calculate(input);System.out.println("结果:" + result);// 记录历史(使用LocalDateTime)String history = LocalDateTime.now().format(DateTimeFormatter.ofPattern("HH:mm:ss")) + " | " + input + " = " + result;System.out.println(history);} catch (Exception e) {System.out.println("错误:" + e.getMessage());}}}private static double calculate(String expr) {// 简单实现(仅支持单运算符)String[] parts = expr.split("[+\\-*/]");if (parts.length != 2) {throw new RuntimeException("表达式格式错误");}double num1 = Double.parseDouble(parts[0]);double num2 = Double.parseDouble(parts[1]);char op = expr.replaceAll("[^+\\-*/]", "").charAt(0);switch (op) {case '+': return num1 + num2;case '-': return num1 - num2;case '*': return num1 * num2;case '/': if (num2 == 0) throw new RuntimeException("除数不能为零");return num1 / num2;default: throw new RuntimeException("不支持的运算符");}}
}
3.3 扩展功能建议
- 支持复杂表达式(使用栈实现运算优先级)
// 改进版表达式解析
private static double evaluateExpression(String expr) {Stack<Double> values = new Stack<>();Stack<Character> ops = new Stack<>();int i = 0;while (i < expr.length()) {if (expr.charAt(i) == ' ') {i++;continue;}if (Character.isDigit(expr.charAt(i))) {StringBuilder sb = new StringBuilder();while (i < expr.length() && (Character.isDigit(expr.charAt(i)) || expr.charAt(i) == '.')) {sb.append(expr.charAt(i++));}values.push(Double.parseDouble(sb.toString()));continue;}while (!ops.isEmpty() && getPrecedence(ops.peek()) >= getPrecedence(expr.charAt(i))) {values.push(applyOp(ops.pop(), values.pop(), values.pop()));}ops.push(expr.charAt(i));i++;}while (!ops.isEmpty()) {values.push(applyOp(ops.pop(), values.pop(), values.pop()));}return values.pop();
}
四、性能优化技巧
4.1 字符串处理优化
// 预编译正则表达式
private static final Pattern SPLIT_PATTERN = Pattern.compile("[+\\-*/]");// 复用StringBuilder
public class StringReuser {private StringBuilder sb = new StringBuilder(1024);public String process(String input) {sb.setLength(0); // 清空而非新建对象return sb.append(input).append("_processed").toString();}
}
4.2 日期处理最佳实践
// 使用TemporalAdjusters进行日期调整
LocalDate date = LocalDate.now();
LocalDate lastDayOfMonth = date.with(TemporalAdjusters.lastDayOfMonth());// 自定义日期格式缓存
public class DateFormatterCache {private static final Map<String, DateTimeFormatter> CACHE = new ConcurrentHashMap<>();public static DateTimeFormatter getFormatter(String pattern) {return CACHE.computeIfAbsent(pattern, p -> DateTimeFormatter.ofPattern(p));}
}
五、总结
通过本文的学习,读者应该掌握:
- 字符串处理类库的选择策略和性能优化技巧
- Java 8日期时间API的现代化用法
- 实际项目开发中类库的综合应用
- 计算器开发中的核心算法实现
建议在实际开发中:
- 字符串拼接超过3次时优先使用StringBuilder
- 日期处理统一使用java.time包替代旧类
- 复杂表达式解析考虑使用ANTLR等解析器生成工具
- 关键操作添加异常处理和日志记录