Rectangle 27 200

The commons/lang builders are great and I have been using them for years without noticeable performance overhead (with and without hibernate). But as Alain writes, the Guava way is even nicer:

Here's a sample Bean:

public class Bean{

    private String name;
    private int length;
    private List<Bean> children;

}

Here's equals() and hashCode() implemented with Commons/Lang:

and here with Guava:

@Override
public int hashCode(){
    return Objects.hashCode(name, length, children);
}

@Override
public boolean equals(final Object obj){
    if(obj instanceof Bean){
        final Bean other = (Bean) obj;
        return Objects.equal(name, other.name)
            && length == other.length // special handling for primitives
            && Objects.equal(children, other.children);
    } else{
        return false;
    }
}

As you can see the Guava version is shorter and avoids superfluous helper objects. In case of equals, it even allows for short-circuiting the evaluation if an earlier Object.equal() call returns false (to be fair: commons / lang has an ObjectUtils.equals(obj1, obj2) method with identical semantics which could be used instead of EqualsBuilder to allow short-circuiting as above).

So: yes, the commons lang builders are very preferable over manually constructed equals() and hashCode() methods (or those awful monsters Eclipse will generate for you), but the Guava versions are even better.

And a note about Hibernate:

be careful about using lazy collections in your equals(), hashCode() and toString() implementations. That will fail miserably if you don't have an open Session.

a) in both versions of equals() above, you might want to use one or both of these shortcuts also:

@Override
public boolean equals(final Object obj){
    if(obj == this) return true;  // test for reference equality
    if(obj == null) return false; // test for null
    // continue as above

b) depending on your interpretation of the equals() contract, you might also change the line(s)

