diff --git a/src/main/java/org/jsoup/internal/SharedConstants.java b/src/main/java/org/jsoup/internal/SharedConstants.java index 141e1df9a8..b0f490ca6d 100644 --- a/src/main/java/org/jsoup/internal/SharedConstants.java +++ b/src/main/java/org/jsoup/internal/SharedConstants.java @@ -11,6 +11,7 @@ public final class SharedConstants { public static final String EndRangeKey = "jsoup.end"; public static final int DefaultBufferSize = 1024 * 32; + public static final int HashPrime = 31; private SharedConstants() {} } diff --git a/src/main/java/org/jsoup/nodes/Attributes.java b/src/main/java/org/jsoup/nodes/Attributes.java index ff2f0b995e..86a2e27870 100644 --- a/src/main/java/org/jsoup/nodes/Attributes.java +++ b/src/main/java/org/jsoup/nodes/Attributes.java @@ -555,20 +555,34 @@ public int deduplicate(ParseSettings settings) { return 0; boolean preserve = settings.preserveAttributeCase(); int dupes = 0; - OUTER: for (int i = 0; i < keys.length; i++) { - for (int j = i + 1; j < keys.length; j++) { - if (keys[j] == null) - continue OUTER; // keys.length doesn't shrink when removing, so re-test - if ((preserve && keys[i].equals(keys[j])) || (!preserve && keys[i].equalsIgnoreCase(keys[j]))) { - dupes++; - remove(j); - j--; - } + + for (int i = 0; i < keys.length; i++) { + dupes += removeDuplicatesFrom(i, preserve); + } + + return dupes; + } + + private int removeDuplicatesFrom(int index, boolean preserve) { + int dupes = 0; + + for (int j = index + 1; j < keys.length; j++) { + if (keys[j] == null) + break; // keys.length doesn't shrink when removing, so re-test + + if (isDuplicate(keys[index], keys[j], preserve)) { + dupes++; + remove(j); + j--; } } return dupes; } + private boolean isDuplicate(String key1, String key2, boolean preserve) { + return preserve ? key1.equals(key2) : key1.equalsIgnoreCase(key2); + } + private static class Dataset extends AbstractMap { private final Attributes attributes; diff --git a/src/main/java/org/jsoup/nodes/Range.java b/src/main/java/org/jsoup/nodes/Range.java index ccc1db5f51..d661470341 100644 --- a/src/main/java/org/jsoup/nodes/Range.java +++ b/src/main/java/org/jsoup/nodes/Range.java @@ -109,7 +109,7 @@ public boolean equals(Object o) { @Override public int hashCode() { int result = start.hashCode(); - result = 31 * result + end.hashCode(); + result = HashPrime * result + end.hashCode(); return result; } @@ -199,8 +199,8 @@ public boolean equals(Object o) { @Override public int hashCode() { int result = pos; - result = 31 * result + lineNumber; - result = 31 * result + columnNumber; + result = HashPrime * result + lineNumber; + result = HashPrime * result + columnNumber; return result; } } @@ -246,7 +246,7 @@ public Range valueRange() { @Override public int hashCode() { int result = nameRange.hashCode(); - result = 31 * result + valueRange.hashCode(); + result = HashPrime * result + valueRange.hashCode(); return result; } }