Add hashcode support to ConfigurationPropertyName
Provide a hashcode implementation for `ConfigurationPropertyName` so that instances can be stored in Map without them all ending up in the same bucket. See gh-20625
This commit is contained in:
@@ -64,6 +64,8 @@ public final class ConfigurationPropertyName implements Comparable<Configuration
|
||||
|
||||
private String string;
|
||||
|
||||
private int hashCode;
|
||||
|
||||
private ConfigurationPropertyName(Elements elements) {
|
||||
this.elements = elements;
|
||||
this.uniformElements = new CharSequence[elements.getSize()];
|
||||
@@ -322,46 +324,22 @@ public final class ConfigurationPropertyName implements Comparable<Configuration
|
||||
}
|
||||
}
|
||||
|
||||
private boolean defaultElementEquals(Elements e1, Elements e2, int i) {
|
||||
int l1 = e1.getLength(i);
|
||||
int l2 = e2.getLength(i);
|
||||
boolean indexed1 = e1.getType(i).isIndexed();
|
||||
boolean indexed2 = e2.getType(i).isIndexed();
|
||||
int i1 = 0;
|
||||
int i2 = 0;
|
||||
while (i1 < l1) {
|
||||
if (i2 >= l2) {
|
||||
return false;
|
||||
}
|
||||
char ch1 = indexed1 ? e1.charAt(i, i1) : Character.toLowerCase(e1.charAt(i, i1));
|
||||
char ch2 = indexed2 ? e2.charAt(i, i2) : Character.toLowerCase(e2.charAt(i, i2));
|
||||
if (!indexed1 && !ElementsParser.isAlphaNumeric(ch1)) {
|
||||
i1++;
|
||||
}
|
||||
else if (!indexed2 && !ElementsParser.isAlphaNumeric(ch2)) {
|
||||
i2++;
|
||||
}
|
||||
else if (ch1 != ch2) {
|
||||
return false;
|
||||
}
|
||||
else {
|
||||
i1++;
|
||||
i2++;
|
||||
}
|
||||
}
|
||||
if (i2 < l2) {
|
||||
if (indexed2) {
|
||||
return false;
|
||||
}
|
||||
do {
|
||||
char ch2 = Character.toLowerCase(e2.charAt(i, i2++));
|
||||
if (ElementsParser.isAlphaNumeric(ch2)) {
|
||||
private boolean fastElementEquals(Elements e1, Elements e2, int i) {
|
||||
int length1 = e1.getLength(i);
|
||||
int length2 = e2.getLength(i);
|
||||
if (length1 == length2) {
|
||||
int i1 = 0;
|
||||
while (length1-- != 0) {
|
||||
char ch1 = e1.charAt(i, i1);
|
||||
char ch2 = e2.charAt(i, i1);
|
||||
if (ch1 != ch2) {
|
||||
return false;
|
||||
}
|
||||
i1++;
|
||||
}
|
||||
while (i2 < l2);
|
||||
return true;
|
||||
}
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
private boolean dashIgnoringElementEquals(Elements e1, Elements e2, int i) {
|
||||
@@ -404,27 +382,70 @@ public final class ConfigurationPropertyName implements Comparable<Configuration
|
||||
return true;
|
||||
}
|
||||
|
||||
private boolean fastElementEquals(Elements e1, Elements e2, int i) {
|
||||
int length1 = e1.getLength(i);
|
||||
int length2 = e2.getLength(i);
|
||||
if (length1 == length2) {
|
||||
int i1 = 0;
|
||||
while (length1-- != 0) {
|
||||
char ch1 = e1.charAt(i, i1);
|
||||
char ch2 = e2.charAt(i, i1);
|
||||
if (ch1 != ch2) {
|
||||
return false;
|
||||
}
|
||||
private boolean defaultElementEquals(Elements e1, Elements e2, int i) {
|
||||
int l1 = e1.getLength(i);
|
||||
int l2 = e2.getLength(i);
|
||||
boolean indexed1 = e1.getType(i).isIndexed();
|
||||
boolean indexed2 = e2.getType(i).isIndexed();
|
||||
int i1 = 0;
|
||||
int i2 = 0;
|
||||
while (i1 < l1) {
|
||||
if (i2 >= l2) {
|
||||
return false;
|
||||
}
|
||||
char ch1 = indexed1 ? e1.charAt(i, i1) : Character.toLowerCase(e1.charAt(i, i1));
|
||||
char ch2 = indexed2 ? e2.charAt(i, i2) : Character.toLowerCase(e2.charAt(i, i2));
|
||||
if (!indexed1 && !ElementsParser.isAlphaNumeric(ch1)) {
|
||||
i1++;
|
||||
}
|
||||
return true;
|
||||
else if (!indexed2 && !ElementsParser.isAlphaNumeric(ch2)) {
|
||||
i2++;
|
||||
}
|
||||
else if (ch1 != ch2) {
|
||||
return false;
|
||||
}
|
||||
else {
|
||||
i1++;
|
||||
i2++;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
if (i2 < l2) {
|
||||
if (indexed2) {
|
||||
return false;
|
||||
}
|
||||
do {
|
||||
char ch2 = Character.toLowerCase(e2.charAt(i, i2++));
|
||||
if (ElementsParser.isAlphaNumeric(ch2)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
while (i2 < l2);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return 0;
|
||||
int hashCode = this.hashCode;
|
||||
Elements elements = this.elements;
|
||||
if (hashCode == 0 && elements.getSize() != 0) {
|
||||
for (int elementIndex = 0; elementIndex < elements.getSize(); elementIndex++) {
|
||||
int elementHashCode = 0;
|
||||
boolean indexed = elements.getType(elementIndex).isIndexed();
|
||||
int length = elements.getLength(elementIndex);
|
||||
for (int i = 0; i < length; i++) {
|
||||
char ch = elements.charAt(elementIndex, i);
|
||||
if (!indexed) {
|
||||
ch = Character.toLowerCase(ch);
|
||||
}
|
||||
if (ElementsParser.isAlphaNumeric(ch)) {
|
||||
elementHashCode = 31 * elementHashCode + ch;
|
||||
}
|
||||
}
|
||||
hashCode = 31 * hashCode + elementHashCode;
|
||||
}
|
||||
}
|
||||
return hashCode;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2012-2019 the original author or authors.
|
||||
* Copyright 2012-2020 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -545,17 +545,18 @@ class ConfigurationPropertyNameTests {
|
||||
ConfigurationPropertyName n13 = ConfigurationPropertyName.of("f-o-o[b-a-r--]");
|
||||
ConfigurationPropertyName n14 = ConfigurationPropertyName.of("[1]");
|
||||
ConfigurationPropertyName n15 = ConfigurationPropertyName.of("[-1]");
|
||||
assertThat(n01.hashCode()).isEqualTo(n02.hashCode());
|
||||
assertThat(n01.hashCode()).isEqualTo(n02.hashCode());
|
||||
assertThat(n01.hashCode()).isEqualTo(n03.hashCode());
|
||||
assertThat(n01.hashCode()).isEqualTo(n04.hashCode());
|
||||
assertThat(n01.hashCode()).isEqualTo(n11.hashCode());
|
||||
assertThat((Object) n01).isEqualTo(n01);
|
||||
assertThat(n01.hashCode()).isEqualTo(n01.hashCode());
|
||||
assertThat((Object) n01).isEqualTo(n02);
|
||||
assertThat(n01.hashCode()).isEqualTo(n02.hashCode());
|
||||
assertThat((Object) n01).isEqualTo(n03);
|
||||
assertThat(n01.hashCode()).isEqualTo(n03.hashCode());
|
||||
assertThat((Object) n01).isEqualTo(n04);
|
||||
assertThat(n01.hashCode()).isEqualTo(n04.hashCode());
|
||||
assertThat((Object) n11).isEqualTo(n03);
|
||||
assertThat(n11.hashCode()).isEqualTo(n03.hashCode());
|
||||
assertThat((Object) n03).isEqualTo(n11);
|
||||
assertThat(n03.hashCode()).isEqualTo(n11.hashCode());
|
||||
assertThat((Object) n01).isNotEqualTo(n05);
|
||||
assertThat((Object) n01).isNotEqualTo(n06);
|
||||
assertThat((Object) n07).isNotEqualTo(n08);
|
||||
|
||||
Reference in New Issue
Block a user