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

如何创建双Key的HashMap?单类实现双键取值方案

嘿,这个需求我熟——想要一个能通过Player对象+字符串标识(比如"fly"、"speed")双键定位值的HashMap,还得只用一个类实现对吧?这就给你安排一个简洁靠谱的方案:

双键HashMap实现方案(单类版本)

核心思路

我们可以在单个类里封装一个普通HashMap,不过把Player和字符串标识打包成一个复合键作为HashMap的键。关键是要给这个复合键正确实现equals()和hashCode()方法,确保只有当两个键(Player和标识字符串)都完全匹配时,才会被HashMap识别为同一个键。

完整代码实现(泛型灵活版)

这个版本支持任意键类型,如果你后续需要扩展其他键类型也能用:

import java.util.HashMap;
import java.util.Objects;

public class DoubleKeyHashMap<K1, K2, V> {
    // 内部用普通HashMap存数据,键是我们自定义的复合键
    private final HashMap<Key, V> internalMap = new HashMap<>();

    // 内部复合键类,仅当前类可见,不用对外暴露
    private class Key {
        private final K1 firstKey;
        private final K2 secondKey;

        public Key(K1 firstKey, K2 secondKey) {
            this.firstKey = firstKey;
            this.secondKey = secondKey;
        }

        // 必须重写equals,保证两个键都匹配才相等
        @Override
        public boolean equals(Object o) {
            if (this == o) return true;
            if (o == null || getClass() != o.getClass()) return false;
            Key key = (Key) o;
            return Objects.equals(firstKey, key.firstKey) && Objects.equals(secondKey, key.secondKey);
        }

        // 必须重写hashCode,让相同的复合键生成相同的哈希值
        @Override
        public int hashCode() {
            return Objects.hash(firstKey, secondKey);
        }
    }

    // 对外的存值方法,直接传两个键和对应值
    public void put(K1 firstKey, K2 secondKey, V value) {
        internalMap.put(new Key(firstKey, secondKey), value);
    }

    // 对外的取值方法,传两个键就能拿到对应值
    public V get(K1 firstKey, K2 secondKey) {
        return internalMap.get(new Key(firstKey, secondKey));
    }

    // 可选:添加移除方法
    public V remove(K1 firstKey, K2 secondKey) {
        return internalMap.remove(new Key(firstKey, secondKey));
    }

    // 可选:获取当前存储的键值对数量
    public int size() {
        return internalMap.size();
    }
}

针对你的需求优化(固定键类型版)

如果不需要泛型的灵活性,直接把第一个键固定为Player,第二个固定为String,代码会更贴合你的场景:

import java.util.HashMap;
import java.util.Objects;

public class PlayerAttributeStore {
    private final HashMap<Key, Integer> internalMap = new HashMap<>();

    private class Key {
        private final Player player;
        private final String attributeType;

        public Key(Player player, String attributeType) {
            this.player = player;
            this.attributeType = attributeType;
        }

        @Override
        public boolean equals(Object o) {
            if (this == o) return true;
            if (o == null || getClass() != o.getClass()) return false;
            Key key = (Key) o;
            return Objects.equals(player, key.player) && Objects.equals(attributeType, key.attributeType);
        }

        @Override
        public int hashCode() {
            return Objects.hash(player, attributeType);
        }
    }

    public void savePlayerAttribute(Player player, String attributeType, Integer value) {
        internalMap.put(new Key(player, attributeType), value);
    }

    public Integer getPlayerAttribute(Player player, String attributeType) {
        return internalMap.get(new Key(player, attributeType));
    }
}

使用示例

假设你的Player类已经正确实现了equals()和hashCode()(这很重要,不然复合键的匹配会出错),使用起来非常简单:

// 创建Player对象
Player bob = new Player("Bob");
PlayerAttributeStore store = new PlayerAttributeStore();

// 存储Bob的飞行和速度属性
store.savePlayerAttribute(bob, "fly", 15);
store.savePlayerAttribute(bob, "speed", 8);

// 获取属性值
Integer bobFlyLevel = store.getPlayerAttribute(bob, "fly"); // 返回15
Integer bobSpeedLevel = store.getPlayerAttribute(bob, "speed"); // 返回8

关键注意事项

  • 一定要确保Player类正确实现了equals()和hashCode(),否则复合键无法正确识别同一个Player对象
  • 内部的Key类是私有,对外完全透明,用户只需要调用暴露的put/get方法即可,不用关心内部实现
  • 整个逻辑都封装在一个类里,完全符合你“仅使用一个类”的要求

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.21 08:29:14