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

Java嵌套HashMap如何简化结构?怎样正确访问及修改其中的Booking对象

一、嵌套HashMap拆分优化方案

你当前的三层嵌套结构本质是通过三层键定位一个Booking对象:[日期(LocalDate)] → [房间号(Integer)] → [时间段(Entry<Long,Long>)] → Booking,完全可以拆分为两层HashMap降低使用复杂度,具体实现如下:

// 封装单日房间记录的自定义类,隐藏内层嵌套逻辑
class DailyRoomRecords {
    // 内部维护 房间号→(时间段→预订记录) 的映射
    private final Map<Integer, Map<Map.Entry<Long, Long>, Booking>> innerMap = new HashMap<>();
    
    // 封装查询方法,外部无需感知内部结构
    public Booking getBooking(Integer roomId, Long start, Long end) {
        var timeEntry = Map.entry(start, end);
        return innerMap.getOrDefault(roomId, Collections.emptyMap()).get(timeEntry);
    }
    
    // 封装新增/替换方法
    public void putBooking(Integer roomId, Long start, Long end, Booking booking) {
        innerMap.computeIfAbsent(roomId, k -> new HashMap<>()).put(Map.entry(start, end), booking);
    }
    
    // 直接提供获取当日所有Booking的工具方法
    public List<Booking> listAllBookings() {
        return innerMap.values().stream()
                .flatMap(m -> m.values().stream())
                .toList();
    }
}

// 拆分后仅需维护一层外层HashMap,整体为两层结构,使用难度大幅降低
private Map<LocalDate, DailyRoomRecords> roomRecord = new HashMap<>();

二、获取所有Booking对象的正确实现

原有代码问题

你当前的实现中两次多余的collect(Collectors.toMap())操作完全没有必要,不仅浪费性能,还会在出现重复键时直接抛出IllegalStateException异常,属于错误写法。

未改结构前的正确写法

如果暂时不调整原有嵌套结构,可以直接通过stream多次打平获取所有Booking:

List<Booking> slots = roomRecord.values().stream()
        // 打平第一层映射,拿到所有房间维度的Map
        .flatMap(dateMap -> dateMap.values().stream())
        // 打平第二层映射,直接拿到所有Booking对象
        .flatMap(roomMap -> roomMap.values().stream())
        .collect(Collectors.toList());
// Java 16+版本可以直接用.toList()替换最后一行collect操作

拆分优化后的写法

如果采用了上面的拆分方案,获取全量Booking的代码会更简洁:

List<Booking> slots = roomRecord.values().stream()
        .flatMap(dailyRecord -> dailyRecord.listAllBookings().stream())
        .collect(Collectors.toList());

三、指定Booking条目替换实现

原有嵌套结构下的替换方法

只要拿到三层键的对应参数,即可直接完成替换:

// 入参:目标日期localDate、目标房间号roomId、目标时间段start/end、新的Booking对象newBooking
roomRecord.computeIfPresent(localDate, (k, dateMap) -> {
    dateMap.computeIfPresent(roomId, (k1, roomMap) -> {
        roomMap.put(Map.entry(start, end), newBooking);
        return roomMap;
    });
    return dateMap;
});
// 如果需要兼容键不存在的场景,可将computeIfPresent替换为computeIfAbsent提前初始化层级

拆分优化后的替换方法

直接调用封装好的工具方法即可,无需关心内部嵌套逻辑:

roomRecord.computeIfAbsent(localDate, k -> new DailyRoomRecords())
        .putBooking(roomId, start, end, newBooking);

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.02 02:45:03