Recipe Map 查找
基本信息
| 属性 | 值 |
|---|---|
| 类 | gttweaker.mods.gregtech.GTRecipeMap(11 行,无注解、无 ZenClass) |
| 静态字段 | public static HashMap<String, RecipeMap<?>> recipeMaps |
| 查询方法 | static RecipeMap<?> getRecipeMap(String map) |
| 匹配依据 | RecipeMap.unlocalizedName(不是 m.name) |
| 数据源 | RecipeMap.ALL_RECIPE_MAPS.values() |
| 使用者 | RA2Builder.addTo(String)、RecipeRemover.remove(map, ...) |
| 注册方式 | 不注册 —— 被上述两者静态引用 |
作用
把脚本传入的字符串(如 "benderRecipes"、"centrifugeRecipes")反查成 GT5 的 RecipeMap<?> 对象,并缓存结果避免重复流式扫描。
实现(GTRecipeMap.java:11-22)
public static RecipeMap<?> getRecipeMap(String map) {
if (!recipeMaps.containsKey(map)) {
recipeMaps.put(map,
RecipeMap.ALL_RECIPE_MAPS.values().stream()
.filter(m -> m.unlocalizedName.equals(map))
.findAny()
.orElse(null));
}
return recipeMaps.get(map);
}
containsKey → put → get 三步;负结果(null)也会被缓存(put(key, null)),因此一次查错的字符串不会重复扫描。
与 55 个机器类的对比
55 个机器类不用本类 —— 它们在编译期用 import static gregtech.api.recipe.RecipeMaps.xxx 直接引用常量,零运行时开销。只有需要运行时按字符串查的两处(RA2Builder.addTo(String) 与 RecipeRemover.remove(String, ...))才走本类。
数值
| 数值 | 值 |
|---|---|
| 类行数 | 11 |
| 查询方法数 | 1 |
| 缓存字段 | HashMap<String, RecipeMap<?>>(public static,可被外部改写) |
| 匹配字段 | unlocalizedName |
| 匹配方式 | equals + findAny(取任一) |
| 未找到 | 缓存 null,返回 null |
| 缓存负结果 | 是 |
| 线程安全 | 无(裸 HashMap) |
| 缓存清理 | 无 |
源码缺陷
findAny()在并行流下不确定、且不做重复校验:RecipeMap.ALL_RECIPE_MAPS.values().stream()是顺序流,findAny在顺序流上等价findFirst,故确定取第一个。若 GT5 存在两个同unlocalizedName的 map(理论上不该),会静默取第一个。public static缓存可被外部污染:recipeMaps是public,任何 mod 或脚本都能put一个错误的RecipeMap进去,影响本 mod 全部按名查询。- 裸
HashMap非线程安全:CraftTweaker 脚本通常在主线程执行,但若其他 mod 在异步线程调用getRecipeMap(该方法与recipeMaps均为public static),会触发HashMap并发写导致的结构损坏。源码无同步。 - 缓存永不过期也永不清理:GT5 的
RecipeMap在postInit后不会变,但若某个脚本在preInit阶段查到null并缓存,而 GT5 在之后才注册完 map,本 mod 会永久返回null。GTTweaker.onPostInit虽然存在,但只做registerClassRegistry,没有清理此缓存。 - 类无
private构造器:可被实例化,无实际意义(与GTTweakerRegistry同问题)。 - 11 行代码承担全部按名查询职责,却没有配套的错误信息 ——
null的处理完全交给调用方(两处调用方各写一条logError,文案不同)。 recipeMaps字段与getRecipeMap方法均为public/static但类无注解,IDE 中不会被识别为「mod 未注册」而误报。
相关条目
- RA2 Builder - 调用方 1(
addTo(String)) - Recipe Remover - 调用方 2(
remove(String, ...)) - 注册时序 -
postInit未清理本缓存 - GT++ 机器 - 对比:机器类全部编译期绑定 map