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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.17 13:52:57