Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[FEATURE] Create a new CacheStrategy.DYNAMIC for the @EqualsAndHashCode #3802

Open
Pectics opened this issue Dec 24, 2024 · 0 comments
Open

Comments

@Pectics
Copy link

Pectics commented Dec 24, 2024

Describe the feature
Create a new CacheStrategy.DYNAMIC, which will only take effect if the member fields involved in the hashCode calculation are private, which will mark the hashCode as "recalculated required" when using the setter, and modify the hashCode the next time hashCode() is called.

Lomboked code:

@EqualsAndHashCode(cacheStrategy = CacheStrategy.DYNAMIC)
@Setter
public class Student {
    private long id;
    private String name;
    private int age;
}

Vanilla Java:

public class Student {
    private transient int $hashCodeCache;
    private transient boolean $hashCodeCacheChange;
    private long id;
    private String name;
    private int age;

    public Student() {
    }

    public boolean equals(Object o) {
        if (o == this) {
            return true;
        } else if (!(o instanceof Student)) {
            return false;
        } else {
            Student other = (Student)o;
            if (!other.canEqual(this)) {
                return false;
            } else if (this.id != other.id) {
                return false;
            } else if (this.age != other.age) {
                return false;
            } else {
                Object this$name = this.name;
                Object other$name = other.name;
                if (this$name == null) {
                    if (other$name == null) {
                        return true;
                    }
                } else if (this$name.equals(other$name)) {
                    return true;
                }

                return false;
            }
        }
    }

    protected boolean canEqual(Object other) {
        return other instanceof Student;
    }

    public int hashCode() {
        if (!this.$hashCodeCacheChange && this.$hashCodeCache != 0) {
            return this.$hashCodeCache;
        } else {
            int PRIME = 1;
            int result = 1;
            long $id = this.id;
            result = result * 59 + (int)($id >>> 32 ^ $id);
            result = result * 59 + this.age;
            Object $name = this.name;
            result = result * 59 + ($name == null ? 43 : $name.hashCode());
            if (result == 0) {
                result = Integer.MIN_VALUE;
            }

            this.$hashCodeCache = result;
            this.$hashCodeCacheChange = false;
            return result;
        }
    }

    public void setId(long id) {
        this.$hashCodeCacheChange = true;
        this.id = id;
    }

    public void setName(String name) {
        this.$hashCodeCacheChange = true;
        this.name = name;
    }

    public void setAge(int age) {
        this.$hashCodeCacheChange = true;
        this.age = age;
    }
}

Describe the target audience
The default CacheStrategy.NEVER has performance problems in large-scale data scenarios, and the dynamic caching function proposed in this issue can be used to optimize some of the member fields participating in hashCode calculation are private

Additional context
There are only minor optimizations to the current mechanism of "hashCode is recalculated every time hashCode() is called", and perhaps there are other better solutions, so I'll just propose a sketch of my own here 😉

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant