前言

大部分Java日常开发都是CRUD,很多开发者写完功能就提交代码,从来不关注代码性能和可读性。看似功能正常的代码,在大数据量、高并发场景下,会出现接口响应慢、CPU占用高、内存浪费等问题。

代码重构不仅是日常开发必备技能,也是Java面试高频考点。今天整理5组工作中90%开发者都会写错的低效代码,直接给出反例+优化代码+底层原理,新手一看就懂,直接用到项目中,面试也能直接背诵。

场景1:字符串拼接,千万别再用+号循环拼接

低效反例(新手常写):循环中使用+拼接字符串,每次都会生成新String对象,产生大量无用垃圾对象,GC压力巨大。

// 低效代码
public static String badConcat(){
    String str = "";
    for(int i=0;i<10000;i++){
        str += i;
    }
    return str;
}

优化后代码:循环拼接统一使用StringBuilder

// 高效代码
public static String goodConcat(){
    StringBuilder sb = new StringBuilder();
    for(int i=0;i<10000;i++){
        sb.append(i);
    }
    return sb.toString();
}

底层原理:String不可变,每次+都会新建对象;StringBuilder可变字符数组,无额外对象创建,大数据量下性能提升3倍以上。

场景2:集合遍历,不要再用普通for循环遍历ArrayList

很多新手遍历ArrayList依旧使用下标for循环,虽然没错,但是增强for循环代码更简洁,同时避免下标越界风险;而LinkedList禁止使用下标遍历,时间复杂度从O(n²)优化为O(n)。

场景3:判空写法优化,告别臃肿的if null判断

JDK8之后推荐使用Optional优雅判空,彻底避免空指针异常,代码可读性大幅提升,也是现在大厂代码规范强制要求。

低效空判断代码

public String getName(User user){
    if(user != null){
        return user.getName();
    }
    return "";
}

优雅Optional优化代码

public String getName(User user){
    return Optional.ofNullable(user)
            .map(User::getName)
            .orElse("");
}

场景4:ArrayList初始化,一定要指定初始容量

ArrayList默认初始容量10,每次扩容需要数组拷贝,频繁扩容严重损耗性能。预估数据量的时候,直接指定初始容量,减少扩容次数。

场景5:避免在循环内创建对象

循环内部频繁new对象,会导致年轻代GC频繁,尽量把对象创建放到循环外部。

总结:日常代码3条黄金优化准则

  1. 循环内杜绝对象创建、字符串+拼接、IO连接创建
  2. 善用JDK8新特性(Optional、Stream)简化冗余代码
  3. 集合使用提前预估容量,减少自动扩容带来的性能损耗

结语

好的代码不是能跑就行,而是低开销、高可读、易维护。很多时候接口卡顿、服务GC频繁,根源就是不起眼的劣质代码积累。建议大家写完代码花30秒自查一遍,养成良好编码习惯,面试和工作都能事半功倍。需要完整5组重构代码的性能测试对比报告,可以评论区留言领取。

更多推荐