|
2 | 2 |
|
3 | 3 | import java.lang.reflect.Array; |
4 | 4 | import java.util.AbstractMap; |
5 | | -import java.util.Arrays; |
6 | 5 | import java.util.Collection; |
7 | 6 | import java.util.IdentityHashMap; |
| 7 | +import java.util.LinkedHashMap; |
8 | 8 | import java.util.Map; |
| 9 | +import java.util.Objects; |
9 | 10 | import java.util.Set; |
10 | 11 |
|
11 | | -import com.cedarsoftware.util.CompactLinkedMap; |
12 | | - |
13 | 12 | /** |
14 | 13 | * This class holds a JSON object in a LinkedHashMap. |
15 | 14 | * LinkedHashMap used to keep fields in same order as they are |
|
34 | 33 | * limitations under the License. |
35 | 34 | */ |
36 | 35 | public class JsonObject extends JsonValue implements Map<Object, Object> { |
37 | | - private final Map<Object, Object> jsonStore = new CompactLinkedMap<>(); |
| 36 | +// private final Map<Object, Object> jsonStore = CompactMap.builder().compactSize(40).insertionOrder().build(); |
| 37 | + private final Map<Object, Object> jsonStore = new LinkedHashMap<>(); |
38 | 38 | private Integer hash = null; |
39 | 39 |
|
40 | 40 | // Explicit fields for meta data |
@@ -187,16 +187,59 @@ private int hashCode(Object array, Map<Object, Integer> seen) { |
187 | 187 | return result; |
188 | 188 | } |
189 | 189 |
|
| 190 | + @Override |
190 | 191 | public boolean equals(Object obj) { |
191 | 192 | if (this == obj) return true; |
192 | 193 | if (!(obj instanceof JsonObject)) return false; |
193 | 194 | JsonObject other = (JsonObject) obj; |
194 | 195 |
|
195 | | - if (!Arrays.deepEquals(new Object[]{items}, new Object[]{other.items})) return false; |
196 | | - if (!Arrays.deepEquals(new Object[]{keys}, new Object[]{other.keys})) return false; |
| 196 | + // Compare 'items' shallowly (element-by-element if both are arrays). |
| 197 | + if (!shallowArrayEquals(this.items, other.items)) { |
| 198 | + return false; |
| 199 | + } |
| 200 | + |
| 201 | + // Compare 'keys' shallowly (element-by-element if both are arrays). |
| 202 | + if (!shallowArrayEquals(this.keys, other.keys)) { |
| 203 | + return false; |
| 204 | + } |
| 205 | + |
| 206 | + // Compare the Map portion the standard way. |
197 | 207 | return jsonStore.equals(other.jsonStore); |
198 | 208 | } |
199 | 209 |
|
| 210 | + /** |
| 211 | + * Compare two Objects if both are arrays, element by element, |
| 212 | + * otherwise do a simple Object.equals(). |
| 213 | + */ |
| 214 | + private static boolean shallowArrayEquals(Object arr1, Object arr2) { |
| 215 | + if (arr1 == arr2) { |
| 216 | + return true; // Same reference or both null |
| 217 | + } |
| 218 | + if (arr1 == null || arr2 == null) { |
| 219 | + return false; // One is null, the other is not |
| 220 | + } |
| 221 | + |
| 222 | + // If both are arrays, compare lengths and elements with .equals() |
| 223 | + if (arr1.getClass().isArray() && arr2.getClass().isArray()) { |
| 224 | + int len1 = Array.getLength(arr1); |
| 225 | + int len2 = Array.getLength(arr2); |
| 226 | + if (len1 != len2) { |
| 227 | + return false; |
| 228 | + } |
| 229 | + for (int i = 0; i < len1; i++) { |
| 230 | + Object e1 = Array.get(arr1, i); |
| 231 | + Object e2 = Array.get(arr2, i); |
| 232 | + if (!Objects.equals(e1, e2)) { |
| 233 | + return false; |
| 234 | + } |
| 235 | + } |
| 236 | + return true; |
| 237 | + } |
| 238 | + |
| 239 | + // Fallback if not arrays: just do a regular equals check |
| 240 | + return Objects.equals(arr1, arr2); |
| 241 | + } |
| 242 | + |
200 | 243 | public boolean isEmpty() { |
201 | 244 | return size() < 1; |
202 | 245 | } |
@@ -304,6 +347,13 @@ void rehashMaps() { |
304 | 347 | for (int i = 0; i < len; i++) { |
305 | 348 | Object key = Array.get(keys, i); |
306 | 349 | Object value = Array.get(items, i); |
| 350 | + |
| 351 | + if (key instanceof String) { |
| 352 | + String k = (String) key; |
| 353 | + if (k.startsWith(JsonIo.PREFIX) && k.endsWith(JsonIo.SUFFIX)) { |
| 354 | + continue; |
| 355 | + } |
| 356 | + } |
307 | 357 | put(key, value); |
308 | 358 | if (targetMap != null) { |
309 | 359 | targetMap.put(key, value); |
|
0 commit comments