
Iβm a senior software engineer loving clean code, and declarative designs. S.O.L.I.D. and agile methodologies fan.
Search for a command to run...

Iβm a senior software engineer loving clean code, and declarative designs. S.O.L.I.D. and agile methodologies fan.
No comments yet. Be the first to comment.
In this series, we will see several symptoms and situations that make us doubt the quality of our developments. We will present possible solutions. Most are just clues. They are no hard rules.
When you ignore your inheritance, you will have trouble with your parents TL;DR: Subclasses should honor ALL their parentβs contract. Problems π Wrong abstraction Subclassification for code reuse Misleading hierarchy Unused or overridden methods ...
Approve the logic once, then let it run the same way forever.

Different stages need different brains.

One Second Brain doesn't scale past one skull.

Style errors double when nobody enforces them.

Know who speaks before the skill runs TL;DR: Always define a clear role at the top of every skill file so you know whose perspective drives the execution. Common Mistake β You write a skill full of

TL;DR: When you use mutable objects as keys in hashed collections, changing them breaks contracts.
When you use mutable objects as keys in hashed collections, changing them key after after you add a related objec can make it unretrievable.
This happens because the hash code changes and the collection can't find the object in the correct bucket.
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
[X] Semi-Automatic
You can detect this smell by checking if you use mutable objects as keys in hash-based collections.
Automated tools like linters or IDE inspections can also flag mutable keys.
[X] Intermediate
The bijection between the real world and your program is important because it ensures that your objects accurately reflect the relationships they are supposed to represent.
In the real world, keys are often immutable (e.g., IDs, names).
When you model these keys as mutable objects, you break the one-to-one correspondence between the real world and your program in the MAPPER.
When you break this bijection using mutable keys, you make the map's inconsistent leading to retrieval failures and unexpected behavior.
AI generators might create this smell if they generate mutable objects as keys without considering the implications.
This is seldom the case since AI generators suffer from primitive obsession.
AI generators can detect this smell with instructions to analyze the use of mutable objects in hash-based collections and flag potential issues.
You can instruct the AI to look for classes without final fields or methods that modify the object's state after creation.
Remember: AI Assistants make lots of mistakes
| Without Proper Instructions | With Specific Instructions |
| ChatGPT | ChatGPT |
| Claude | Claude |
| Perplexity | Perplexity |
| Copilot | Copilot |
| Gemini | Gemini |
| DeepSeek | DeepSeek |
| Meta AI | Meta AI |
When you use mutable objects as keys, you risk breaking the contract between the key's state and hash code.
Use immutable objects to avoid this issue.
Code Smells are my opinion.
Photo by Kathyryn Tripp on Unsplash
The most important property of a program is whether it accomplishes the intention of its user.
C.A.R. Hoare
This article is part of the CodeSmell Series.