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

如何优化Android Studio中Java代码的复杂分支逻辑?

计算器代码优化方案

你的代码目前存在逻辑过于集中、重复代码冗余、可读性差的问题,下面是几个落地性强的优化方向:

1. 用枚举替代字符串常量,消除硬编码

原代码直接用字符串判断按钮类型,容易出错且难以维护。定义一个枚举类封装所有按钮的类型和文本:

public enum CalculatorButton {
    CLEAR("AC"),
    DELETE("⌫"),
    EQUALS("="),
    BRACKET("( )"),
    SQUARE_ROOT("√"),
    LOG("log"),
    TAN("tan"),
    COS("cos"),
    SIN("sin"),
    PERCENT("%"),
    FACTORIAL("!"),
    POWER("^"),
    MINUS("-"),
    PLUS("+"),
    MULTIPLY("×"),
    DIVIDE("÷"),
    PI("π"),
    DOT("."),
    NUMBER(null); // 数字按钮统一归类

    private final String text;

    CalculatorButton(String text) {
        this.text = text;
    }

    public static CalculatorButton fromText(String text) {
        for (CalculatorButton button : values()) {
            if (text.equals(button.text)) {
                return button;
            }
        }
        // 数字按钮返回NUMBER类型
        if (text.matches("[0-9]")) {
            return NUMBER;
        }
        throw new IllegalArgumentException("Unknown button text: " + text);
    }
}

这样switch时直接用枚举,避免字符串拼写错误:

CalculatorButton button = CalculatorButton.fromText(buttonString);
switch (button) {
    case CLEAR:
        clearMethod();
        break;
    case DELETE:
        deleteMethod();
        break;
    case BRACKET:
        handleBracketInput(); // 拆分到独立方法
        break;
    // ... 其他case
}

2. 拆分巨型case到独立方法

原代码中( )和.的逻辑过于冗长,把这些逻辑拆成单独的方法,让switch结构更清晰:

private void handleBracketInput() {
    if (mInputText.length() == 0) {
        addLeftBracket();
        return;
    }

    if (mCursorPosition == mInputText.length()) {
        handleBracketAtEnd();
    } else if (mCursorPosition == 0) {
        handleBracketAtStart();
    } else {
        handleBracketInMiddle();
    }
}

// 再拆分更细的子方法
private void addLeftBracket() {
    updateInputView(mCursorPosition + 1, mCursorPosition, getResources().getString(R.string.bracketleft));
    mBracketStatus++;
}

private void handleBracketAtEnd() {
    if (mBracketStatus > 0) {
        char lastChar = mInputText.charAt(mCursorPosition - 1);
        if (isValidBeforeRightBracket(lastChar)) {
            addRightBracket();
        } else if (isValidBeforeLeftBracket(lastChar)) {
            addLeftBracket();
        }
    } else {
        char lastChar = mInputText.charAt(mCursorPosition - 1);
        if (isValidBeforeLeftBracket(lastChar)) {
            addLeftBracket();
        }
    }
}

3. 用集合替代字符串查找,提升可读性和性能

原代码用NOT_BEFORE_BRACKET_LEFT.indexOf(...) == -1这种方式判断字符合法性,可读性差且性能低。改成用Set<Character>存储允许/禁止的字符:

// 类初始化时定义集合
private static final Set<Character> BEFORE_LEFT_BRACKET_FORBIDDEN = new HashSet<>(Arrays.asList('.', 'a', 'n', 'o', 't', 'c', 's', 'i', 'l', 'g'));
private static final Set<Character> BEFORE_RIGHT_BRACKET_FORBIDDEN = new HashSet<>(Arrays.asList('.', 'a', 'n', 'o', 't', 'c', 's', 'i', 'l', 'g'));

// 判断方法
private boolean isValidBeforeLeftBracket(char c) {
    return !BEFORE_LEFT_BRACKET_FORBIDDEN.contains(c);
}

private boolean isValidBeforeRightBracket(char c) {
    return !BEFORE_RIGHT_BRACKET_FORBIDDEN.contains(c);
}

这样代码里的判断逻辑就变成if (isValidBeforeRightBracket(lastChar)),可读性大幅提升。

4. 提取重复逻辑为公共方法

原代码中很多按钮的输入判断逻辑重复(比如判断光标在开头、结尾、中间的情况),提取成公共方法:

// 判断是否可以在当前光标位置插入内容
private boolean canInsertAtCurrentPosition(Set<Character> forbiddenBefore, Set<Character> forbiddenAfter) {
    if (mInputText.length() == 0) {
        return true;
    }
    if (mCursorPosition == mInputText.length()) {
        char lastChar = mInputText.charAt(mCursorPosition - 1);
        return !forbiddenBefore.contains(lastChar);
    } else if (mCursorPosition == 0) {
        char firstChar = mInputText.charAt(0);
        return !forbiddenAfter.contains(firstChar);
    } else {
        char beforeChar = mInputText.charAt(mCursorPosition - 1);
        char afterChar = mInputText.charAt(mCursorPosition);
        return !forbiddenBefore.contains(beforeChar) && !forbiddenAfter.contains(afterChar);
    }
}

然后像√按钮的逻辑就可以简化为:

case SQUARE_ROOT:
    Set<Character> sqrtForbiddenBefore = Collections.singleton('.');
    if (canInsertAtCurrentPosition(sqrtForbiddenBefore, NOT_AFTER_OPERATOR_1_SET)) {
        updateInputView(mCursorPosition + 1, mCursorPosition, button.getText());
    }
    break;

5. 封装输入状态,避免散列变量

把mInputText、mCursorPosition、mBracketStatus这些状态封装成一个单独的类,比如CalculatorInputState,让状态管理更集中:

public class CalculatorInputState {
    private StringBuilder inputText;
    private int cursorPosition;
    private int bracketStatus;

    public CalculatorInputState() {
        inputText = new StringBuilder();
        cursorPosition = 0;
        bracketStatus = 0;
    }

    // 提供getter和setter,以及操作方法
    public void addText(String text) {
        inputText.insert(cursorPosition, text);
        cursorPosition += text.length();
    }

    public char getCharBeforeCursor() {
        if (cursorPosition == 0) {
            throw new IllegalStateException("Cursor at start, no character before");
        }
        return inputText.charAt(cursorPosition - 1);
    }

    // ... 其他必要的方法
}

这样原代码里的状态操作就变成调用这个类的方法,减少散列变量带来的维护成本。

进阶:用策略模式彻底消除switch

如果想进一步解耦,可以给枚举添加一个处理接口,每个枚举实现自己的处理逻辑:

public interface ButtonHandler {
    void handle(CalculatorInputState state, CalculatorView view);
}

public enum CalculatorButton implements ButtonHandler {
    CLEAR("AC") {
        @Override
        public void handle(CalculatorInputState state, CalculatorView view) {
            view.clear();
            state.reset();
        }
    },
    BRACKET("( )") {
        @Override
        public void handle(CalculatorInputState state, CalculatorView view) {
            // 括号处理逻辑
        }
    },
    // ... 其他枚举实现handle方法
};

然后调用时直接:

CalculatorButton button = CalculatorButton.fromText(buttonString);
button.handle(mInputState, mCalculatorView);

这样就彻底去掉了巨型switch,代码结构更清晰,扩展新按钮时只需添加枚举即可。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.17 22:03:06