常用工具类
java提供了许多实用的工具类,可以大大提高开发效率。以下是java中最实用的工具类分类介绍
1.集合工具类
java.util.Collections
提供对集合操作的静态方法
常用的方法
Collections.sort(list); // 排序
Collections.reverse(list); // 反转
Collections.shuffle(list); // 随机打乱
Collections.max(list); // 获取最大值
Collections.min(list); // 获取最小值
Collections.binarySearch(list, key); // 二分查找
Collections.synchronizedList(list); // 获取线程安全集合
java.util.Arrays
数组操作工具类
常用方法
Arrays.sort(arr); // 数组排序
Arrays.binarySearch(arr, key); // 二分查找
Arrays.copyOf(arr, newLength); // 数组复制
Arrays.equals(arr1, arr2); // 数组比较
Arrays.fill(arr, value); // 填充数组
Arrays.toString(arr); // 数组转字符串
2.字符串工具类
org.apache.commons.lang3.StringUtils(Apache Commons Lang)
比JDK的String类提供更多的功能
常用方法
StringUtils.isEmpty(str); // 判断空字符串
StringUtils.isBlank(str); // 判断空白字符串
StringUtils.join(array, separator); // 数组/集合拼接
StringUtils.split(str, separator); // 字符串分割
StringUtils.trim(str); // 去除两端空格
StringUtils.substring(str, start, end); // 截取子串
java.util.StringJoiner
(JDK 8+)
用于构造由分隔符分隔的字符序列
示例:
StringJoiner sj = new StringJoiner(",", "[", "]");
sj.add("A").add("B").add("C");
System.out.println(sj); // 输出: [A,B,C]
3.日期时间工具类
java.time包(JDK 8+)
LocalDate – 日期
LocalTime – 时间
LocalDateTime – 日期时间
DateTimeFoermatter – 日期格式化
示例
LocalDate today = LocalDate.now();
LocalDateTime now = LocalDateTime.now();
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
String formatted = now.format(formatter);
org.apache.commons.lang3.time.ateUtils(Apche Commons Lang)
提供日期操作功能
常用方法
DateUtils.addDays(date, 1); // 添加天数
DateUtils.addHours(date, 1); // 添加小时
DateUtils.truncate(date, Calendar.DAY_OF_MONTH); // 截断时间
4.数学工具类
java.lang.Math
基本数学运算
常用方法
Math.abs(-1); // 绝对值
Math.max(a, b); // 最大值
Math.min(a, b); // 最小值
Math.sqrt(9); // 平方根
Math.pow(2, 3); // 幂运算
Math.round(3.14); // 四舍五入
Math.random(); // 随机数 [0,1)
java.math.BigDecimal
精确的十进制运算
示例
BigDecimal bd1 = new BigDecimal("0.1");
BigDecimal bd2 = new BigDecimal("0.2");
BigDecimal sum = bd1.add(bd2); // 0.3 (精确)
5.IO/文件工具类
org.apache.commons.io.FileUtils(Apach Commons IO)
文件操作工具
常用方法
FileUtils.readFileToString(file, "UTF-8"); // 读取文件内容
FileUtils.writeStringToFile(file, content); // 写入文件
FileUtils.copyFile(src, dest); // 复制文件
FileUtils.deleteDirectory(dir); // 删除目录
Org.apache.commons.io.IOUtils(Apache Commons IO)
IO流操作工具
常用方法
IOUtils.copy(inputStream, outputStream); // 流复制
IOUtils.toString(inputStream, "UTF-8"); // 流转字符串
IOUtils.closeQuietly(closeable); // 安静关闭流
6.反射工具类
org.apache.commons.lang3.reflect.FieldUtils(Apache Commons Lang)
反射操作工具
常用方法
FieldUtils.readField(obj, "fieldName", true); // 读取字段值
FieldUtils.writeField(obj, "fieldName", value, true); // 设置字段值
7.其他实用工具类
java.util.Objects(JDK 7+)
对象操作工具
常用方法
Objects.equals(a, b); // 安全的对象比较
Objects.hashCode(obj); // 安全的哈希码
Objects.requireNonNull(obj); // 非空检查
org.apache.commons.lang3.RandomUtils(Apache Commons Lang)
随机数生成
常用方法
RandomUtils.nextInt(startInclusive, endExclusive); // 随机整数
RandomUtils.nextDouble(startInclusive, endExclusive); // 随机浮点数
使用建议
优先使用 JDK 自带的工具类
对于复杂操作,可以考虑引入 Apache Commons Lang/IO 等第三方库
注意线程安全问题,特别是集合工具类
对于日期操作,推荐使用 JDK 8 的 java.time
包
这些工具类可以显著减少样板代码,提高开发效率和代码质量。
正则和枚举
正则表达式
1.基本正则表达式类
java提供了java.util.regex包来处理正则表达式,
主要包含了两个类
Pattern:真个则表达式的编译表示
Matcher:通过解释Pattern对字符序列执行匹配操作的引擎
java正则表达式的基本用法
import java.util.regex.*;
public class RegexBasic {
public static void main(String[] args) {
// 1. 简单匹配
Pattern pattern = Pattern.compile("hello");
Matcher matcher = pattern.matcher("hello world");
System.out.println("简单匹配结果: " + matcher.find());
// 2. 元字符使用
checkPattern("\d", "123", "数字匹配"); // 匹配数字
checkPattern("\D", "abc", "非数字匹配"); // 匹配非数字
checkPattern("\w", "a1_", "单词字符匹配"); // 匹配单词字符[a-zA-Z_0-9]
checkPattern("\W", "@#$", "非单词字符匹配"); // 匹配非单词字符
checkPattern("\s", " ", "空白字符匹配"); // 匹配空白字符
checkPattern("\S", "a", "非空白字符匹配"); // 匹配非空白字符
// 3. 量词使用
checkPattern("a?", "a", "0或1次匹配"); // 0或1次
checkPattern("a*", "aaa", "0或多次匹配"); // 0或多次
checkPattern("a+", "aaa", "1或多次匹配"); // 1或多次
checkPattern("a{3}", "aaa", "精确次数匹配"); // 精确3次
checkPattern("a{2,4}", "aaa", "范围次数匹配"); // 2到4次
}
private static void checkPattern(String regex, String input, String description) {
Pattern p = Pattern.compile(regex);
Matcher m = p.matcher(input);
System.out.printf("%s (%s): %b%n", description, regex, m.find());
}
}
2.常用正则表达式模式
电子邮件验证
import java.util.regex.*;
public class EmailValidation {
public static void main(String[] args) {
String emailRegex = "^[a-zA-Z0-9_+&*-]+(?:\.[a-zA-Z0-9_+&*-]+)*@(?:[a-zA-Z0-9-]+\.)+[a-zA-Z]{2,7}$";
String[] emails = {
"test@example.com",
"user.name@domain.co",
"invalid.email@",
"missing@dotcom",
"special@chars.com"
};
Pattern pattern = Pattern.compile(emailRegex);
for (String email : emails) {
Matcher matcher = pattern.matcher(email);
System.out.printf("%-20s: %s%n", email, matcher.matches() ? "有效" : "无效");
}
}
}
手机号验证
import java.util.regex.*;
public class PhoneValidation {
public static void main(String[] args) {
// 中国手机号正则
String phoneRegex = "^1[3-9]\d{9}$";
String[] phones = {
"13800138000",
"12345678901",
"15812345678",
"98765432109",
"17712345678"
};
Pattern pattern = Pattern.compile(phoneRegex);
for (String phone : phones) {
Matcher matcher = pattern.matcher(phone);
System.out.printf("%-11s: %s%n", phone, matcher.matches() ? "有效" : "无效");
}
}
}
3.高级正则表达式功能
分组和捕获
import java.util.regex.*;
public class RegexGroups {
public static void main(String[] args) {
String dateRegex = "(\d{4})-(\d{2})-(\d{2})";
String date = "2023-05-15";
Pattern pattern = Pattern.compile(dateRegex);
Matcher matcher = pattern.matcher(date);
if (matcher.find()) {
System.out.println("完整匹配: " + matcher.group(0));
System.out.println("年份: " + matcher.group(1));
System.out.println("月份: " + matcher.group(2));
System.out.println("日期: " + matcher.group(3));
}
}
}
查找和替换
import java.util.regex.*;
public class RegexReplace {
public static void main(String[] args) {
String text = "The quick brown fox jumps over the lazy dog.";
String regex = "\b\w{4}\b"; // 匹配4字母单词
// 替换所有4字母单词为"****"
String replaced = text.replaceAll(regex, "****");
System.out.println("替换结果: " + replaced);
// 使用Matcher进行更复杂的替换
Pattern pattern = Pattern.compile("(\w)(\w{2})(\w)");
Matcher matcher = pattern.matcher(text);
StringBuffer sb = new StringBuffer();
while (matcher.find()) {
matcher.appendReplacement(sb,
matcher.group(1).toUpperCase() +
matcher.group(2) +
matcher.group(3).toLowerCase());
}
matcher.appendTail(sb);
System.out.println("复杂替换: " + sb.toString());
}
}
4.常用正则表达式模式总结
用途 |
正则表达式模式 |
说明 |
用户名 |
|
3-16字符,包含字母数字-_ |
强密码 |
|
至少8字符,包含大小写字母、数字和特殊字符 |
IPv4地址 |
|
基本IPv4格式验证 |
URL |
|
HTTP/HTTPS URL验证 |
中文 |
|
纯中文字符 |
身份证号(15或18位) |
`^(d{15} |
d{17}[dxX])$` |
5.性能优化建议
1. 预编译模式
对于频繁使用的正则表达式,使用 Pattern.compile()
预编译
2. 避免贪婪量词
在不需要时使用非贪婪量词 *?
、+?
、??
3. 使用边界匹配
^
和 $
或 可以提高匹配效率
4. 简化字符类
[a-z]
比 (a|b|c|...|z)
更高效
5. 避免回溯
复杂的正则表达式可能导致性能问题
通过掌握这些正则表达式知识和技巧,您可以在Java中高效地进行文本处理和验证。
枚举(Enum)
1. 基本枚举定义
基础枚举示例
public enum Day {
MONDAY,
TUESDAY,
WEDNESDAY,
THURSDAY,
FRIDAY,
SATURDAY,
SUNDAY
}
2. 带属性的枚举
带属性的枚举
public enum Planet {
MERCURY(3.303e+23, 2.4397e6),
VENUS(4.869e+24, 6.0518e6),
EARTH(5.976e+24, 6.37814e6),
MARS(6.421e+23, 3.3972e6),
JUPITER(1.9e+27, 7.1492e7),
SATURN(5.688e+26, 6.0268e7),
URANUS(8.686e+25, 2.5559e7),
NEPTUNE(1.024e+26, 2.4746e7);
private final double mass; // in kilograms
private final double radius; // in meters
Planet(double mass, double radius) {
this.mass = mass;
this.radius = radius;
}
public double getMass() { return mass; }
public double getRadius() { return radius; }
// universal gravitational constant (m3 kg-1 s-2)
public static final double G = 6.67300E-11;
public double surfaceGravity() {
return G * mass / (radius * radius);
}
public double surfaceWeight(double otherMass) {
return otherMass * surfaceGravity();
}
}
3. 枚举方法与抽象方法
枚举方法与抽象方法
public enum Operation {
PLUS {
public double apply(double x, double y) { return x + y; }
},
MINUS {
public double apply(double x, double y) { return x - y; }
},
TIMES {
public double apply(double x, double y) { return x * y; }
},
DIVIDE {
public double apply(double x, double y) { return x / y; }
};
public abstract double apply(double x, double y);
}
4. 枚举实用方法
枚举实用方法
import java.util.EnumSet;
public class EnumTest {
public static void main(String[] args) {
// 遍历枚举
for (Day day : Day.values()) {
System.out.println(day);
}
// 使用EnumSet
EnumSet<Day> weekdays = EnumSet.range(Day.MONDAY, Day.FRIDAY);
System.out.println("Weekdays: " + weekdays);
// 根据名称获取枚举实例
Day day = Day.valueOf("MONDAY");
System.out.println("Found: " + day);
// 枚举比较
System.out.println("Is Monday before Friday? " +
Day.MONDAY.compareTo(Day.FRIDAY) < 0);
}
}
5. 枚举实现接口
枚举实现接口
一、枚举基础
1. 枚举定义
枚举(enum)是Java 5引入的一种特殊数据类型,用于定义一组固定的常量。
// 基本枚举定义
public enum Day {
MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY, SUNDAY
}
2. 枚举特点
类型安全:比使用常量(int/String)更安全
可读性强:枚举值有明确的名称
功能丰富:可以添加方法、属性等
天然单例:每个枚举实例都是单例的
二、带属性的枚举
1. 定义带属性的枚举
public enum Planet {
// 枚举值(调用构造函数)
MERCURY(3.303e+23, 2.4397e6),
VENUS(4.869e+24, 6.0518e6),
EARTH(5.976e+24, 6.37814e6);
// 枚举属性
private final double mass; // 质量(kg)
private final double radius; // 半径(m)
// 枚举构造函数(必须是private或包私有)
Planet(double mass, double radius) {
this.mass = mass;
this.radius = radius;
}
// 枚举方法
public double getMass() { return mass; }
public double getRadius() { return radius; }
// 计算表面重力
public double surfaceGravity() {
return G * mass / (radius * radius);
}
// 常量
public static final double G = 6.67300E-11;
}
2. 使用带属性的枚举
public class EnumTest {
public static void main(String[] args) {
double earthWeight = 175; // 地球上的重量(磅)
double mass = earthWeight / Planet.EARTH.surfaceGravity();
for (Planet p : Planet.values()) {
System.out.printf("Your weight on %s is %f%n",
p, p.surfaceWeight(mass));
}
}
}
三、枚举方法与抽象方法
1. 枚举中定义方法
public enum Operation {
PLUS, MINUS, TIMES, DIVIDE;
// 枚举方法
public double apply(double x, double y) {
switch(this) {
case PLUS: return x + y;
case MINUS: return x - y;
case TIMES: return x * y;
case DIVIDE: return x / y;
}
throw new AssertionError("未知操作: " + this);
}
}
2. 枚举中定义抽象方法(更优雅的实现)
public enum Operation {
PLUS {
public double apply(double x, double y) { return x + y; }
},
MINUS {
public double apply(double x, double y) { return x - y; }
},
TIMES {
public double apply(double x, double y) { return x * y; }
},
DIVIDE {
public double apply(double x, double y) { return x / y; }
};
// 抽象方法,每个枚举值必须实现
public abstract double apply(double x, double y);
}
四、枚举实用方法
1. values()方法
返回枚举的所有值数组
Day[] days = Day.values();
for (Day day : days) {
System.out.println(day);
}
2. valueOf()方法
根据名称获取枚举值
Day day = Day.valueOf("MONDAY"); // 返回Day.MONDAY
3. name()和ordinal()方法
Day day = Day.MONDAY;
System.out.println(day.name()); // 输出"MONDAY"
System.out.println(day.ordinal()); // 输出0(枚举定义的顺序)
五、枚举实现接口
1. 枚举实现接口
public interface Command {
void execute();
}
public enum Direction implements Command {
LEFT {
public void execute() {
System.out.println("向左转");
}
},
RIGHT {
public void execute() {
System.out.println("向右转");
}
};
}
2. 使用接口统一处理枚举
public class Test {
public static void main(String[] args) {
Command cmd = Direction.LEFT;
cmd.execute(); // 输出"向左转"
}
}
六、枚举单例模式
1. 枚举实现单例(推荐方式)
public enum Singleton {
INSTANCE;
public void doSomething() {
System.out.println("单例方法调用");
}
}
// 使用
Singleton.INSTANCE.doSomething();
2. 为什么枚举单例是最好的实现方式
线程安全:由JVM保证
防止反射攻击
防止序列化破坏单例
代码简洁
七、枚举高级特性
1. 枚举集合(EnumSet和EnumMap)
// EnumSet示例
EnumSet<Day> weekend = EnumSet.of(Day.SATURDAY, Day.SUNDAY);
// EnumMap示例
EnumMap<Day, String> activityMap = new EnumMap<>(Day.class);
activityMap.put(Day.MONDAY, "上班");
activityMap.put(Day.SATURDAY, "休息");
2. 枚举常量特定方法
public enum ConstantSpecificMethod {
DATE_TIME {
String getInfo() { return "日期时间"; }
},
IP_ADDRESS {
String getInfo() { return "IP地址"; }
};
abstract String getInfo();
}
八、枚举最佳实践
优先使用枚举代替常量:比public static final更安全
为枚举添加有用的方法:增强枚举的功能性
考虑使用枚举实现单例:最安全可靠的实现方式
合理使用枚举集合:EnumSet和EnumMap性能优异
避免过度复杂的枚举:保持简单清晰
枚举是Java中一种强大而灵活的特性,合理使用可以大大提高代码的可读性、安全性和可维护性。
关键特性总结
类型安全:枚举提供了编译时类型检查
可扩展性:可以添加属性、方法和构造函数
单例支持:枚举实例天然是单例的
多态支持:可以通过抽象方法实现多态行为
工具支持:values()
和valueOf()
方法自动生成
集合支持:EnumSet
和EnumMap
提供高效实现
枚举是Java中一种强大的类型,特别适合表示固定集合的常量,并能通过面向对象的方式扩展功能。
异常
一、异常体系结构
Java 异常体系采用层次化设计,所有异常都继承自 Throwable
类:
Throwable
├── Error (系统严重错误,通常不应捕获)
│ ├── VirtualMachineError
│ ├── OutOfMemoryError
│ └── ...
└── Exception (可检查异常)
├── RuntimeException (非检查异常/运行时异常)
│ ├── NullPointerException
│ ├── ArrayIndexOutOfBoundsException
│ ├── IllegalArgumentException
│ └── ...
└── 其他检查异常
├── IOException
├── SQLException
└── ...
二、异常分类
1. 检查异常(Checked Exception)
继承自 Exception
但不继承 RuntimeException
编译器强制要求处理
代表程序可以预期并恢复的问题
示例:IOException
, SQLException
2. 非检查异常(Unchecked Exception)
继承自 RuntimeException
编译器不强制要求处理
通常代表编程错误
示例:NullPointerException
, ArrayIndexOutOfBoundsException
3. 错误(Error)
继承自 Error
表示严重系统问题
应用程序通常不应捕获
示例:OutOfMemoryError
, StackOverflowError
三、异常处理关键字
1. try-catch-finally 基本结构
try {
// 可能抛出异常的代码
} catch (ExceptionType1 e1) {
// 处理ExceptionType1
} catch (ExceptionType2 e2) {
// 处理ExceptionType2
} finally {
// 无论是否发生异常都会执行的代码
// 常用于资源清理
}
2. try-with-resources (Java 7+)
try (ResourceType resource = new ResourceType()) {
// 使用资源的代码
} catch (Exception e) {
// 异常处理
}
// 资源会自动关闭,无需finally块
四、自定义异常
1. 创建检查异常
public class BusinessException extends Exception {
public BusinessException(String message) {
super(message);
}
public BusinessException(String message, Throwable cause) {
super(message, cause);
}
}
2. 创建非检查异常
public class RuntimeBusinessException extends RuntimeException {
public RuntimeBusinessException(String message) {
super(message);
}
public RuntimeBusinessException(String message, Throwable cause) {
super(message, cause);
}
}
五、异常处理最佳实践
早抛出,晚捕获原则
在发现问题的地方立即抛出异常
在能够处理异常的地方集中捕获
避免空的catch块
// 错误示例
try {
// ...
} catch (Exception e) {
// 什么都不做
}
使用特定异常而非通用异常
// 好
catch (FileNotFoundException e) { ... }
// 不好
catch (Exception e) { ... }
保留原始异常信息
try {
// ...
} catch (IOException e) {
throw new BusinessException("文件处理失败", e);
}
合理使用finally进行资源清理
FileInputStream fis = null;
try {
fis = new FileInputStream("file.txt");
// ...
} catch (IOException e) {
// ...
} finally {
if (fis != null) {
try {
fis.close();
} catch (IOException e) {
// 记录日志
}
}
}
考虑使用异常链
try {
// ...
} catch (LowLevelException e) {
throw new HighLevelException("高层异常信息", e);
}
六、常见异常处理模式
1. 防御性编程模式
public void process(String input) {
if (input == null) {
throw new IllegalArgumentException("输入不能为null");
}
// 继续处理
}
2. 异常转换模式
public void databaseOperation() throws BusinessException {
try {
// JDBC操作
} catch (SQLException e) {
throw new BusinessException("数据库操作失败", e);
}
}
3. 模板方法模式中的异常处理
public void templateMethod() {
try {
// 前置处理
doSomething();
// 后置处理
} catch (Exception e) {
// 统一异常处理
}
}
protected abstract void doSomething() throws Exception;
七、Java 8 异常处理新特性
1. CompletableFuture 异常处理
CompletableFuture.supplyAsync(() -> {
// 可能抛出异常的操作
return doSomething();
}).exceptionally(ex -> {
// 异常处理
return defaultValue;
}).thenAccept(result -> {
// 正常结果处理
});
2. Optional 与异常处理结合
public Optional<String> findUserById(int id) {
try {
String user = userDao.findById(id);
return Optional.ofNullable(user);
} catch (DataAccessException e) {
// 记录日志
return Optional.empty();
}
}
八、日志记录最佳实践
在捕获异常时记录日志
try {
// ...
} catch (Exception e) {
logger.error("处理失败,原因: {}", e.getMessage(), e);
throw new BusinessException("处理失败", e);
}
避免重复记录日志
确保异常只在一个地方被记录
记录足够上下文信息
包括相关参数、状态等
九、性能考虑
异常处理成本
创建异常对象开销较大(需要填充栈轨迹)
不应使用异常进行常规流程控制
优化建议
在性能关键路径避免频繁抛出异常
预先检查条件比捕获异常更高效
十、总结
Java 异常处理的核心原则:
明确区分检查异常和非检查异常的使用场景
提供有意义的异常信息和适当的异常层次结构
确保资源被正确释放
在适当的抽象层次处理异常
保持异常处理代码简洁且专注
良好的异常处理能显著提高代码的健壮性和可维护性,是编写高质量Java程序的重要组成部分。
暂无评论内容