更改密钥,丢失值
TL;DR:当您使用可变对象作为散列集合中的键时,更改它们会破坏契约。
当您使用可变对象作为散列集合中的键时,在添加相关对象之后更改它们的键可能会使其无法检索。
发生这种情况的原因是哈希码发生了变化,并且集合无法在正确的存储桶中找到对象。
class MutableKey { int id; MutableKey(int newId) { this.id = newId; } @Override public int hashCode() { return this.id; } @Override public boolean equals(Object objectToCompare) { if (this == objectToCompare) return true; MutableKey that = (MutableKey) objectToCompare; return id == that.id; } } MutableKey key = new MutableKey(42); Map<MutableKey, String> map = new HashMap<>(); map.put(key, "Yes Album"); // The key mutates key.id = 90125; // Now you cannont retrieve the album System.out.println(map.get(key)); // Output: null
class ImmutableKey { private final int id; ImmutableKey(int newId) { this.id = newId; } @Override public int hashCode() { return this.id; } @Override public boolean equals(Object objectToCompare) { if (this == objectToCompare) return true; ImmutableKey that = (ImmutableKey) objectToCompare; return id == that.id; } } ImmutableKey key = new ImmutableKey(42); Map<ImmutableKey, String> map = new HashMap<>(); map.put(key, "Yes Album"); System.out.println(map.get(key)); // Output: Yes Album
您可以通过检查是否使用可变对象作为基于哈希的集合中的键来检测这种气味。
诸如 linters 或 IDE 检查之类的自动化工具也可以标记可变键。
现实世界和程序之间的双射很重要,因为它可以确保对象准确反映它们应该表示的关系。
在现实世界中,密钥通常是不可变的(例如,ID,名称)。
当您将这些键建模为可变对象时,您会打破现实世界与MAPPER中的程序之间的一一对应关系。
当使用可变键破坏这种双射时,会导致映射不一致,从而导致检索失败和意外行为。
如果人工智能生成器生成可变对象作为键而不考虑其含义,则可能产生这种气味。
由于人工智能生成器受到原始痴迷的影响,因此这种情况很少发生。
人工智能生成器可以通过指令分析基于哈希的集合中可变对象的使用情况并标记潜在问题来检测这种气味。
您可以指示 AI 寻找没有最终字段或在创建后修改对象状态的方法的类。
记住:人工智能助手会犯很多错误
没有正确指导 | 有具体说明 |
---|---|
当您使用可变对象作为键时,您可能会面临破坏键的状态和哈希码之间的契约的风险。
使用不可变对象来避免此问题。
https://hackernoon.com/how-to-find-the-stinky-parts-of-your-code-part-xxxiv
https://hackernoon.com/how-to-find-the-stinky-parts-of-your-code-part-xxv
https://hackernoon.com/how-to-find-the-stinky-parts-of-your-code-part-xxiv
https://hackernoon.com/how-to-find-the-stinky-parts-of-your-code-part-xxxvi
https://hackernoon.com/how-to-find-the-stinky-parts-of-your-code-part-xviii
https://hackernoon.com/how-to-find-the-stinky-parts-of-your-code-part-xxvi
https://hackernoon.com/how-to-find-the-stinky-parts-of-your-code-part-xlii
我认为“代码异味”是“代码异味”。
凯瑟琳·特里普 (Kathryn Tripp)在Unsplash上拍摄的照片
程序最重要的属性是它是否能实现用户的意图。
卡尔·霍尔
本文是 CodeSmell 系列的一部分。