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 未注册」而误报。

相关条目