Spring Boot中如何优雅实现Java货币枚举有序对到数值的映射?
优雅生成货币对汇率Map的实现方案
核心思路
利用Java 8+的Stream API替代传统双重循环,结合不可变的键类型(推荐Java 16+的Record,或Java 8的AbstractMap.SimpleEntry)构建以Currency枚举对为键的汇率Map,代码简洁高效。
方案1:Java 16+ 用Record作为键(推荐)
Record会自动生成正确的equals()和hashCode()方法,完美适配Map键的要求:
// 定义不可变的货币对键 public record CurrencyPair(Currency from, Currency to) {}
生成汇率Map的代码:
import java.util.Map; import java.util.Random; import java.util.stream.Collectors; import java.util.Arrays; public class ExchangeRateProvider { // 复用随机数实例,避免频繁创建 private static final Random RANDOM = new Random(); // 自定义汇率范围:0.5到2.5之间(可按需调整) private static final double MIN_RATE = 0.5; private static final double MAX_RATE = 2.5; public static Map<CurrencyPair, Double> buildExchangeRateMap() { Currency[] allCurrencies = Currency.values(); return Arrays.stream(allCurrencies) // 用flatMap实现单循环遍历所有货币对组合 .flatMap(fromCurrency -> Arrays.stream(allCurrencies) .map(toCurrency -> new CurrencyPair(fromCurrency, toCurrency))) .collect(Collectors.toMap( // 键为CurrencyPair实例 pair -> pair, // 同货币汇率固定为1.0,不同货币生成随机汇率 pair -> pair.from().equals(pair.to()) ? 1.0 : MIN_RATE + RANDOM.nextDouble() * (MAX_RATE - MIN_RATE) )); } }
方案2:Java 8-15 用AbstractMap.SimpleEntry作为键
如果项目未升级到Java 16,可使用JDK自带的SimpleEntry作为键:
import java.util.AbstractMap; import java.util.Map; import java.util.Random; import java.util.stream.Collectors; import java.util.Arrays; public class ExchangeRateProvider { private static final Random RANDOM = new Random(); private static final double MIN_RATE = 0.5; private static final double MAX_RATE = 2.5; public static Map<Map.Entry<Currency, Currency>, Double> buildExchangeRateMap() { Currency[] allCurrencies = Currency.values(); return Arrays.stream(allCurrencies) .flatMap(fromCurrency -> Arrays.stream(allCurrencies) .map(toCurrency -> new AbstractMap.SimpleEntry<>(fromCurrency, toCurrency))) .collect(Collectors.toMap( entry -> entry, entry -> entry.getKey().equals(entry.getValue()) ? 1.0 : MIN_RATE + RANDOM.nextDouble() * (MAX_RATE - MIN_RATE) )); } }
使用示例
转账时直接通过货币对获取汇率:
// 初始化汇率Map(建议在Spring容器中作为单例Bean注入) Map<CurrencyPair, Double> exchangeRates = ExchangeRateProvider.buildExchangeRateMap(); // 转账场景:从EUR账户转至USD账户 Currency from = Currency.EUR; Currency to = Currency.USD; Double rate = exchangeRates.get(new CurrencyPair(from, to)); // 计算实际到账金额:转出金额 * 汇率 double transferAmount = 100.0; double receivedAmount = transferAmount * rate;
优势说明
- 避免了传统双重循环的冗余代码,Stream API链式调用更易读和维护
- 键类型自动实现
equals()和hashCode(),不会出现Map键匹配错误 - 可灵活调整汇率范围,同货币汇率固定为1.0符合业务逻辑
- 完全基于JDK原生API,无第三方依赖
内容的提问来源于stack exchange,提问作者Jason
相关产品推荐
相关产品推荐

