如何优雅转换ID映射为AccountDto映射(无需显式实例化Map)
优雅生成AccountDto映射的方案
场景回顾
现有DTO类:
@Builder public class AccountDto { private Long id; private BigDecimal balance; private Currency currency; }
Currency为自定义枚举(含约300种货币),已生成ID映射:
public static final Map<Currency, List<Long>> ACCOUNT_IDS_OF_GIVEN_CURRENCIES = Map.of( Currency.USD, LongStream.rangeClosed(1L, 10L).boxed().toList(), Currency.GBP, LongStream.rangeClosed(11L, 20L).boxed().toList(), Currency.EUR, LongStream.rangeClosed(21L, 30L).boxed().toList(), Currency.INR, LongStream.rangeClosed(31L, 40L).boxed().toList() );
需要生成键相同、值为AccountDto列表的映射,避免显式实例化HashMap。
方案1:纯Java流式API实现
无需第三方依赖,利用Collectors.toMap直接生成目标映射:
import java.util.stream.Collectors; Map<Currency, List<AccountDto>> accountMap = ACCOUNT_IDS_OF_GIVEN_CURRENCIES.entrySet() .stream() .collect(Collectors.toMap( Map.Entry::getKey, entry -> entry.getValue().stream() .map(id -> AccountDto.builder() .id(id) .balance(BigDecimal.ZERO) // 可根据需求设置随机值或固定值 .currency(entry.getKey()) .build()) .toList() ));
说明:遍历原映射的Entry,直接复用键,将每个ID转换为AccountDto并收集为列表,最终通过流式操作一次性生成目标映射,完全无需手动创建HashMap。
方案2:Guava库实现
若项目已引入Guava,可使用Maps.transformEntries简化代码,直接获取每个Entry的键和值进行转换:
import com.google.common.collect.Maps; Map<Currency, List<AccountDto>> accountMap = Maps.transformEntries( ACCOUNT_IDS_OF_GIVEN_CURRENCIES, (currency, ids) -> ids.stream() .map(id -> AccountDto.builder() .id(id) .balance(BigDecimal.ZERO) .currency(currency) .build()) .toList() ); // 如需不可变映射,结合ImmutableMap: import com.google.common.collect.ImmutableMap; Map<Currency, List<AccountDto>> immutableAccountMap = ImmutableMap.copyOf(accountMap);
说明:transformEntries直接接收Entry的键和值,避免了反向查找Currency的操作,代码更简洁;生成的映射默认是原映射的视图(原映射变化会同步影响该映射),若需要独立的不可变映射,可通过ImmutableMap.copyOf转换。
方案3:Apache Commons Collections实现
若项目已引入Apache Commons Collections,可使用TransformedMap结合EntryTransformer实现:
import org.apache.commons.collections4.map.TransformedMap; import org.apache.commons.collections4.functors.EntryTransformer; EntryTransformer<Currency, List<Long>, List<AccountDto>> entryTransformer = (currency, ids) -> ids.stream() .map(id -> AccountDto.builder() .id(id) .balance(BigDecimal.ZERO) .currency(currency) .build()) .toList(); Map<Currency, List<AccountDto>> accountMap = TransformedMap.transformedMap( new HashMap<>(ACCOUNT_IDS_OF_GIVEN_CURRENCIES), null, // 不对键做转换 entryTransformer );
说明:该方案会基于传入的Map生成一个带有转换逻辑的映射,适合需要动态转换的场景;若仅需一次性生成映射,纯Java流式API方案更轻量。
内容的提问来源于stack exchange,提问作者Jason
相关产品推荐
相关产品推荐

