You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何为StringBuilder和StringBuffer提取重复代码至公共方法?

解决StringBuffer与StringBuilder重复代码提取问题

嘿,我完全懂你遇到的困扰——StringBuffer和StringBuilder功能几乎一致,但偏偏是两个独立的类,既没有共同的、包含核心操作的父类(除了Object),也没实现同一个能覆盖所有你需要的方法的接口,所以一开始想靠泛型解决确实走不通。不过咱们有几个实用的办法来提取重复代码:

方法一:用函数式接口封装操作(推荐)

利用两者方法签名完全一致的特点,用Supplier来创建实例,用Consumer来封装重复的逻辑,这样就能把公共逻辑抽离出来:

// 公共方法:负责创建实例并执行重复逻辑
private String processMutableString(Supplier<? extends Appendable> instanceCreator, Consumer<? super Appendable> logic) {
    Appendable mutableStr = instanceCreator.get();
    logic.accept(mutableStr);
    // 如果需要返回最终字符串,直接转换即可
    return mutableStr.toString();
}

// 调用StringBuilder版本
public String buildWithStringBuilder() {
    return processMutableString(
        StringBuilder::new,
        sb -> {
            sb.append("Hello");
            sb.append(" World");
            // 这里放所有重复的操作,比如插入、删除、反转等
            if (sb instanceof StringBuilder) {
                ((StringBuilder) sb).reverse(); // 若用到Appendable没有的方法,需要强转
            }
        }
    );
}

// 调用StringBuffer版本
public String buildWithStringBuffer() {
    return processMutableString(
        StringBuffer::new,
        sb -> {
            sb.append("Hello");
            sb.append(" World");
            // 和上面完全一样的重复逻辑
            if (sb instanceof StringBuffer) {
                ((StringBuffer) sb).reverse();
            }
        }
    );
}

如果你的重复逻辑用到了Appendable接口没有定义的方法(比如reverse()、delete()),可以在Consumer里做个简单的类型判断强转,或者自定义一个包含这些方法的函数式接口来更优雅地处理。

方法二:工具类静态方法(适合简单逻辑)

如果你的重复逻辑比较简单,可以直接写一个静态工具方法,通过instanceof来处理两种类型:

public static void applyCommonLogic(Object mutableString) {
    if (mutableString instanceof StringBuilder sb) {
        sb.append("Common content");
        sb.reverse();
    } else if (mutableString instanceof StringBuffer sb) {
        sb.append("Common content");
        sb.reverse();
    }
}

// 调用时
StringBuilder sb = new StringBuilder();
applyCommonLogic(sb);

StringBuffer sbf = new StringBuffer();
applyCommonLogic(sbf);

这种方式代码量少,但扩展性稍差,如果以后新增类似的可变字符串类,需要修改工具方法。

方法三:适配器模式(适合复杂逻辑)

如果你的重复逻辑非常复杂,可以创建一个适配器接口,然后为StringBuilder和StringBuffer分别写实现类,把公共逻辑放在适配器的默认方法或者抽象类里:

// 定义适配器接口
interface MutableStringAdapter {
    void append(String content);
    void reverse();
    String getResult();

    // 公共逻辑放在默认方法里
    default void applyCommonLogic() {
        append("Common prefix");
        reverse();
        append("Common suffix");
    }
}

// StringBuilder适配器
class StringBuilderAdapter implements MutableStringAdapter {
    private final StringBuilder sb = new StringBuilder();

    @Override
    public void append(String content) {
        sb.append(content);
    }

    @Override
    public void reverse() {
        sb.reverse();
    }

    @Override
    public String getResult() {
        return sb.toString();
    }
}

// StringBuffer适配器
class StringBufferAdapter implements MutableStringAdapter {
    private final StringBuffer sb = new StringBuffer();

    @Override
    public void append(String content) {
        sb.append(content);
    }

    @Override
    public void reverse() {
        sb.reverse();
    }

    @Override
    public String getResult() {
        return sb.toString();
    }
}

// 使用示例
MutableStringAdapter sbAdapter = new StringBuilderAdapter();
sbAdapter.applyCommonLogic();
String result1 = sbAdapter.getResult();

MutableStringAdapter sbfAdapter = new StringBufferAdapter();
sbfAdapter.applyCommonLogic();
String result2 = sbfAdapter.getResult();

这种方式最优雅,但适合逻辑复杂、需要频繁复用的场景,小逻辑的话有点过度设计。

总结一下:泛型确实帮不上忙,因为这两个类没有共同的操作契约,所以得靠函数式编程、类型判断或者适配器来解决重复代码问题,根据你的逻辑复杂度选对应的方式就好~

内容的提问来源于stack exchange,提问作者zond

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.19 04:36:10