简体   繁体   中英

Java: Generate Per Member Equals Possibly With Lombok or Intellij IDEA?

Is there any generator that helps with the following topic:

In a java class, I have a member attribute:

private String attribute1;

I want to have a generator or something similar, that helps me to have these lines of code:

public boolean equalsAttribute1(MyClass myClass) {
    return myClass.getAttribute1().equals(this.attribute1);
}

Does Lombok offer this possibility? Or is there a Intellij IDEA plugin for it?

The closest you'll get is a live template. For a live template define a template as:

public boolean equals$NAME$($CLASS$ myClass) {
    return myClass.get$NAME$().equals(this.$CamelCaseName$);
}

The variables are defined as:

NAME=capitalize(clipboard())
CLASS=className()
CamelCaseName=camelCase(NAME)

Bind this to something such as "eq" followed by tab.

Now copy the attribute name to the clipboard, move the cursor to where you want the method and type "eq" followed by tab. It should expand to give you what you want.

You could probably define a macro to do the whole lot for you.

Note that your code mixes getters and fields and throws an NPE.

Do you really need a bunch of methods or would a single, more general method do?

I'd strongly prefer the latter as for a bunch of methods to be useful, you'd need a bunch of callers and the code bloat would proliferate.

For this, you can use reflection or annotation processing. Reflection has some runtime overhead (not as bad as it used to), but it can access private members (unless forbidden by a security manager).

Something like the following should do

public static ImmutableSet<String> differingFields(Object o1, Object o2) throws IllegalAccessException {
    checkNotNull(o1);
    checkNotNull(o2);
    checkArgument(o1.getClass() != o2.getClass());
    ImmutableSet.Builder<String> result = ImmutableSet.builder();
    for (Field f : o1.getClass().getDeclaredFields()) {
        f.setAccessible(true);
        if (!Objects.equals(f.get(o1), f.get(o2))) {
            result.add(f.getName());
        }
    }
    return result.build();
}

It uses Guava, 'cause I prefer immutable results, but it's not needed. The inefficiencies come from autoboxing and reflective access and are most probably acceptable.

It only works when instances of exactly the same class are passed in. It ignores inherited fields. This is easily fixable.

Instead of just the field names, you could return Guava's MapDifference or alike. Instead of implementing differingFields , you could convert your objects to maps and work on them.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM