大家好!我是Java技术博主,今天给大家带来一篇绝对能让你技术升级的干货文章!无论你是刚入门的新手,还是有一定经验的开发者,这些技巧都能让你的Java代码质量提升一个档次!💪
📌 1. 使用Optional优雅处理null
问题场景
我们经常遇到NPE(NullPointerException)问题,传统做法是各种if-null检查:
User user = getUser();
if (user != null) {
Address address = user.getAddress();
if (address != null) {
// 业务逻辑...
}
}
更优雅的解决方案
Java 8的Optional让代码更简洁安全:
Optional.ofNullable(getUser())
.map(User::getAddress)
.ifPresent(address -> {
// 业务逻辑...
});
解析:
ofNullable()
将可能为null的对象包装成Optionalmap()
进行级联操作,如果上一步为empty则跳过ifPresent()
只有在值存在时执行操作
📌 2. 利用Stream API进行集合操作
传统方式 vs Stream方式
// 传统方式:筛选年龄>18的用户并收集到新列表
List adults = new ArrayList<>();
for (User user : users) {
if (user.getAge() > 18) {
adults.add(user);
}
}
// Stream方式
List adults = users.stream()
.filter(user -> user.getAge() > 18)
.collect(Collectors.toList());
进阶用法:
// 分组:按城市分组用户
Map> usersByCity = users.stream()
.collect(Collectors.groupingBy(User::getCity));
// 统计:计算平均年龄
double avgAge = users.stream()
.collect(Collectors.averagingInt(User::getAge));
📌 3. 正确使用StringBuilder拼接字符串
错误示范
String result = "";
for (int i = 0; i < 100; i++) {
result += i; // 每次循环都创建新String对象!
}
正确方式
StringBuilder sb = new StringBuilder();
for (int i = 0; i < 100; i++) {
sb.append(i);
}
String result = sb.toString();
性能对比:
- 拼接10000次字符串:
- 使用
+
:约500ms - 使用StringBuilder:约5ms
- 使用
📌 4. 使用try-with-resources管理资源
旧式写法(容易忘记关闭资源)
BufferedReader br = null;
try {
br = new BufferedReader(new FileReader("file.txt"));
// 使用br...
} catch (IOException e) {
e.printStackTrace();
} finally {
if (br != null) {
try {
br.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
Java 7+推荐写法
try (BufferedReader br = new BufferedReader(new FileReader("file.txt"))) {
// 使用br...
} catch (IOException e) {
e.printStackTrace();
}
优势:
- 自动关闭资源(实现了AutoCloseable接口)
- 代码更简洁
- 不会忘记关闭资源
📌 5. 使用枚举替代常量类
不推荐做法
public class Constants {
public static final int STATUS_OPEN = 1;
public static final int STATUS_CLOSED = 2;
// 更多状态...
}
推荐做法
public enum Status {
OPEN(1, "开放"),
CLOSED(2, "关闭");
private int code;
private String desc;
Status(int code, String desc) {
this.code = code;
this.desc = desc;
}
// getters...
}
优势:
- 类型安全
- 自带命名空间
- 可添加方法和属性
- 更好的可读性
📌 6. 使用Lambda简化代码
传统匿名类
button.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
System.out.println("按钮被点击");
}
});
Lambda表达式
button.addActionListener(e -> System.out.println("按钮被点击"));
更多示例:
// 线程创建
new Thread(() -> System.out.println("线程运行中")).start();
// 集合排序
Collections.sort(users, (u1, u2) -> u1.getAge() - u2.getAge());
📌 7. 正确重写equals和hashCode
标准实现模板
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
User user = (User) o;
return age == user.age &&
Objects.equals(name, user.name) &&
Objects.equals(email, user.email);
}
@Override
public int hashCode() {
return Objects.hash(name, age, email);
}
必须遵守的规则:
- 自反性:x.equals(x)必须为true
- 对称性:x.equals(y)和y.equals(x)结果相同
- 传递性:如果x.equals(y)且y.equals(z),则x.equals(z)
- 一致性:多次调用结果相同
- 非空性:x.equals(null)必须为false
📌 8. 使用并发工具类替代wait/notify
传统方式(容易出错)
// 生产者
synchronized(queue) {
while (queue.isFull()) {
queue.wait();
}
queue.add(item);
queue.notifyAll();
}
// 消费者
synchronized(queue) {
while (queue.isEmpty()) {
queue.wait();
}
queue.take();
queue.notifyAll();
}
使用BlockingQueue
BlockingQueue queue = new LinkedBlockingQueue<>(10);
// 生产者
queue.put(item);
// 消费者
Item item = queue.take();
Java并发工具包推荐:
CountDownLatch
:等待多个线程完成CyclicBarrier
:线程到达屏障点Semaphore
:控制资源访问ConcurrentHashMap
:线程安全Map
📌 9. 使用日志框架替代System.out
不推荐做法
System.out.println("用户登录:" + username);
推荐做法
private static final Logger logger = LoggerFactory.getLogger(UserService.class);
// 使用占位符,避免字符串拼接
logger.debug("用户登录:{}", username);
// 错误日志
try {
// 业务代码...
} catch (Exception e) {
logger.error("用户登录异常", e);
}
日志级别选择:
- ERROR:需要立即处理的错误
- WARN:潜在问题
- INFO:重要业务信息
- DEBUG:调试信息
- TRACE:最详细日志
📌 10. 使用JUnit5进行现代化测试
基础测试示例
@Test
@DisplayName("测试用户创建")
void shouldCreateUser() {
User user = new User("张三", 25);
assertAll("用户属性验证",
() -> assertEquals("张三", user.getName()),
() -> assertEquals(25, user.getAge()),
() -> assertNotNull(user.getCreateTime())
);
}
参数化测试
@ParameterizedTest
@ValueSource(ints = {18, 20, 30})
void isAdult(int age) {
assertTrue(age >= 18);
}
JUnit5新特性:
- 更灵活的断言
- 嵌套测试
- 动态测试
- 扩展模型
🎯 总结
掌握这些Java编程技巧,你的代码将:
✅ 更健壮 - 减少NPE和并发问题
✅ 更高效 - 提升性能表现
✅ 更简洁 - 减少样板代码
✅ 更易维护 - 提高可读性
记住,优秀的Java开发者不仅要让代码能运行,更要让代码优雅高效!💯
互动时间:你平时最常用的Java技巧是什么?或者遇到过哪些Java坑?欢迎在评论区分享!👇
📢 下期预告:《深入理解Java虚拟机:从字节码到性能调优》敬请期待!
如果觉得有帮助,别忘了点赞❤️收藏⭐️转发🔄!你的支持是我创作的最大动力!