mirror of
https://github.com/tiennm99/lombok.git
synced 2026-10-14 18:18:48 +00:00
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:
1 parent
23dcc9f5a5
commit
251fd03cd7
25 files changed
+49
-44
No files matched your search
@@ -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() {
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
Reference in new issue
Block a user