The hashCode() method now generates a magic prime instead of 0 for the hash of null values; this reduces collisions.

This commit is contained in:
Reinier Zwitserloot committed 2015-06-25 00:13:12 +02:00
1 parent 23dcc9f5a5
commit 251fd03cd7
25 files changed
+49 -44

No files matched your search

+1
View File
@@ -4,6 +4,7 @@ Lombok Changelog
### v1.16.5 "Edgy Guinea Pig"
* BUGFIX: Parameterized static methods with `@Builder` would produce compiler errors in javac. [Issue #793](https://code.google.com/p/projectlombok/issues/detail?id=793).
* PERFORMANCE: the config system caused significant slowdowns in eclipse if the filesystem is very slow (network file system) or has a slow authentication system.
* FEATURE: the `hashCode()` method generated by lombok via `@EqualsAndHashCode`, `@Data`, and `@Value` is now smarter about nulls; they are treated as if they hash to a magic prime instead of 0, which reduces hash collisions.
### v1.16.4 (April 14th, 2015)
* BUGFIX: Lombok now works with Eclipse Mars.
@@ -68,6 +68,10 @@ public class HandlerUtil {
return 97;
}
public static int primeForNull() {
return 43;
}
/** Checks if the given name is a valid identifier.
*
* If it is, this returns {@code true} and does nothing else.
@@ -358,7 +358,7 @@ public class HandleEqualsAndHashCode extends EclipseAnnotationHandler<EqualsAndH
statements.add(createResultCalculation(source, fieldAccessor));
} else /* objects */ {
/* final java.lang.Object $fieldName = this.fieldName; */
/* $fieldName == null ? 0 : $fieldName.hashCode() */
/* $fieldName == null ? NULL_PRIME : $fieldName.hashCode() */
statements.add(createLocalDeclaration(source, dollarFieldName, generateQualifiedTypeRef(source, TypeConstants.JAVA_LANG_OBJECT), fieldAccessor));
SingleNameReference copy1 = new SingleNameReference(dollarFieldName, p);
@@ -375,8 +375,8 @@ public class HandleEqualsAndHashCode extends EclipseAnnotationHandler<EqualsAndH
setGeneratedBy(nullLiteral, source);
EqualExpression objIsNull = new EqualExpression(copy2, nullLiteral, OperatorIds.EQUAL_EQUAL);
setGeneratedBy(objIsNull, source);
IntLiteral int0 = makeIntLiteral("0".toCharArray(), source);
ConditionalExpression nullOrHashCode = new ConditionalExpression(objIsNull, int0, hashCodeCall);
IntLiteral intMagic = makeIntLiteral(String.valueOf(HandlerUtil.primeForNull()).toCharArray(), source);
ConditionalExpression nullOrHashCode = new ConditionalExpression(objIsNull, intMagic, hashCodeCall);
nullOrHashCode.sourceStart = pS; nullOrHashCode.sourceEnd = pE;
setGeneratedBy(nullOrHashCode, source);
statements.add(createResultCalculation(source, nullOrHashCode));
@@ -307,7 +307,7 @@ public class HandleEqualsAndHashCode extends JavacAnnotationHandler<EqualsAndHas
statements.append(createResultCalculation(typeNode, maker.Apply(List.<JCExpression>nil(), hcMethod, List.of(fieldAccessor))));
} else /* objects */ {
/* final java.lang.Object $fieldName = this.fieldName; */
/* $fieldName == null ? 0 : $fieldName.hashCode() */
/* $fieldName == null ? NULL_PRIME : $fieldName.hashCode() */
Name dollarFieldName = dollar.append(((JCVariableDecl)fieldNode.get()).name);
statements.append(maker.VarDef(maker.Modifiers(finalFlag), dollarFieldName, genJavaLangTypeRef(typeNode, "Object"), fieldAccessor));
@@ -315,7 +315,7 @@ public class HandleEqualsAndHashCode extends JavacAnnotationHandler<EqualsAndHas
JCExpression hcCall = maker.Apply(List.<JCExpression>nil(), maker.Select(maker.Ident(dollarFieldName), typeNode.toName("hashCode")),
List.<JCExpression>nil());
JCExpression thisEqualsNull = maker.Binary(CTC_EQUAL, maker.Ident(dollarFieldName), maker.Literal(CTC_BOT, null));
statements.append(createResultCalculation(typeNode, maker.Conditional(thisEqualsNull, maker.Literal(0), hcCall)));
statements.append(createResultCalculation(typeNode, maker.Conditional(thisEqualsNull, maker.Literal(HandlerUtil.primeForNull()), hcCall)));
}
}
@@ -100,7 +100,7 @@ class AccessorsPrefix3 {
final int PRIME = 59;
int result = 1;
final java.lang.Object $fName = this.getName();
result = result * PRIME + ($fName == null ? 0 : $fName.hashCode());
result = result * PRIME + ($fName == null ? 43 : $fName.hashCode());
return result;
}
}
@@ -50,7 +50,7 @@ class DataOnLocalClass1 {
int result = 1;
result = result * PRIME + this.getX();
final java.lang.Object $name = this.getName();
result = result * PRIME + ($name == null ? 0 : $name.hashCode());
result = result * PRIME + ($name == null ? 43 : $name.hashCode());
return result;
}
@java.lang.Override
@@ -116,7 +116,7 @@ class DataOnLocalClass2 {
final int PRIME = 59;
int result = 1;
final java.lang.Object $name = this.getName();
result = result * PRIME + ($name == null ? 0 : $name.hashCode());
result = result * PRIME + ($name == null ? 43 : $name.hashCode());
return result;
}
@java.lang.Override
@@ -49,7 +49,7 @@ class Data1 {
int result = 1;
result = result * PRIME + this.getX();
final java.lang.Object $name = this.getName();
result = result * PRIME + ($name == null ? 0 : $name.hashCode());
result = result * PRIME + ($name == null ? 43 : $name.hashCode());
return result;
}
@java.lang.Override
@@ -110,7 +110,7 @@ class Data2 {
int result = 1;
result = result * PRIME + this.getX();
final java.lang.Object $name = this.getName();
result = result * PRIME + ($name == null ? 0 : $name.hashCode());
result = result * PRIME + ($name == null ? 43 : $name.hashCode());
return result;
}
@java.lang.Override
@@ -165,7 +165,7 @@ final class Data3 {
int result = 1;
result = result * PRIME + this.getX();
final java.lang.Object $name = this.getName();
result = result * PRIME + ($name == null ? 0 : $name.hashCode());
result = result * PRIME + ($name == null ? 43 : $name.hashCode());
return result;
}
@java.lang.Override
@@ -47,7 +47,7 @@ class DataWithGetter {
result = result * PRIME + this.getX();
result = result * PRIME + this.getY();
final java.lang.Object $z = this.getZ();
result = result * PRIME + ($z == null ? 0 : $z.hashCode());
result = result * PRIME + ($z == null ? 43 : $z.hashCode());
return result;
}
@java.lang.Override
@@ -47,7 +47,7 @@ class DataWithGetterNone {
result = result * PRIME + this.x;
result = result * PRIME + this.y;
final java.lang.Object $z = this.z;
result = result * PRIME + ($z == null ? 0 : $z.hashCode());
result = result * PRIME + ($z == null ? 43 : $z.hashCode());
return result;
}
@java.lang.Override
@@ -38,9 +38,9 @@ class EqualsAndHashCode {
result = result * PRIME + java.util.Arrays.hashCode(this.y);
result = result * PRIME + java.util.Arrays.deepHashCode(this.z);
final java.lang.Object $a = this.a;
result = result * PRIME + ($a == null ? 0 : $a.hashCode());
result = result * PRIME + ($a == null ? 43 : $a.hashCode());
final java.lang.Object $b = this.b;
result = result * PRIME + ($b == null ? 0 : $b.hashCode());
result = result * PRIME + ($b == null ? 43 : $b.hashCode());
return result;
}
}
@@ -41,9 +41,9 @@ class EqualsAndHashCodeWithOnParam {
result = result * PRIME + java.util.Arrays.hashCode(this.y);
result = result * PRIME + java.util.Arrays.deepHashCode(this.z);
final java.lang.Object $a = this.a;
result = result * PRIME + ($a == null ? 0 : $a.hashCode());
result = result * PRIME + ($a == null ? 43 : $a.hashCode());
final java.lang.Object $b = this.b;
result = result * PRIME + ($b == null ? 0 : $b.hashCode());
result = result * PRIME + ($b == null ? 43 : $b.hashCode());
return result;
}
}
@@ -34,9 +34,9 @@ class GetterLazyEahcToString {
final int PRIME = 59;
int result = 1;
final java.lang.Object $value = this.getValue();
result = result * PRIME + ($value == null ? 0 : $value.hashCode());
result = result * PRIME + ($value == null ? 43 : $value.hashCode());
final java.lang.Object $value2 = this.value2;
result = result * PRIME + ($value2 == null ? 0 : $value2.hashCode());
result = result * PRIME + ($value2 == null ? 43 : $value2.hashCode());
return result;
}
@@ -39,7 +39,7 @@ final class Value1 {
int result = 1;
result = result * PRIME + this.getX();
final java.lang.Object $name = this.getName();
result = result * PRIME + ($name == null ? 0 : $name.hashCode());
result = result * PRIME + ($name == null ? 43 : $name.hashCode());
return result;
}
@java.lang.Override
@@ -96,7 +96,7 @@ class Value2 {
int result = 1;
result = result * PRIME + this.getX();
final java.lang.Object $name = this.getName();
result = result * PRIME + ($name == null ? 0 : $name.hashCode());
result = result * PRIME + ($name == null ? 43 : $name.hashCode());
return result;
}
@java.lang.Override
@@ -93,7 +93,7 @@ class AccessorsChain {
final int PRIME = 59;
int result = 1;
final java.lang.Object $fName = this.getName();
result = ((result * PRIME) + (($fName == null) ? 0 : $fName.hashCode()));
result = ((result * PRIME) + (($fName == null) ? 43 : $fName.hashCode()));
return result;
}
}
@@ -40,7 +40,7 @@ class DataOnLocalClass1 {
int result = 1;
result = ((result * PRIME) + this.getX());
final java.lang.Object $name = this.getName();
result = ((result * PRIME) + (($name == null) ? 0 : $name.hashCode()));
result = ((result * PRIME) + (($name == null) ? 43 : $name.hashCode()));
return result;
}
public @java.lang.Override @java.lang.SuppressWarnings("all") @javax.annotation.Generated("lombok") java.lang.String toString() {
@@ -89,7 +89,7 @@ class DataOnLocalClass2 {
final int PRIME = 59;
int result = 1;
final java.lang.Object $name = this.getName();
result = ((result * PRIME) + (($name == null) ? 0 : $name.hashCode()));
result = ((result * PRIME) + (($name == null) ? 43 : $name.hashCode()));
return result;
}
public @java.lang.Override @java.lang.SuppressWarnings("all") @javax.annotation.Generated("lombok") java.lang.String toString() {
@@ -35,7 +35,7 @@ import lombok.Data;
int result = 1;
result = ((result * PRIME) + this.getX());
final java.lang.Object $name = this.getName();
result = ((result * PRIME) + (($name == null) ? 0 : $name.hashCode()));
result = ((result * PRIME) + (($name == null) ? 43 : $name.hashCode()));
return result;
}
public @java.lang.Override @java.lang.SuppressWarnings("all") @javax.annotation.Generated("lombok") java.lang.String toString() {
@@ -82,7 +82,7 @@ import lombok.Data;
int result = 1;
result = ((result * PRIME) + this.getX());
final java.lang.Object $name = this.getName();
result = ((result * PRIME) + (($name == null) ? 0 : $name.hashCode()));
result = ((result * PRIME) + (($name == null) ? 43 : $name.hashCode()));
return result;
}
public @java.lang.Override @java.lang.SuppressWarnings("all") @javax.annotation.Generated("lombok") java.lang.String toString() {
@@ -124,7 +124,7 @@ final @Data class Data3 {
int result = 1;
result = ((result * PRIME) + this.getX());
final java.lang.Object $name = this.getName();
result = ((result * PRIME) + (($name == null) ? 0 : $name.hashCode()));
result = ((result * PRIME) + (($name == null) ? 43 : $name.hashCode()));
return result;
}
public @java.lang.Override @java.lang.SuppressWarnings("all") @javax.annotation.Generated("lombok") java.lang.String toString() {
@@ -35,7 +35,7 @@
result = ((result * PRIME) + this.getX());
result = ((result * PRIME) + this.getY());
final java.lang.Object $z = this.getZ();
result = ((result * PRIME) + (($z == null) ? 0 : $z.hashCode()));
result = ((result * PRIME) + (($z == null) ? 43 : $z.hashCode()));
return result;
}
public @java.lang.Override @java.lang.SuppressWarnings("all") @javax.annotation.Generated("lombok") java.lang.String toString() {
@@ -35,7 +35,7 @@
result = ((result * PRIME) + this.x);
result = ((result * PRIME) + this.y);
final java.lang.Object $z = this.z;
result = ((result * PRIME) + (($z == null) ? 0 : $z.hashCode()));
result = ((result * PRIME) + (($z == null) ? 43 : $z.hashCode()));
return result;
}
public @java.lang.Override @java.lang.SuppressWarnings("all") @javax.annotation.Generated("lombok") java.lang.String toString() {
@@ -41,9 +41,9 @@
result = ((result * PRIME) + java.util.Arrays.hashCode(this.y));
result = ((result * PRIME) + java.util.Arrays.deepHashCode(this.z));
final java.lang.Object $a = this.a;
result = ((result * PRIME) + (($a == null) ? 0 : $a.hashCode()));
result = ((result * PRIME) + (($a == null) ? 43 : $a.hashCode()));
final java.lang.Object $b = this.b;
result = ((result * PRIME) + (($b == null) ? 0 : $b.hashCode()));
result = ((result * PRIME) + (($b == null) ? 43 : $b.hashCode()));
return result;
}
}
@@ -44,9 +44,9 @@
result = ((result * PRIME) + java.util.Arrays.hashCode(this.y));
result = ((result * PRIME) + java.util.Arrays.deepHashCode(this.z));
final java.lang.Object $a = this.a;
result = ((result * PRIME) + (($a == null) ? 0 : $a.hashCode()));
result = ((result * PRIME) + (($a == null) ? 43 : $a.hashCode()));
final java.lang.Object $b = this.b;
result = ((result * PRIME) + (($b == null) ? 0 : $b.hashCode()));
result = ((result * PRIME) + (($b == null) ? 43 : $b.hashCode()));
return result;
}
}
@@ -49,9 +49,9 @@
final int PRIME = 59;
int result = 1;
final java.lang.Object $value = this.getValue();
result = ((result * PRIME) + (($value == null) ? 0 : $value.hashCode()));
result = ((result * PRIME) + (($value == null) ? 43 : $value.hashCode()));
final java.lang.Object $value2 = this.value2;
result = ((result * PRIME) + (($value2 == null) ? 0 : $value2.hashCode()));
result = ((result * PRIME) + (($value2 == null) ? 43 : $value2.hashCode()));
return result;
}
public @java.lang.Override @java.lang.SuppressWarnings("all") @javax.annotation.Generated("lombok") java.lang.String toString() {
@@ -27,7 +27,7 @@ final @lombok.Value class Value1 {
int result = 1;
result = ((result * PRIME) + this.getX());
final java.lang.Object $name = this.getName();
result = ((result * PRIME) + (($name == null) ? 0 : $name.hashCode()));
result = ((result * PRIME) + (($name == null) ? 43 : $name.hashCode()));
return result;
}
public @java.lang.Override @java.lang.SuppressWarnings("all") @javax.annotation.Generated("lombok") java.lang.String toString() {
@@ -72,7 +72,7 @@ final @lombok.Value class Value1 {
int result = 1;
result = ((result * PRIME) + this.getX());
final java.lang.Object $name = this.getName();
result = ((result * PRIME) + (($name == null) ? 0 : $name.hashCode()));
result = ((result * PRIME) + (($name == null) ? 43 : $name.hashCode()));
return result;
}
public @java.lang.Override @java.lang.SuppressWarnings("all") @javax.annotation.Generated("lombok") java.lang.String toString() {
+3 -3
View File
@@ -62,7 +62,7 @@ public class DataExample {
final int PRIME = 59;
int result = 1;
final long temp1 = Double.doubleToLongBits(this.getScore());
result = (result*PRIME) + (this.getName() == null ? 0 : this.getName().hashCode());
result = (result*PRIME) + (this.getName() == null ? 43 : this.getName().hashCode());
result = (result*PRIME) + this.getAge();
result = (result*PRIME) + (int)(temp1 ^ (temp1 >>> 32));
result = (result*PRIME) + Arrays.deepHashCode(this.getTags());
@@ -111,8 +111,8 @@ public class DataExample {
@Override public int hashCode() {
final int PRIME = 59;
int result = 1;
result = (result*PRIME) + (this.getName() == null ? 0 : this.getName().hashCode());
result = (result*PRIME) + (this.getValue() == null ? 0 : this.getValue().hashCode());
result = (result*PRIME) + (this.getName() == null ? 43 : this.getName().hashCode());
result = (result*PRIME) + (this.getValue() == null ? 43 : this.getValue().hashCode());
return result;
}
}
@@ -27,7 +27,7 @@ public class EqualsAndHashCodeExample {
final int PRIME = 59;
int result = 1;
final long temp1 = Double.doubleToLongBits(this.score);
result = (result*PRIME) + (this.name == null ? 0 : this.name.hashCode());
result = (result*PRIME) + (this.name == null ? 43 : this.name.hashCode());
result = (result*PRIME) + (int)(temp1 ^ (temp1 >>> 32));
result = (result*PRIME) + Arrays.deepHashCode(this.tags);
return result;
+3 -3
View File
@@ -49,7 +49,7 @@ public final class ValueExample {
final int PRIME = 59;
int result = 1;
final Object $name = this.getName();
result = result * PRIME + ($name == null ? 0 : $name.hashCode());
result = result * PRIME + ($name == null ? 43 : $name.hashCode());
result = result * PRIME + this.getAge();
final long $score = Double.doubleToLongBits(this.getScore());
result = result * PRIME + (int)($score >>> 32 ^ $score);
@@ -106,9 +106,9 @@ public final class ValueExample {
final int PRIME = 59;
int result = 1;
final Object $name = this.getName();
result = result * PRIME + ($name == null ? 0 : $name.hashCode());
result = result * PRIME + ($name == null ? 43 : $name.hashCode());
final Object $value = this.getValue();
result = result * PRIME + ($value == null ? 0 : $value.hashCode());
result = result * PRIME + ($value == null ? 43 : $value.hashCode());
return result;
}