Fix Map key collision
This commit is contained in:
parent
a4ee9ebf4d
commit
1e0236bbe0
2 changed files with 62 additions and 1 deletions
|
|
@ -16,6 +16,7 @@ import java.time.LocalDateTime;
|
|||
import java.time.LocalTime;
|
||||
import java.util.Collection;
|
||||
import java.util.Date;
|
||||
import java.util.HashMap;
|
||||
import java.util.IdentityHashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
|
|
@ -256,6 +257,7 @@ public final class Serializer {
|
|||
|
||||
private static JsonElement serializeMap(Map<?, ?> map, IdentityHashMap<Object, Boolean> seen, int depth) {
|
||||
JsonObject jsonObject = new JsonObject();
|
||||
Map<String, Integer> keyCount = new HashMap<>();
|
||||
int count = 0;
|
||||
|
||||
for (Map.Entry<?, ?> entry : map.entrySet()) {
|
||||
|
|
@ -263,7 +265,8 @@ public final class Serializer {
|
|||
jsonObject.addProperty("__truncated__", map.size() - count + " more entries");
|
||||
break;
|
||||
}
|
||||
String key = entry.getKey() != null ? entry.getKey().toString() : "null";
|
||||
String baseKey = entry.getKey() != null ? entry.getKey().toString() : "null";
|
||||
String key = getUniqueKey(baseKey, keyCount);
|
||||
jsonObject.add(key, serialize(entry.getValue(), seen, depth + 1));
|
||||
count++;
|
||||
}
|
||||
|
|
@ -311,4 +314,16 @@ public final class Serializer {
|
|||
return clazz.getName();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a unique key for map serialization, appending _N suffix for duplicates.
|
||||
*/
|
||||
private static String getUniqueKey(String baseKey, Map<String, Integer> keyCount) {
|
||||
int count = keyCount.getOrDefault(baseKey, 0);
|
||||
keyCount.put(baseKey, count + 1);
|
||||
|
||||
if (count == 0) {
|
||||
return baseKey;
|
||||
}
|
||||
return baseKey + "_" + count;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -251,6 +251,52 @@ class SerializerTest {
|
|||
}
|
||||
}
|
||||
|
||||
@Nested
|
||||
@DisplayName("Map Key Collision")
|
||||
class MapKeyCollisionTests {
|
||||
|
||||
@Test
|
||||
@DisplayName("should handle duplicate toString keys without losing data")
|
||||
void testDuplicateToStringKeys() {
|
||||
Map<Object, String> map = new LinkedHashMap<>();
|
||||
map.put(new SameToString("A"), "first");
|
||||
map.put(new SameToString("B"), "second");
|
||||
|
||||
String json = Serializer.toJson(map);
|
||||
// Both values should be present, not overwritten
|
||||
assertTrue(json.contains("first"), "First value should be present, got: " + json);
|
||||
assertTrue(json.contains("second"), "Second value should be present, got: " + json);
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("should append index to duplicate keys")
|
||||
void testDuplicateKeysGetIndex() {
|
||||
Map<Object, String> map = new LinkedHashMap<>();
|
||||
map.put(new SameToString("A"), "first");
|
||||
map.put(new SameToString("B"), "second");
|
||||
map.put(new SameToString("C"), "third");
|
||||
|
||||
String json = Serializer.toJson(map);
|
||||
// Should have same-key, same-key_1, same-key_2
|
||||
assertTrue(json.contains("\"same-key\""), "Original key should be present");
|
||||
assertTrue(json.contains("\"same-key_1\""), "First duplicate should have _1 suffix");
|
||||
assertTrue(json.contains("\"same-key_2\""), "Second duplicate should have _2 suffix");
|
||||
}
|
||||
}
|
||||
|
||||
static class SameToString {
|
||||
String internalValue;
|
||||
|
||||
SameToString(String value) {
|
||||
this.internalValue = value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "same-key";
|
||||
}
|
||||
}
|
||||
|
||||
@Nested
|
||||
@DisplayName("Class and Proxy Types")
|
||||
class ClassAndProxyTests {
|
||||
|
|
|
|||
Loading…
Reference in a new issue