优化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
相关产品推荐
相关产品推荐

