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

优化Java进制转换程序:消除代码冗余与改进面向对象设计

进制转换程序的代码冗余优化与面向对象设计方案

一、减少toDec()/fromDec()重复代码的核心思路

不管是二进制、八进制还是十六进制转十进制,核心逻辑都是按位加权求和;十进制转其他进制则是除基取余、逆序拼接。重复代码的根源是把不同进制的相同逻辑拆成了独立方法,解决方法是提取通用逻辑,将进制基数、字符映射作为参数传入。

1. 通用转十进制方法

把不同进制的共性逻辑抽成通用方法,仅将基数、字符-数值映射作为参数:

// 通用转十进制方法,处理所有进制的转十进制逻辑
private static long parseToDecimal(String input, int radix, Map<Character, Integer> charToValue) {
    long result = 0;
    boolean isNegative = input.startsWith("-");
    int startIdx = isNegative ? 1 : 0;

    for (int i = startIdx; i < input.length(); i++) {
        char c = Character.toUpperCase(input.charAt(i));
        Integer value = charToValue.get(c);
        if (value == null || value >= radix) {
            throw new IllegalArgumentException("非法字符: " + c);
        }
        result = result * radix + value;
    }

    return isNegative ? -result : result;
}

// 二进制转十进制,仅传入对应参数
public long binaryToDecimal(String binary) {
    Map<Character, Integer> binMap = Map.of('0', 0, '1', 1);
    return parseToDecimal(binary, 2, binMap);
}

// 十六进制转十进制,仅传入对应参数
public long hexToDecimal(String hex) {
    Map<Character, Integer> hexMap = new HashMap<>();
    for (int i = 0; i <= 9; i++) hexMap.put((char)('0'+i), i);
    for (int i = 10; i <=15; i++) hexMap.put((char)('A'+i-10), i);
    return parseToDecimal(hex, 16, hexMap);
}

2. 通用从十进制转其他进制方法

同理,把十进制转任意进制的逻辑抽成通用方法,传入基数、数值-字符映射:

// 通用十进制转其他进制方法
private static String formatFromDecimal(long decimal, int radix, Map<Integer, Character> valueToChar) {
    if (decimal == 0) return "0";

    boolean isNegative = decimal < 0;
    decimal = Math.abs(decimal);
    StringBuilder sb = new StringBuilder();

    while (decimal > 0) {
        int remainder = (int)(decimal % radix);
        sb.append(valueToChar.get(remainder));
        decimal = decimal / radix;
    }

    if (isNegative) sb.append("-");
    return sb.reverse().toString();
}

// 十进制转二进制,仅传入对应参数
public String decimalToBinary(long decimal) {
    Map<Integer, Character> binMap = Map.of(0, '0', 1, '1');
    return formatFromDecimal(decimal, 2, binMap);
}

// 十进制转十六进制,仅传入对应参数
public String decimalToHex(long decimal) {
    Map<Integer, Character> hexMap = new HashMap<>();
    for (int i = 0; i <=9; i++) hexMap.put(i, (char)('0'+i));
    for (int i =10; i<=15; i++) hexMap.put(i, (char)('A'+i-10));
    return formatFromDecimal(decimal, 16, hexMap);
}

二、更优的面向对象设计方案

通过抽象出进制的共性特征,定义接口/抽象类,再为每种进制实现具体类,实现逻辑复用和可扩展性。

1. 定义NumberBase接口

封装所有进制的核心属性(基数、字符映射)和方法(转十进制、从十进制转出):

public interface NumberBase {
    // 获取进制基数
    int getRadix();
    // 获取字符转数值的映射表
    Map<Character, Integer> getCharToValueMap();
    // 获取数值转字符的映射表
    Map<Integer, Character> getValueToCharMap();

    // 默认实现转十进制逻辑
    default long toDecimal(String input) {
        boolean isNegative = input.startsWith("-");
        int startIdx = isNegative ? 1 : 0;
        long result = 0;

        for (int i = startIdx; i < input.length(); i++) {
            char c = Character.toUpperCase(input.charAt(i));
            Integer value = getCharToValueMap().get(c);
            if (value == null || value >= getRadix()) {
                throw new IllegalArgumentException("非法字符: " + c);
            }
            result = result * getRadix() + value;
        }

        return isNegative ? -result : result;
    }

