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

如何创建不包含重复WeaponAccessory类型的集合?

确保WeaponAccessory集合中同类型唯一的实现方案

这是个很常见的需求——给武器做配件系统,确保同类型配件只能装一个。下面给你几种实用的实现方式,以Java为例(从类名来看应该是Java场景):

方案1:用HashMap以类型为键(最推荐)

利用HashMap的键唯一性,直接把配件的Class对象作为键,配件实例作为值。这样天然保证同类型配件只会存在一个,而且查询、添加、删除的效率都很高(O(1))。

首先定义基础的接口和实现类:

// 配件接口
public interface WeaponAccessory {
    String getEffect(); // 示例方法:返回配件效果
}

// 抑制器实现
public class Suppressor implements WeaponAccessory {
    @Override
    public String getEffect() {
        return "降低枪声与后坐力";
    }
}

// 扩容弹匣实现
public class ExtendedMagazine implements WeaponAccessory {
    @Override
    public String getEffect() {
        return "提升弹容量";
    }
}

然后是M16类的实现:

import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import java.util.Collection;

public class M16 {
    // 核心存储:键是配件类型,值是配件实例
    private final Map<Class<? extends WeaponAccessory>, WeaponAccessory> accessories = new HashMap<>();

    // 添加配件的方法,返回是否添加成功
    public boolean addAccessory(WeaponAccessory accessory) {
        if (accessory == null) {
            throw new IllegalArgumentException("配件不能为null");
        }
        Class<? extends WeaponAccessory> accessoryType = accessory.getClass();
        // 检查类型是否已存在
        if (accessories.containsKey(accessoryType)) {
            return false; // 已有同类型配件,添加失败
        }
        accessories.put(accessoryType, accessory);
        return true;
    }

    // 获取所有配件(返回不可修改集合,防止外部破坏约束)
    public Collection<WeaponAccessory> getAccessories() {
        return Collections.unmodifiableCollection(accessories.values());
    }

    // 根据类型快速获取配件
    @SuppressWarnings("unchecked")
    public <T extends WeaponAccessory> T getAccessory(Class<T> type) {
        return (T) accessories.get(type);
    }

    // 根据类型移除配件
    public boolean removeAccessory(Class<? extends WeaponAccessory> type) {
        return accessories.remove(type) != null;
    }
}

优点:

  • 实现简单,利用Java集合的天然特性避免重复
  • 按类型查询配件的效率极高
  • 代码易读易维护

方案2:自定义包装类+HashSet

如果更倾向于用Set来存储,可以创建一个包装类,让包装类的equals()和hashCode()基于配件的类型,这样HashSet会自动过滤同类型的元素。

// 配件包装类
class AccessoryWrapper {
    private final WeaponAccessory accessory;

    public AccessoryWrapper(WeaponAccessory accessory) {
        this.accessory = accessory;
    }

    public WeaponAccessory getAccessory() {
        return accessory;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        AccessoryWrapper that = (AccessoryWrapper) o;
        // 比较配件的类型是否相同
        return accessory.getClass().equals(that.accessory.getClass());
    }

    @Override
    public int hashCode() {
        return accessory.getClass().hashCode();
    }
}

// M16类实现
import java.util.HashSet;
import java.util.Set;
import java.util.stream.Collectors;

public class M16 {
    private final Set<AccessoryWrapper> accessoryWrappers = new HashSet<>();

    public boolean addAccessory(WeaponAccessory accessory) {
        if (accessory == null) {
            throw new IllegalArgumentException("配件不能为null");
        }
        // HashSet的add方法会自动判断是否重复(基于包装类的equals/hashCode)
        return accessoryWrappers.add(new AccessoryWrapper(accessory));
    }

    public Set<WeaponAccessory> getAccessories() {
        return accessoryWrappers.stream()
                .map(AccessoryWrapper::getAccessory)
                .collect(Collectors.toUnmodifiableSet());
    }
}

缺点:需要额外编写包装类,代码量稍多;按类型查询配件需要遍历集合,效率不如HashMap。

方案3:普通集合+手动检查(适合小型集合)

如果你的配件数量很少,也可以用普通的List,在添加时手动遍历检查是否已有同类型元素:

import java.util.ArrayList;
import java.util.List;

public class M16 {
    private final List<WeaponAccessory> accessories = new ArrayList<>();

    public boolean addAccessory(WeaponAccessory accessory) {
        if (accessory == null) {
            throw new IllegalArgumentException("配件不能为null");
        }
        // 遍历检查是否已有同类型配件
        boolean hasSameType = accessories.stream()
                .anyMatch(a -> a.getClass().equals(accessory.getClass()));
        if (hasSameType) {
            return false;
        }
        accessories.add(accessory);
        return true;
    }

    // 返回不可修改的列表,防止外部修改
    public List<WeaponAccessory> getAccessories() {
        return List.copyOf(accessories);
    }
}

缺点:每次添加都要遍历集合,性能随集合大小下降;查询同类型配件也需要遍历。


总结

如果追求性能和易用性,**方案1(HashMap)**是最优选择,它不仅能保证同类型唯一,还能快速按类型获取、删除配件,代码也最简洁。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.26 10:09:25