1. 项目概述
"sdut-Java面向对象-10 常用类(编程题8-15)"是一组针对Java常用类的编程练习题目,主要面向计算机专业学生和Java初学者。这组题目涵盖了Java标准库中最常用的几个核心类,包括String、Math、Date、Calendar等类的实际应用场景。
作为Java语言学习的重要环节,常用类的掌握程度直接影响后续开发效率。这组题目从基础到进阶,通过8个编程练习(第8题至第15题)帮助学习者深入理解这些类的API设计思想和使用技巧。我在大学任教期间,曾用类似题目训练过数百名学生,发现这是突破Java学习瓶颈的关键阶段。
2. 核心需求解析
2.1 题目设计目标
这组编程题主要考察以下几个核心能力:
- 字符串处理能力(String/StringBuilder)
- 数学运算能力(Math类)
- 日期时间处理能力(Date/Calendar)
- 包装类使用(Integer/Double等)
- 正则表达式基础应用
2.2 典型题目分析
以第10题为例,通常要求实现以下功能:
- 给定一个包含多种字符的字符串
- 统计其中字母、数字、空格和其他字符的数量
- 输出各类型字符的占比
这类题目看似简单,但涉及String的charAt()、length()方法,Character的isLetter()、isDigit()等方法,以及格式化输出的处理,非常考验对API的熟悉程度。
3. 核心实现细节
3.1 字符串处理专题
3.1.1 String与StringBuilder的选择
// 适合使用String的场景 String greeting = "Hello"; String name = "World"; String message = greeting + ", " + name + "!"; // 适合使用StringBuilder的场景 StringBuilder sb = new StringBuilder(); for(int i=0; i<100; i++){ sb.append(i).append(", "); } String result = sb.toString();关键经验:单次拼接用String,循环拼接必须用StringBuilder,否则会产生大量临时对象。
3.1.2 字符串分割与正则
String data = "Java,Python,C++,JavaScript"; String[] languages = data.split(","); // 简单分割 String complexData = "A1,B2,C3,D4"; String[] items = complexData.split("(?<=\\D)(?=\\d)|(?<=\\d)(?=\\D)"); // 复杂正则分割3.2 数学运算专题
3.2.1 Math类常用方法
double a = 3.6, b = 2.4; // 四舍五入 long rounded = Math.round(a); // 4 // 向上取整 double ceil = Math.ceil(b); // 3.0 // 向下取整 double floor = Math.floor(a); // 3.0 // 幂运算 double power = Math.pow(2, 10); // 1024.0 // 随机数 double random = Math.random(); // [0,1)3.2.2 精度处理技巧
// 保留两位小数 double value = 123.45678; double formatted = Math.round(value * 100) / 100.0; // 123.46 // 更精确的方式 DecimalFormat df = new DecimalFormat("#.##"); String result = df.format(value); // "123.46"3.3 日期时间处理专题
3.3.1 Date与Calendar转换
// Date转Calendar Date now = new Date(); Calendar cal = Calendar.getInstance(); cal.setTime(now); // Calendar转Date cal.add(Calendar.DAY_OF_MONTH, 7); Date nextWeek = cal.getTime();3.3.2 日期计算模式
// 计算两个日期相差天数 Calendar cal1 = Calendar.getInstance(); Calendar cal2 = Calendar.getInstance(); cal2.add(Calendar.MONTH, 1); long diffInMillis = cal2.getTimeInMillis() - cal1.getTimeInMillis(); long diffInDays = diffInMillis / (1000 * 60 * 60 * 24);4. 常见问题与解决方案
4.1 字符串编码问题
// 错误示范 String str = new String(bytes); // 可能产生乱码 // 正确做法 String str = new String(bytes, "UTF-8");4.2 日期格式化线程安全
// 非线程安全用法(多线程环境下可能出错) SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd"); // 线程安全方案1:每次创建新实例 // 线程安全方案2:使用ThreadLocal private static final ThreadLocal<SimpleDateFormat> dateFormat = ThreadLocal.withInitial(() -> new SimpleDateFormat("yyyy-MM-dd"));4.3 数学运算精度丢失
// 错误示范 double result = 0.1 + 0.2; // 0.30000000000000004 // 解决方案1:使用BigDecimal BigDecimal bd1 = new BigDecimal("0.1"); BigDecimal bd2 = new BigDecimal("0.2"); BigDecimal sum = bd1.add(bd2); // 0.3 // 解决方案2:限定精度范围 double epsilon = 0.000001; if(Math.abs(result - 0.3) < epsilon) { // 视为相等 }5. 高级应用技巧
5.1 正则表达式优化
// 基础匹配 String pattern = "\\d{3}-\\d{2}-\\d{4}"; // 美国社保号格式 // 预编译正则提升性能 Pattern compiledPattern = Pattern.compile(pattern); Matcher matcher = compiledPattern.matcher(input); if(matcher.matches()) { // 匹配成功 }5.2 自定义工具类封装
public class StringUtils { // 判空处理 public static boolean isBlank(String str) { return str == null || str.trim().isEmpty(); } // 反转字符串 public static String reverse(String input) { if(isBlank(input)) return input; return new StringBuilder(input).reverse().toString(); } }5.3 Java 8时间API迁移
// 传统Date转LocalDate Date date = new Date(); Instant instant = date.toInstant(); LocalDate localDate = instant.atZone(ZoneId.systemDefault()).toLocalDate(); // 日期计算更简洁 LocalDate tomorrow = LocalDate.now().plusDays(1); LocalTime nextHour = LocalTime.now().plusHours(1);6. 实战项目建议
基于这组编程题,可以扩展以下实战项目:
- 学生成绩管理系统(字符串处理+文件IO)
- 银行利息计算器(Math类应用)
- 会议日程安排工具(日期时间处理)
- 数据清洗工具(正则表达式应用)
我在实际教学中发现,当学生完成8-15题后,再让他们尝试这些实战项目,能够显著提升对Java常用类的理解深度。特别是日期时间处理部分,建议额外增加时区转换的练习,这是企业开发中的常见需求。