Java 使用LinkedHashMap.containsKey()会产生奇怪的结果
我对Java编程有点陌生,但目前正在为一些生产过程开发一个模拟器。在这样做的过程中,我发现了一些非常奇怪的东西,我似乎无法理解,也无法在互联网或任何其他问题上找到 作为生产工厂的一部分,我需要一个特定的组件来确定它是否可以根据产品的配方将产品发送到任何机器。为此,我发现使用LinkedHashMap是解决此类问题的一个很好的实现。下一段代码描述了机器的设置并创建了初始HashMap。它使用一个机器配置列表,每个配置都有一个与之兼容的配方列表。HashMap的形式是这样的,我可以通过搜索到达物品的配方来找到可用的机器Java 使用LinkedHashMap.containsKey()会产生奇怪的结果,java,Java,我对Java编程有点陌生,但目前正在为一些生产过程开发一个模拟器。在这样做的过程中,我发现了一些非常奇怪的东西,我似乎无法理解,也无法在互联网或任何其他问题上找到 作为生产工厂的一部分,我需要一个特定的组件来确定它是否可以根据产品的配方将产品发送到任何机器。为此,我发现使用LinkedHashMap是解决此类问题的一个很好的实现。下一段代码描述了机器的设置并创建了初始HashMap。它使用一个机器配置列表,每个配置都有一个与之兼容的配方列表。HashMap的形式是这样的,我可以通过搜索到达物品的
public void setupMachines(List<Config> configurationList) {
for (int i = 0; i<configurationList.size(); i++) {
Config config = configurationList.get(i);
Machine machine = new Machine(config, config.getName());
for (int j = 0; j<config.getCompatibleRecipes().size(); j++){
Recipe key = config.getCompatibleRecipes().get(j);
if (!recipeInfo.containsKey(key)) {
recipeInfo.put(key, new ArrayList<Machine>());
}
recipeInfo.get(key).add();
}
}
}
在机器组的类中,以下代码用于根据从模拟器获得的配方为某个项目找到合适的机器,并将该项目从队列发送到该机器
public void checkAvailableMachinesAndRedirectItems() {
int i = 0;
while (i<queue.size()) {
Lot lot = queue.get(i);
Recipe key = lot.getRecipe();
if (recipeInfo.containsKey(key)) {
if (!recipeInfo.get(key).isEmpty()) {
Machine machine = recipeInfo.get(key).get(0);
lot.setReservedMachine(machine);
removeFromRecipeInfo(machine);
queue.remove(lot);
machine.take(lot);
}
else { i++; }
}
else { i++; }
}
}
在模拟器的一个测试文件中,我必须遵循一段代码来构建运行模拟所需的两个简单配方和一组机器
MachineGroup machineGroup = new MachineGroup();
ArrayList<Config> configurationList = new ArrayList<Config>();
//create two recipes:
Recipe recipeA = model.getSimFactory().createRecipe("RecipeA");
Recipe recipeB = model.getSimFactory().createRecipe("RecipeB");
//both recipes need to have the process step of passing through a machine
recipeA.add( new ProcessStep("MachineStep", machineGroup, ...with a bunch of variables... ) );
recipeB.add( new ProcessStep("MachineStep", machineGroup, ...with a bunch of variables... ) );
//Create two machine configurations:
Config configA = new Config(...bunch of variables...);
Config configB = new Config(...bunch of variables...);
//For this example both configs have just one compatible recipe:
configA.addCompatibleRecipe(recipeA);
configB.addCompatibleRecipe(recipeB);
//add both configs tho a list:
configurationList.add(configA);
configurationList.add(configB);
// -- THIS IS THE IMPORTANT STATEMENT -- \\
machineGroup.setupMachines(configurationList);
// *** ------- **** \\
//create a sink for deleted items that are completed:
model.getSimFactory().createProcessStepAndAddToRecipe("sinkStep", sink, recipeA);
model.getSimFactory().createProcessStepAndAddToRecipe("sinkStep", sink, recipeB);
//create a source for items with different recipes and inter arrival times:
Source sourceA = model.getSimFactory().createSource("SourceA", recipeA, 10L);
Source sourceB = model.getSimFactory().createSource("SourceB", recipeB, 8L);
engine.init(model);
model.addComponent(machineGroup);
engine.runSimulation(50L);
它初始化了一个模拟这个东西已经正常工作了,使用machineGroup.setupMachines函数创建工厂设置,初始HashMap如下:{RecipeEA=[MachineConfigA],RecipeB=[MachineConfigB]}。但是,第二段代码中询问recipeInfo是否包含属于该批次的配方的第一条IF语句从未返回true,即使该批次配方的哈希代码与当前在HashMap中充当键值的配方的哈希代码相同
现在由于我自己不知道的原因,我也尝试了engine.runSimulation函数上方的machineGroup.setupMachines函数,奇怪的是IF语句现在似乎工作正常。我最初认为这与在构建初始HashMap源和接收器后向配方中添加一些步骤有关,但通过浏览互联网,我得出的结论是,即使对象本身可能已经更改,HashMap中的键值也只是一个仍然指向对象的指针,对吗?同样,它们具有相同的哈希代码
我的上司也无法理解这种行为,但由于他经常使用LinkedHashMap,他和我都非常想了解更多关于这个话题的信息。有人知道这里发生了什么吗
我想重复一次,我还不是javaguru,因此您的答案中的简化和示例非常值得赞赏:。通常,这个问题与您存储在HashMap键中的对象有关。该类不重写hashCode或/或不重写equals 您应该验证存储和测试的对象是否相等 内部比较代码可以帮助您理解原因。HashMap.getNode的简化Java源代码
如果您看到HashMap键的不可靠行为,我的第一个猜测是Recipe.hashCode方法正在基于可变状态计算其返回值。将键对象添加到HashMap后更改其hashCode将破坏HashMap的功能。编辑您的问题,并包括配方类的代码,以获得更确切的答案。
do {
if (e.hash == hash &&
((k = e.key) == key || (key != null && key.equals(k))))
return e;
} while ((e = e.next) != null);