if(obj instanceof Bean){
// make sure you run a null check before this
    if(obj.getClass() == getClass()){

If you use the second version, you probably also want to call super(equals()) inside your equals() method. Opinions differ here, the topic is discussed in this question:

(although it's about hashCode(), the same applies to equals())

Note (inspired by Comment from kayahr)

Objects.hashCode(..) (just as the underlying Arrays.hashCode(...)) might perform badly if you have many primitive fields. In such cases, EqualsBuilder may actually be the better solution.

If I'm reading it correctly, Josh Bloch says in Effective Java, Item 8, that you should not use getClass() in your equals() method; rather you should use instanceof.

@SeanPatrickFloyd The Guava-way not only creates an array object for the varargs, it also converts ALL parameters to objects. So when you pass 10 int values to it then you will end up with 10 Integer objects and an array object. The commons-lang solution only creates a single object, no matter how many values you append to the hash code. The same problem with equals. Guava converts all values to objects, commons-lang only creates a single new object.

@wonhee I strongly disagree that this is better. Using Reflection to calculate hash codes is not something I would ever do. The performance overhead is probably negligible, but it just feels wrong.

@kaushik making a class final actually solves the potential problems of both versions (instanceof and getClass()), as long as you implement your equals() in leaf classes only

java - Apache Commons equals/hashCode builder - Stack Overflow

java hibernate equals apache-commons hashcode
Rectangle 27 200

The commons/lang builders are great and I have been using them for years without noticeable performance overhead (with and without hibernate). But as Alain writes, the Guava way is even nicer:

Here's a sample Bean:

public class Bean{

    private String name;
    private int length;
    private List<Bean> children;

}

Here's equals() and hashCode() implemented with Commons/Lang:

and here with Guava:

@Override
public int hashCode(){
    return Objects.hashCode(name, length, children);
}

@Override
public boolean equals(final Object obj){
    if(obj instanceof Bean){
        final Bean other = (Bean) obj;
        return Objects.equal(name, other.name)
            && length == other.length // special handling for primitives
            && Objects.equal(children, other.children);
    } else{
        return false;
    }
}

As you can see the Guava version is shorter and avoids superfluous helper objects. In case of equals, it even allows for short-circuiting the evaluation if an earlier Object.equal() call returns false (to be fair: commons / lang has an ObjectUtils.equals(obj1, obj2) method with identical semantics which could be used instead of EqualsBuilder to allow short-circuiting as above).

So: yes, the commons lang builders are very preferable over manually constructed equals() and hashCode() methods (or those awful monsters Eclipse will generate for you), but the Guava versions are even better.

And a note about Hibernate:

be careful about using lazy collections in your equals(), hashCode() and toString() implementations. That will fail miserably if you don't have an open Session.

a) in both versions of equals() above, you might want to use one or both of these shortcuts also:

@Override
public boolean equals(final Object obj){
    if(obj == this) return true;  // test for reference equality
    if(obj == null) return false; // test for null
    // continue as above

b) depending on your interpretation of the equals() contract, you might also change the line(s)

if(obj instanceof Bean){
// make sure you run a null check before this
    if(obj.getClass() == getClass()){

If you use the second version, you probably also want to call super(equals()) inside your equals() method. Opinions differ here, the topic is discussed in this question:

(although it's about hashCode(), the same applies to equals())

Note (inspired by Comment from kayahr)

Objects.hashCode(..) (just as the underlying Arrays.hashCode(...)) might perform badly if you have many primitive fields. In such cases, EqualsBuilder may actually be the better solution.

If I'm reading it correctly, Josh Bloch says in Effective Java, Item 8, that you should not use getClass() in your equals() method; rather you should use instanceof.

@SeanPatrickFloyd The Guava-way not only creates an array object for the varargs, it also converts ALL parameters to objects. So when you pass 10 int values to it then you will end up with 10 Integer objects and an array object. The commons-lang solution only creates a single object, no matter how many values you append to the hash code. The same problem with equals. Guava converts all values to objects, commons-lang only creates a single new object.

@wonhee I strongly disagree that this is better. Using Reflection to calculate hash codes is not something I would ever do. The performance overhead is probably negligible, but it just feels wrong.

@kaushik making a class final actually solves the potential problems of both versions (instanceof and getClass()), as long as you implement your equals() in leaf classes only

java - Apache Commons equals/hashCode builder - Stack Overflow

java hibernate equals apache-commons hashcode
Rectangle 27 165

In my opinion the better choice is Guava (formerly known as Google collections):

  • it absolutely follows the Collections API requirements
  • CacheBuilder and it's predecessor MapMaker are just plain awesome

Apache Commons Collections is a good library as well, but it has long failed to provide a generics-enabled version (which is a major drawback for a collections API in my opinion) and generally seems to be in a maintenance/don't-do-too-much-work-on-it mode Recently Commons Collections has picked up some steam again, but it has some catching up to do..

If download size/memory footprint/code size is an issue then Apache Commons Collections might be a better candidate, since it is a common dependency of other libraries. Therefore using it in your own code as well could potentially be done without adding any additional dependencies. Edit: This particular "advantage" has been partially subverted by now, since many new libraries actually depend on Guava and not on Apache Commons Collections.

What I really wonder: why are there no other opinions? Should I be playing the devils advocate? Apache Commons Collections is not a bad library, after all.

Since the Apache lacks generics, I think it's obvious which of these two is the future. Google is the next logical step forward. It's a strange feeling, though, that it's built by The Giant... but as long as it's under a free license it shouldn't matter even if it was built by Microsoft. I guess.

MapMaker

@RoyTruelove It doesn't surprise me that much has changed and I would love to hear your current thoughts on the matter, or perhaps a link to a more recent review/comparison. I like the "immutable by default / mutable only if required" philosophy and the inclusion of generics in guava, but the materials I have been reading may all have been dated like you say this thread has become.

Sign up for our newsletter and get our top new questions delivered to your inbox (see an example).

java - Apache Commons vs. Guava (formerly "Google Collections") - Stac...

java collections apache-commons guava
Rectangle 27 68

The most important things I've found that make Google Collections the place to start:

  • Consistency with Collections framework (Josh Bloch was a key player in this framework)
  • Correctness. These guys are desperately tied to getting this problem right; they have something like 25K unit tests, and are tied to getting the API just right.

Here's a great Youtube video of a talk that was given by the primary author and he does a good job of discussing what is worth knowing about this library.

Great further reading about Google Collections: javalobby.org/articles/google-collections (an interview with its main creators). Look for the question "What is unique about your approach? How does it differ to, for example, the Apache Commons Collection?"

java - Apache Commons vs. Guava (formerly "Google Collections") - Stac...

java collections apache-commons guava
Rectangle 27 61

Why did Google build all this, when it could have tried to improve the Apache Commons Collections instead?

The Apache Commons Collections very clearly did not meet our needs. It does not use generics, which is a problem for us as we hate to get compilation warnings from our code. It has also been in a "holding pattern" for a long time. We could see that it would require a pretty major investment from us to fix it up until we were happy to use it, and in the meantime, our own library was already growing organically.

An important difference between the Apache library and ours is that our collections very faithfully adhere to the contracts specified by the JDK interfaces they implement. If you review the Apache documentation, you'll find countless examples of violations. They deserve credit for pointing these out so clearly, but still, deviating from standard collection behavior is risky! You must be careful what you do with such a collection; bugs are always just waiting to happen.

Our collections are fully generified and never violate their contracts (with isolated exceptions, where JDK implementations have set a strong precedent for acceptable violations). This means you can pass one of our collections to any method that expects a Collection and feel pretty confident that things will work exactly as they should.

java - Apache Commons vs. Guava (formerly "Google Collections") - Stac...

java collections apache-commons guava
Rectangle 27 12

Folks, wake up! Since Java 7 there are helper methods for equals and hashCode in the standard library. Their usage is fully equivalent to usage of Guava methods.

a) at the time this question was asked, Java 7 wasn't there yet b) technically, they're not quite equivalent. jdk has the Objects.equals method versus Guava's Objects.equal methods. I can use static imports with Guava's version only. That's just cosmetics, I know, but it makes the non-Guava noticeably more cluttered.

This isn't a good method for overriding an objects equals method due to the fact that Objects.equals will call the instance's .equals method. If you call Objects.equals within the instance's .equals method it'll lead to a stack overflow.

Can you give an example, when it falls into a loop?

OP is asking for overriding the equals() method within an Object. As per the documentation of the static method Objects.equals(): "Returns true if the arguments are equal to each other and false otherwise. Consequently, if both arguments are null, true is returned and if exactly one argument is null, false is returned. Otherwise, equality is determined by using the equals method of the first argument." Therefore, if you used Objects.equals() within the overridden instance equals() it'd call it's own equals method, then Objects.equals() then itself again, giving a stack overflow.

@dardo We are speaking about implementing structural equality, so it means two objects are equal to each other if their fields do. See the Guava example above, how equals is implemented.

java - Apache Commons equals/hashCode builder - Stack Overflow

java hibernate equals apache-commons hashcode
Rectangle 27 12

Folks, wake up! Since Java 7 there are helper methods for equals and hashCode in the standard library. Their usage is fully equivalent to usage of Guava methods.

a) at the time this question was asked, Java 7 wasn't there yet b) technically, they're not quite equivalent. jdk has the Objects.equals method versus Guava's Objects.equal methods. I can use static imports with Guava's version only. That's just cosmetics, I know, but it makes the non-Guava noticeably more cluttered.

This isn't a good method for overriding an objects equals method due to the fact that Objects.equals will call the instance's .equals method. If you call Objects.equals within the instance's .equals method it'll lead to a stack overflow.

Can you give an example, when it falls into a loop?

OP is asking for overriding the equals() method within an Object. As per the documentation of the static method Objects.equals(): "Returns true if the arguments are equal to each other and false otherwise. Consequently, if both arguments are null, true is returned and if exactly one argument is null, false is returned. Otherwise, equality is determined by using the equals method of the first argument." Therefore, if you used Objects.equals() within the overridden instance equals() it'd call it's own equals method, then Objects.equals() then itself again, giving a stack overflow.

@dardo We are speaking about implementing structural equality, so it means two objects are equal to each other if their fields do. See the Guava example above, how equals is implemented.

java - Apache Commons equals/hashCode builder - Stack Overflow

java hibernate equals apache-commons hashcode
Rectangle 27 22

By default, DBCP does not allow access to the "real" underlying database connection instance, so you cannot get to the Oracle class.

accessToUnderlyingConnectionAllowed = true

Default is false, it is a potential dangerous operation and misbehaving programs can do harmful things. (closing the underlying or continue using it when the guarded connection is already closed) Be careful and only use when you need direct access to driver specific extensions

NOTE: Do not close the underlying connection, only the original one.

I have the following parameters used in the resource details, still its not working. initialSize="5" maxActive="5" minidle= "5" maxIdle="5" maxWait="20000" removeAbandoned="true" removeAbandonedTimeout="60" maxIdleTime="3000" accessToUnderlyingConnectionAllowed="true"

This helped me a lot, thank you!

@Prodigy Have u got the solution ? i am facing same issue.

Just to note. This solution only works in combination with the answer below: stackoverflow.com/a/14327357/912829

java - Apache Commons DBCP connection object problem, Thread: ClassCas...

java jdbc apache-commons-dbcp
Rectangle 27 22

By default, DBCP does not allow access to the "real" underlying database connection instance, so you cannot get to the Oracle class.

accessToUnderlyingConnectionAllowed = true

Default is false, it is a potential dangerous operation and misbehaving programs can do harmful things. (closing the underlying or continue using it when the guarded connection is already closed) Be careful and only use when you need direct access to driver specific extensions

NOTE: Do not close the underlying connection, only the original one.

I have the following parameters used in the resource details, still its not working. initialSize="5" maxActive="5" minidle= "5" maxIdle="5" maxWait="20000" removeAbandoned="true" removeAbandonedTimeout="60" maxIdleTime="3000" accessToUnderlyingConnectionAllowed="true"

This helped me a lot, thank you!

@Prodigy Have u got the solution ? i am facing same issue.

Just to note. This solution only works in combination with the answer below: stackoverflow.com/a/14327357/912829

java - Apache Commons DBCP connection object problem, Thread: ClassCas...

java jdbc apache-commons-dbcp
Rectangle 27 8

If you do not want to depend on a 3rd party library (maybe you are running an a device with limited resources) and you even do not want to type your own methods, you can also let the IDE do the job, e.g. in eclipse use

Source -> Generate hashCode() and equals()...

You will get 'native' code which you can configure as you like and which you have to support on changes.

import java.util.Arrays;
import java.util.List;

public class FooBar {

    public String string;
    public List<String> stringList;
    public String[] stringArray;

    /* (non-Javadoc)
     * @see java.lang.Object#hashCode()
     */
    @Override
    public int hashCode() {
        final int prime = 31;
        int result = 1;
        result = prime * result + ((string == null) ? 0 : string.hashCode());
        result = prime * result + Arrays.hashCode(stringArray);
        result = prime * result
                + ((stringList == null) ? 0 : stringList.hashCode());
        return result;
    }
    /* (non-Javadoc)
     * @see java.lang.Object#equals(java.lang.Object)
     */
    @Override
    public boolean equals(Object obj) {
        if (this == obj)
            return true;
        if (obj == null)
            return false;
        if (getClass() != obj.getClass())
            return false;
        FooBar other = (FooBar) obj;
        if (string == null) {
            if (other.string != null)
                return false;
        } else if (!string.equals(other.string))
            return false;
        if (!Arrays.equals(stringArray, other.stringArray))
            return false;
        if (stringList == null) {
            if (other.stringList != null)
                return false;
        } else if (!stringList.equals(other.stringList))
            return false;
        return true;
    }

}

True, but the code generated by Eclipse is unreadable and unmaintainable.

Please, never ever think about something as terrible as the eclipse-generated equals. If you don't want to depend on 3rd party library, then write the one-line method like Objects.equal yourself. Even when used only once or twice, it makes the code way better!

equals
hashCode

@maaartinus Guava is a 3rd party library. I pointed out that my solution can be used if you want to AVOID using 3rd party libraries.

@FrVaBe: And I wrote "If you don't want to depend on 3rd party library, then write the one-line method like Objects.equal yourself." And then I wrote the one-line method which you may use to AVOID using Guava and still cut the length of equals to about one half.

java - Apache Commons equals/hashCode builder - Stack Overflow

java hibernate equals apache-commons hashcode
Rectangle 27 8

If you do not want to depend on a 3rd party library (maybe you are running an a device with limited resources) and you even do not want to type your own methods, you can also let the IDE do the job, e.g. in eclipse use

Source -> Generate hashCode() and equals()...

You will get 'native' code which you can configure as you like and which you have to support on changes.

import java.util.Arrays;
import java.util.List;

public class FooBar {

    public String string;
    public List<String> stringList;
    public String[] stringArray;

    /* (non-Javadoc)
     * @see java.lang.Object#hashCode()
     */
    @Override
    public int hashCode() {
        final int prime = 31;
        int result = 1;
        result = prime * result + ((string == null) ? 0 : string.hashCode());
        result = prime * result + Arrays.hashCode(stringArray);
        result = prime * result
                + ((stringList == null) ? 0 : stringList.hashCode());
        return result;
    }
    /* (non-Javadoc)
     * @see java.lang.Object#equals(java.lang.Object)
     */
    @Override
    public boolean equals(Object obj) {
        if (this == obj)
            return true;
        if (obj == null)
            return false;
        if (getClass() != obj.getClass())
            return false;
        FooBar other = (FooBar) obj;
        if (string == null) {
            if (other.string != null)
                return false;
        } else if (!string.equals(other.string))
            return false;
        if (!Arrays.equals(stringArray, other.stringArray))
            return false;
        if (stringList == null) {
            if (other.stringList != null)
                return false;
        } else if (!stringList.equals(other.stringList))
            return false;
        return true;
    }

}

True, but the code generated by Eclipse is unreadable and unmaintainable.

Please, never ever think about something as terrible as the eclipse-generated equals. If you don't want to depend on 3rd party library, then write the one-line method like Objects.equal yourself. Even when used only once or twice, it makes the code way better!

equals
hashCode

@maaartinus Guava is a 3rd party library. I pointed out that my solution can be used if you want to AVOID using 3rd party libraries.

@FrVaBe: And I wrote "If you don't want to depend on 3rd party library, then write the one-line method like Objects.equal yourself." And then I wrote the one-line method which you may use to AVOID using Guava and still cut the length of equals to about one half.

java - Apache Commons equals/hashCode builder - Stack Overflow

java hibernate equals apache-commons hashcode
Rectangle 27 31

You need the Apache Commons Logging library on your classpath.

pdfbox - Exception in thread "main" java.lang.NoClassDefFoundError: or...

java pdfbox
Rectangle 27 16

If you are using a Java 6 compliant JDBC Connection, you can use code like the following:

OracleConnection oracleConnection = null;
try {
    if (connection.isWrapperFor(OracleConnection.class)) {
        oracleConnection = connection.unwrap(OracleConnection.class);
    }
} catch (SQLException ex) {
    // do something
}
return oracleConnection;

From this point on, use the oracleConnection instead of the original connection.

It is worth nothing here that you want to import the OracleConnection interface in oracle.jdbc rather than the concrete implementation with the same name.

java - Apache Commons DBCP connection object problem, Thread: ClassCas...

java jdbc apache-commons-dbcp
Rectangle 27 16

If you are using a Java 6 compliant JDBC Connection, you can use code like the following:

OracleConnection oracleConnection = null;
try {
    if (connection.isWrapperFor(OracleConnection.class)) {
        oracleConnection = connection.unwrap(OracleConnection.class);
    }
} catch (SQLException ex) {
    // do something
}
return oracleConnection;

From this point on, use the oracleConnection instead of the original connection.

It is worth nothing here that you want to import the OracleConnection interface in oracle.jdbc rather than the concrete implementation with the same name.

java - Apache Commons DBCP connection object problem, Thread: ClassCas...

java jdbc apache-commons-dbcp
Rectangle 27 6

The EqualsBuilder and HashCodeBuilder make it easier to compare fields that could be null. With manually writen code this creates a lot of boilerplate.

The EqualsBuilder will on the other hand create an instance per equals method call. If your equals methods are call often this will create a lot of instances.

For almost all domain objects loaded with hibernate the runtime overhead (even without escape analysis) of the Builder can be ignored

As skaffman mentioned the reflection version cannot be used in production code. Reflection will be to slow and the "implementation" will not be correct for all but the simplest classes. Taking all members into account is also dangerous as newly introduced members change the equals method behaviour. The reflection version can be useful in test code.

I disagree that the reflection implementation "will not be correct for all but the simplest classes." With the builders you can explicitly exclude fields if you like, so the implementation really depends on your business key definition. Unfortunately, I can't disagree with the performance aspect of the reflection based implementation.

@digitaljoel Yes, you can exclude fields, but these definitions are not refactoring save. So I did not mention them on purpose.

java - Apache Commons equals/hashCode builder - Stack Overflow

java hibernate equals apache-commons hashcode
Rectangle 27 6

The EqualsBuilder and HashCodeBuilder make it easier to compare fields that could be null. With manually writen code this creates a lot of boilerplate.

The EqualsBuilder will on the other hand create an instance per equals method call. If your equals methods are call often this will create a lot of instances.

For almost all domain objects loaded with hibernate the runtime overhead (even without escape analysis) of the Builder can be ignored

As skaffman mentioned the reflection version cannot be used in production code. Reflection will be to slow and the "implementation" will not be correct for all but the simplest classes. Taking all members into account is also dangerous as newly introduced members change the equals method behaviour. The reflection version can be useful in test code.

I disagree that the reflection implementation "will not be correct for all but the simplest classes." With the builders you can explicitly exclude fields if you like, so the implementation really depends on your business key definition. Unfortunately, I can't disagree with the performance aspect of the reflection based implementation.

@digitaljoel Yes, you can exclude fields, but these definitions are not refactoring save. So I did not mention them on purpose.

java - Apache Commons equals/hashCode builder - Stack Overflow

java hibernate equals apache-commons hashcode
Rectangle 27 4

If you don't to write your own, there is also the possibility to use google guava (formerly google collections)

java - Apache Commons equals/hashCode builder - Stack Overflow

java hibernate equals apache-commons hashcode
Rectangle 27 4

If you don't to write your own, there is also the possibility to use google guava (formerly google collections)

java - Apache Commons equals/hashCode builder - Stack Overflow

java hibernate equals apache-commons hashcode
Rectangle 27 5

Seen this post i can get the OracleConnection with this code:

DataSource ds1 = // get the org.apache.commons.dbcp.PoolingDataSource
org.apache.tomcat.dbcp.dbcp.DelegatingConnection del = new org.apache.tomcat.dbcp.dbcp.DelegatingConnection(cds1.getConnection());
OracleConnection con = (OracleConnection) del.getInnermostDelegate();

remember the commons-dbcp-1.4.jar neet to be in the class path

java - Apache Commons DBCP connection object problem, Thread: ClassCas...

java jdbc apache-commons-dbcp
Rectangle 27 5

Seen this post i can get the OracleConnection with this code:

DataSource ds1 = // get the org.apache.commons.dbcp.PoolingDataSource
org.apache.tomcat.dbcp.dbcp.DelegatingConnection del = new org.apache.tomcat.dbcp.dbcp.DelegatingConnection(cds1.getConnection());
OracleConnection con = (OracleConnection) del.getInnermostDelegate();

remember the commons-dbcp-1.4.jar neet to be in the class path

java - Apache Commons DBCP connection object problem, Thread: ClassCas...

java jdbc apache-commons-dbcp