    // 默认实现从十进制转出逻辑
    default String fromDecimal(long decimal) {
        if (decimal == 0) return "0";
        boolean isNegative = decimal < 0;
        decimal = Math.abs(decimal);
        StringBuilder sb = new StringBuilder();

        while (decimal > 0) {
            int remainder = (int)(decimal % getRadix());
            sb.append(getValueToCharMap().get(remainder));
            decimal = decimal / getRadix();
        }

        return isNegative ? "-" + sb.reverse() : sb.reverse().toString();
    }
}

2. 实现具体进制类

为二进制、八进制、十六进制分别实现NumberBase接口,仅需提供各自的基数和映射表:

// 二进制实现类
public class Binary implements NumberBase {
    private static final int RADIX = 2;
    private static final Map<Character, Integer> CHAR_TO_VALUE = Map.of('0',0, '1',1);
    private static final Map<Integer, Character> VALUE_TO_CHAR = Map.of(0,'0', 1,'1');

    @Override
    public int getRadix() { return RADIX; }
    @Override
    public Map<Character, Integer> getCharToValueMap() { return CHAR_TO_VALUE; }
    @Override
    public Map<Integer, Character> getValueToCharMap() { return VALUE_TO_CHAR; }
}

// 十六进制实现类
public class Hexadecimal implements NumberBase {
    private static final int RADIX = 16;
    private static final Map<Character, Integer> CHAR_TO_VALUE;
    private static final Map<Integer, Character> VALUE_TO_CHAR;

    static {
        CHAR_TO_VALUE = new HashMap<>();
        VALUE_TO_CHAR = new HashMap<>();
        for (int i = 0; i <=9; i++) {
            CHAR_TO_VALUE.put((char)('0'+i), i);
            VALUE_TO_CHAR.put(i, (char)('0'+i));
        }
        for (int i =10; i<=15; i++) {
            char c = (char)('A'+i-10);
            CHAR_TO_VALUE.put(c, i);
            VALUE_TO_CHAR.put(i, c);
        }
    }

    @Override
    public int getRadix() { return RADIX; }
    @Override
    public Map<Character, Integer> getCharToValueMap() { return CHAR_TO_VALUE; }
    @Override
    public Map<Integer, Character> getValueToCharMap() { return VALUE_TO_CHAR; }
}

3. 统一转换工具类

提供跨进制转换的入口,复用已有逻辑:

public class BaseConverter {
    public static String convert(String input, NumberBase fromBase, NumberBase toBase) {
        long decimal = fromBase.toDecimal(input);
        return toBase.fromDecimal(decimal);
    }
}

4. 扩展分步说明功能

如果需要保留分步说明,可以在NumberBase接口中添加默认方法,统一收集转换步骤:

// 定义存储结果和步骤的类
public class ConversionResult {
    private final long result;
    private final List<String> steps;

    public ConversionResult(long result, List<String> steps) {
        this.result = result;
        this.steps = steps;
    }

    // getter方法
    public long getResult() { return result; }
    public List<String> getSteps() { return steps; }
}

// 在NumberBase接口中添加分步转换方法
default ConversionResult toDecimalWithSteps(String input) {
    boolean isNegative = input.startsWith("-");
    String targetInput = isNegative ? input.substring(1) : input;
    long result = 0;
    List<String> steps = new ArrayList<>();

    steps.add(String.format("将%s转换为十进制(基数:%d)", input, getRadix()));
    if (isNegative) steps.add("先处理绝对值部分,最终添加负号");

    for (int i = 0; i < targetInput.length(); i++) {
        char c = Character.toUpperCase(targetInput.charAt(i));
        int value = getCharToValueMap().get(c);
        int exponent = targetInput.length() - 1 - i;
        long weight = (long) Math.pow(getRadix(), exponent);
        long contribution = value * weight;

        steps.add(String.format("第%d位'%c' → 数值%d,权重%d^%d=%d,贡献值%d×%d=%d",
                i+1, c, value, getRadix(), exponent, weight, value, weight, contribution));
        result += contribution;
    }

    if (isNegative) {
        result = -result;
        steps.add("添加负号,最终结果:" + result);
    } else {
        steps.add("累加贡献值,最终结果:" + result);
    }

    return new ConversionResult(result, steps);
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.02 00:24:50