java - 替换重复的 java 对象,包括所有引用

标签 java object reference

我知道我们已经对 replacement of object instances 有疑问,答案总是:即使你可以,也永远不要这样做,这是黑魔法,但我不知道如何解决我的问题,所以让我解释一下......

我正在解析有关某些车辆及其特定模块的数据以存储在数据库中(这是关于游戏的)。每个Vehicle除其他数据外还包含许多CompatibleModules:

class Vehicle {
    String id;
    // other stuff...
    CompatibleModules modules;
}

CompatibleModules 在复杂的排列(依赖项和内容)中包含许多 Module 类的后代对象(例如 Engine extends Module) .

class CompatibleModules {
    Engine defaultEngine;
    List<Engine> compatibleEngines;
    // other stuff...
}

预计同一Module会在此类中被多次引用。

我只是在每辆车的基础上获取数据,所以即使某些车辆共享相同的模块(它们这样做,过度),我正在编写一个新的 Module 对象每辆车。完成解析后,我想通过删除重复项并单独存储模块来优化数据库,以便车辆仅通过 ID 引用模块。

这就是问题开始的地方:我可以轻松地从每个VehicleCompatibleModules结构中获取所有Module,存储它们位于 HashSet 中,从而检测冲突。但在我检测到冲突后,将 CompatibleModules 中重复项的所有引用替换为原始引用并不是一项简单的任务。

在这种情况下,替换所有重复项的引用的优雅方法是什么?

最佳答案

不要将模块视为车辆的一部分,而应将它们视为用于制造车辆的独立部件。

因此,您希望有一个工厂来管理可用的模块,当您制造车辆时,您会向工厂询问必要的模块。然后工厂确保每个模块“类型”或“实例”在整个系统中只存在一次。

[编辑] 一种解决方案是替换 List<Engine> compatibleEnginesSet<Engine> compatibleEngines = new LinkedHashSet<>();LinkedHashSet保留插入顺序。进行此更改后,您只需添加模块即可,它们将相互覆盖。

注意:要使其正常工作,您必须覆盖 equals()hashCode() .

如果你做不到这一点,那么创建一个具有良好 equals() 的包装对象和hashCode() 。清除重复项:

Set<Wrapper> wrappedEngines = new LinkedHashSet<>();    
for( Engine e : compatibleEngines ) {
    wrappedEngines.add( new Wrapper( e ) );
}
compatibleEngines.clear();
for( Wrapper e : wrappedEngines ) {
    compatibleEngines.add( e.getDelegate() );
}

关于java - 替换重复的 java 对象,包括所有引用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21481551/

相关文章:

configuration - 从 Biztalk BTSNTSvc.exe.config 访问 webreference appSettings

C++ 对象 : When should I use pointer or reference

java - Java EE7 和 CDI 2.0 的 Maven 依赖项是什么?

java - 如何使用 FileChannel 将一个文件的内容附加到另一个文件的末尾?

java - 为什么Java中的对象没有被全局初始化?

c++ 将一个类中的对象推送到另一个类中的 vector 中?

javascript - 如何更改 params JavaScript 中的对象属性

java - Tomcat、WAR 和多个操作系统

java - 如何用 2 种类型的 JSONObject 解析 JSONArray?

.net - 在 Visual Studio 中,编程 .NET,如何从项目引用中分辨出文件引用?