<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Transient Technology &#187; equals</title>
	<atom:link href="http://martinaharris.com/tag/equals/feed/" rel="self" type="application/rss+xml" />
	<link>http://martinaharris.com</link>
	<description>Next time you look it might be gone</description>
	<lastBuildDate>Tue, 24 Jan 2012 18:14:10 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<item>
		<title>Google Objects.equal, useful but be careful.</title>
		<link>http://martinaharris.com/2010/02/google-objects-equal-useful-but-be-careful/</link>
		<comments>http://martinaharris.com/2010/02/google-objects-equal-useful-but-be-careful/#comments</comments>
		<pubDate>Tue, 16 Feb 2010 20:20:14 +0000</pubDate>
		<dc:creator>Martin Harris</dc:creator>
				<category><![CDATA[java]]></category>
		<category><![CDATA[software quality]]></category>
		<category><![CDATA[testing]]></category>
		<category><![CDATA[compareto]]></category>
		<category><![CDATA[equals]]></category>
		<category><![CDATA[google]]></category>

		<guid isPermaLink="false">http://martinaharris.com/?p=818</guid>
		<description><![CDATA[Google have a nice equals method to make boiler plate equals easier to read. Particularly good if you have many attributes in the method. http://publicobject.com/2007/09/coding-in-small-with-google-collections_8175.html Be careful to check that your objects are consistent with equals though.  I have mentioned &#8230; <a href="http://martinaharris.com/2010/02/google-objects-equal-useful-but-be-careful/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>Google have a nice equals method to make boiler plate equals easier to read.  Particularly good if you have many attributes in the method.  <a title="Google Object.equals method." href="http://publicobject.com/2007/09/coding-in-small-with-google-collections_8175.html" target="_blank">http://publicobject.com/2007/09/coding-in-small-with-google-collections_8175.html</a></p>
<p>Be careful to check that your objects are consistent with equals though.  I have mentioned this <a title="Equals Generation" href="/2009/10/ide-generation-of-equals-methods-has-its-moments/" target="_blank">before</a>.<br />
<span id="more-818"></span><br />
In the following method I am using the Objects.equal with a BigDecimal class.  It does not work because BigDecimal equals treats 0 and 0.0 as not equal, which is probably not what you need.</p>
<pre class="brush: java; light: true">
public boolean equals(Object obj) {
    if (obj == null) {
      return false;
    }
    if (getClass() != obj.getClass()) {
      return false;
    }

    final TestEquals other = (TestEquals) obj;

    return Objects.equal(this.bigDecimal, other);
}</pre>
<p>The common solution is to use the compareTo method instead like so.</p>
<pre class="brush: java; light: true">  final TestEquals other = (TestEquals) obj;
  if (this.bigDecimal != other.bigDecimal &amp;&amp;
      (this.bigDecimal == null
      || this.bigDecimal.compareTo(other.bigDecimal) != 0)) {
    return false;
  }
  return true;</pre>
<p>I will be using this technique, especially where the object has many attributes but I will be <a title="Testing Equals" href="/2009/10/testing-java-equals-and-hashcode-methods-essential/" target="_blank">testing the equals method</a>.</p>
<div class="lightsocial_container"><a class="lightsocial_a" href="http://digg.com/submit?url=http%3A%2F%2Fmartinaharris.com%2F2010%2F02%2Fgoogle-objects-equal-useful-but-be-careful%2F&amp;title=Google+Objects.equal%2C+useful+but+be+careful." target="_blank"><img class="lightsocial_img" src="http://martinaharris.com/wp-content/plugins/light-social/digg.png" alt="Digg This" title="Digg This" /></a>&nbsp;&nbsp;<a class="lightsocial_a" href="http://www.reddit.com/submit?url=http%3A%2F%2Fmartinaharris.com%2F2010%2F02%2Fgoogle-objects-equal-useful-but-be-careful%2F&amp;title=Google+Objects.equal%2C+useful+but+be+careful." target="_blank"><img class="lightsocial_img" src="http://martinaharris.com/wp-content/plugins/light-social/reddit.png" alt="Reddit This" title="Reddit This" /></a>&nbsp;&nbsp;<a class="lightsocial_a" href="http://www.stumbleupon.com/submit?url=http%3A%2F%2Fmartinaharris.com%2F2010%2F02%2Fgoogle-objects-equal-useful-but-be-careful%2F&amp;title=Google+Objects.equal%2C+useful+but+be+careful." target="_blank"><img class="lightsocial_img" src="http://martinaharris.com/wp-content/plugins/light-social/stumbleupon.png" alt="Stumble Now!" title="Stumble Now!" /></a>&nbsp;&nbsp;<a class="lightsocial_a" href="http://buzz.yahoo.com/buzz?targetUrl=http%3A%2F%2Fmartinaharris.com%2F2010%2F02%2Fgoogle-objects-equal-useful-but-be-careful%2F&amp;headline=Google+Objects.equal%2C+useful+but+be+careful." target="_blank"><img class="lightsocial_img" src="http://martinaharris.com/wp-content/plugins/light-social/yahoo_buzz.png" alt="Buzz This" title="Buzz This" /></a>&nbsp;&nbsp;<a class="lightsocial_a" href="http://www.dzone.com/links/add.html?title=Google+Objects.equal%2C+useful+but+be+careful.&amp;url=http%3A%2F%2Fmartinaharris.com%2F2010%2F02%2Fgoogle-objects-equal-useful-but-be-careful%2F" target="_blank"><img class="lightsocial_img" src="http://martinaharris.com/wp-content/plugins/light-social/dzone.png" alt="Vote on DZone" title="Vote on DZone" /></a>&nbsp;&nbsp;<a class="lightsocial_a" href="http://www.facebook.com/sharer.php?t=Google+Objects.equal%2C+useful+but+be+careful.&amp;u=http%3A%2F%2Fmartinaharris.com%2F2010%2F02%2Fgoogle-objects-equal-useful-but-be-careful%2F" target="_blank"><img class="lightsocial_img" src="http://martinaharris.com/wp-content/plugins/light-social/facebook.png" alt="Share on Facebook" title="Share on Facebook" /></a>&nbsp;&nbsp;<a class="lightsocial_a" href="http://delicious.com/save?title=Google+Objects.equal%2C+useful+but+be+careful.&amp;url=http%3A%2F%2Fmartinaharris.com%2F2010%2F02%2Fgoogle-objects-equal-useful-but-be-careful%2F" target="_blank"><img class="lightsocial_img" src="http://martinaharris.com/wp-content/plugins/light-social/delicious.png" alt="Bookmark this on Delicious" title="Bookmark this on Delicious" /></a>&nbsp;&nbsp;<a class="lightsocial_a" href="http://www.dotnetkicks.com/kick/?title=Google+Objects.equal%2C+useful+but+be+careful.&amp;url=http%3A%2F%2Fmartinaharris.com%2F2010%2F02%2Fgoogle-objects-equal-useful-but-be-careful%2F" target="_blank"><img class="lightsocial_img" src="http://martinaharris.com/wp-content/plugins/light-social/dotnetkicks.png" alt="Kick It on DotNetKicks.com" title="Kick It on DotNetKicks.com" /></a>&nbsp;&nbsp;<a class="lightsocial_a" href="http://dotnetshoutout.com/Submit?title=Google+Objects.equal%2C+useful+but+be+careful.&amp;url=http%3A%2F%2Fmartinaharris.com%2F2010%2F02%2Fgoogle-objects-equal-useful-but-be-careful%2F" target="_blank"><img class="lightsocial_img" src="http://martinaharris.com/wp-content/plugins/light-social/dotnetshoutout.png" alt="Shout it" title="Shout it" /></a>&nbsp;&nbsp;<a class="lightsocial_a" href="http://www.linkedin.com/shareArticle?mini=true&amp;url=http%3A%2F%2Fmartinaharris.com%2F2010%2F02%2Fgoogle-objects-equal-useful-but-be-careful%2F&amp;title=Google+Objects.equal%2C+useful+but+be+careful.&amp;summary=&amp;source=" target="_blank"><img class="lightsocial_img" src="http://martinaharris.com/wp-content/plugins/light-social/linkedin.png" alt="Share on LinkedIn" title="Share on LinkedIn" /></a>&nbsp;&nbsp;<a class="lightsocial_a" href="http://www.technorati.com/faves?add=http%3A%2F%2Fmartinaharris.com%2F2010%2F02%2Fgoogle-objects-equal-useful-but-be-careful%2F" target="_blank"><img class="lightsocial_img" src="http://martinaharris.com/wp-content/plugins/light-social/technorati.png" alt="Bookmark this on Technorati" title="Bookmark this on Technorati" /></a>&nbsp;&nbsp;<a class="lightsocial_a" href="http://twitter.com/home?status=Reading+http%3A%2F%2Fmartinaharris.com%2F2010%2F02%2Fgoogle-objects-equal-useful-but-be-careful%2F" target="_blank"><img class="lightsocial_img" src="http://martinaharris.com/wp-content/plugins/light-social/twitter.png" alt="Post on Twitter" title="Post on Twitter" /></a>&nbsp;&nbsp;<a class="lightsocial_a" href="http://www.google.com/buzz/post?url=http%3A%2F%2Fmartinaharris.com%2F2010%2F02%2Fgoogle-objects-equal-useful-but-be-careful%2F" target="_blank"><img class="lightsocial_img" src="http://martinaharris.com/wp-content/plugins/light-social/google_buzz.png" alt="Google Buzz (aka. Google Reader)" title="Google Buzz (aka. Google Reader)" /></a>&nbsp;&nbsp;</div><div class="dzone_button" style="float: right; margin-left: 5px;">
<script type="text/javascript">
var dzone_url = 'http://martinaharris.com/2010/02/google-objects-equal-useful-but-be-careful/';
var dzone_title = 'Google Objects.equal, useful but be careful.';
var dzone_blurb = '';
var dzone_style = '2';
</script>
<script language="javascript" src="http://widgets.dzone.com/links/widgets/zoneit.js"></script>
</div>]]></content:encoded>
			<wfw:commentRss>http://martinaharris.com/2010/02/google-objects-equal-useful-but-be-careful/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Neat multiset in google collections API</title>
		<link>http://martinaharris.com/2009/10/neat-multiset-in-google-collections-api/</link>
		<comments>http://martinaharris.com/2009/10/neat-multiset-in-google-collections-api/#comments</comments>
		<pubDate>Sat, 31 Oct 2009 00:14:27 +0000</pubDate>
		<dc:creator>Martin Harris</dc:creator>
				<category><![CDATA[java]]></category>
		<category><![CDATA[software quality]]></category>
		<category><![CDATA[testing]]></category>
		<category><![CDATA[collections]]></category>
		<category><![CDATA[equals]]></category>
		<category><![CDATA[google]]></category>
		<category><![CDATA[quality]]></category>
		<category><![CDATA[thread]]></category>

		<guid isPermaLink="false">http://martinaharris.com/?p=113</guid>
		<description><![CDATA[This good thing was so small that I almost did not bother to blog it But the devil is in the detail so here it is anyway. I have this multi threaded application. One of the problems with integration testing &#8230; <a href="http://martinaharris.com/2009/10/neat-multiset-in-google-collections-api/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<h3>This good thing was so small that I almost did not bother to blog it</h3>
<p><cite>But the devil is in the detail</cite> so here it is anyway.</p>
<p>I have this multi threaded application.  One of the problems with integration testing it is, you can&#8217;t guarantee the order that messages will be written to a stream.  So during the test I have to go to some trouble to split and order the lines written out.  If I don&#8217;t do this the test fails sometimes. It depends on which thread writes first. The output though is correct, order is not important.  Not exactly rocket science.</p>
<p>Here is the method I was using to massage the string.</p>
<pre class="brush: java; gutter: false; wrap-lines: false">
 public List&lt;String&gt; getSortedLines(String expectedString) {

        String[] splitExpectedResultLines = expectedString.toString().split("\n");
        List&lt;String&gt; resultLines = new ArrayList&lt;String&gt;();
        for (String messageLine : resultLines) {
            resultLines.add(messageLine);
        }

        Collections.sort(resultLines);
        return resultLines;
    }
</pre>
<p>There is nothing particularly wrong with the method.  It takes a string, splits it into lines, loads a List, sorts and returns it.  Thus when its used in an assertion later the expected and actual lists are the same.</p>
<p>With google collections its just three lines!  The HashMultiset is designed to be used in equals methods.  Its equal even if the order of the elements in collections being compared is different.  From the API documentation: <cite>An extension of Collection that may contain duplicate values like a List, yet has order-independent equality like a Set. One typical use for a multiset is to represent a histogram.</cite> </p>
<p>Its possible to use the HashMultiSet.create static factory method, passing in an Iterable.  i.e a Collection.  So from the original code, both the loop and the Collections.sort are no longer required.</p>
<pre class="brush: java; gutter: false; wrap-lines: false; highlight: 6">
   public HashMultiset&lt;String&gt; getOrderAgnosticCollection(String expectedString) {

        String[] splitExpectedResultLines = expectedString.toString().split("\n");
        Iterable&lt;String&gt; resultLines = Arrays.asList(splitExpectedResultLines);
        HashMultiset&lt;String&gt; orderAgnosticResultLines =
                                              HashMultiset.create(resultLines);

        return orderAgnosticResultLines;
    }
</pre>
<p>If there was something that performed the split, but returned an Iterable the method would be perfect!  <img src='http://martinaharris.com/wp-includes/images/smilies/icon_wink.gif' alt=';-)' class='wp-smiley' /> </p>
<div class="lightsocial_container"><a class="lightsocial_a" href="http://digg.com/submit?url=http%3A%2F%2Fmartinaharris.com%2F2009%2F10%2Fneat-multiset-in-google-collections-api%2F&amp;title=Neat+multiset+in+google+collections+API" target="_blank"><img class="lightsocial_img" src="http://martinaharris.com/wp-content/plugins/light-social/digg.png" alt="Digg This" title="Digg This" /></a>&nbsp;&nbsp;<a class="lightsocial_a" href="http://www.reddit.com/submit?url=http%3A%2F%2Fmartinaharris.com%2F2009%2F10%2Fneat-multiset-in-google-collections-api%2F&amp;title=Neat+multiset+in+google+collections+API" target="_blank"><img class="lightsocial_img" src="http://martinaharris.com/wp-content/plugins/light-social/reddit.png" alt="Reddit This" title="Reddit This" /></a>&nbsp;&nbsp;<a class="lightsocial_a" href="http://www.stumbleupon.com/submit?url=http%3A%2F%2Fmartinaharris.com%2F2009%2F10%2Fneat-multiset-in-google-collections-api%2F&amp;title=Neat+multiset+in+google+collections+API" target="_blank"><img class="lightsocial_img" src="http://martinaharris.com/wp-content/plugins/light-social/stumbleupon.png" alt="Stumble Now!" title="Stumble Now!" /></a>&nbsp;&nbsp;<a class="lightsocial_a" href="http://buzz.yahoo.com/buzz?targetUrl=http%3A%2F%2Fmartinaharris.com%2F2009%2F10%2Fneat-multiset-in-google-collections-api%2F&amp;headline=Neat+multiset+in+google+collections+API" target="_blank"><img class="lightsocial_img" src="http://martinaharris.com/wp-content/plugins/light-social/yahoo_buzz.png" alt="Buzz This" title="Buzz This" /></a>&nbsp;&nbsp;<a class="lightsocial_a" href="http://www.dzone.com/links/add.html?title=Neat+multiset+in+google+collections+API&amp;url=http%3A%2F%2Fmartinaharris.com%2F2009%2F10%2Fneat-multiset-in-google-collections-api%2F" target="_blank"><img class="lightsocial_img" src="http://martinaharris.com/wp-content/plugins/light-social/dzone.png" alt="Vote on DZone" title="Vote on DZone" /></a>&nbsp;&nbsp;<a class="lightsocial_a" href="http://www.facebook.com/sharer.php?t=Neat+multiset+in+google+collections+API&amp;u=http%3A%2F%2Fmartinaharris.com%2F2009%2F10%2Fneat-multiset-in-google-collections-api%2F" target="_blank"><img class="lightsocial_img" src="http://martinaharris.com/wp-content/plugins/light-social/facebook.png" alt="Share on Facebook" title="Share on Facebook" /></a>&nbsp;&nbsp;<a class="lightsocial_a" href="http://delicious.com/save?title=Neat+multiset+in+google+collections+API&amp;url=http%3A%2F%2Fmartinaharris.com%2F2009%2F10%2Fneat-multiset-in-google-collections-api%2F" target="_blank"><img class="lightsocial_img" src="http://martinaharris.com/wp-content/plugins/light-social/delicious.png" alt="Bookmark this on Delicious" title="Bookmark this on Delicious" /></a>&nbsp;&nbsp;<a class="lightsocial_a" href="http://www.dotnetkicks.com/kick/?title=Neat+multiset+in+google+collections+API&amp;url=http%3A%2F%2Fmartinaharris.com%2F2009%2F10%2Fneat-multiset-in-google-collections-api%2F" target="_blank"><img class="lightsocial_img" src="http://martinaharris.com/wp-content/plugins/light-social/dotnetkicks.png" alt="Kick It on DotNetKicks.com" title="Kick It on DotNetKicks.com" /></a>&nbsp;&nbsp;<a class="lightsocial_a" href="http://dotnetshoutout.com/Submit?title=Neat+multiset+in+google+collections+API&amp;url=http%3A%2F%2Fmartinaharris.com%2F2009%2F10%2Fneat-multiset-in-google-collections-api%2F" target="_blank"><img class="lightsocial_img" src="http://martinaharris.com/wp-content/plugins/light-social/dotnetshoutout.png" alt="Shout it" title="Shout it" /></a>&nbsp;&nbsp;<a class="lightsocial_a" href="http://www.linkedin.com/shareArticle?mini=true&amp;url=http%3A%2F%2Fmartinaharris.com%2F2009%2F10%2Fneat-multiset-in-google-collections-api%2F&amp;title=Neat+multiset+in+google+collections+API&amp;summary=&amp;source=" target="_blank"><img class="lightsocial_img" src="http://martinaharris.com/wp-content/plugins/light-social/linkedin.png" alt="Share on LinkedIn" title="Share on LinkedIn" /></a>&nbsp;&nbsp;<a class="lightsocial_a" href="http://www.technorati.com/faves?add=http%3A%2F%2Fmartinaharris.com%2F2009%2F10%2Fneat-multiset-in-google-collections-api%2F" target="_blank"><img class="lightsocial_img" src="http://martinaharris.com/wp-content/plugins/light-social/technorati.png" alt="Bookmark this on Technorati" title="Bookmark this on Technorati" /></a>&nbsp;&nbsp;<a class="lightsocial_a" href="http://twitter.com/home?status=Reading+http%3A%2F%2Fmartinaharris.com%2F2009%2F10%2Fneat-multiset-in-google-collections-api%2F" target="_blank"><img class="lightsocial_img" src="http://martinaharris.com/wp-content/plugins/light-social/twitter.png" alt="Post on Twitter" title="Post on Twitter" /></a>&nbsp;&nbsp;<a class="lightsocial_a" href="http://www.google.com/buzz/post?url=http%3A%2F%2Fmartinaharris.com%2F2009%2F10%2Fneat-multiset-in-google-collections-api%2F" target="_blank"><img class="lightsocial_img" src="http://martinaharris.com/wp-content/plugins/light-social/google_buzz.png" alt="Google Buzz (aka. Google Reader)" title="Google Buzz (aka. Google Reader)" /></a>&nbsp;&nbsp;</div><div class="dzone_button" style="float: right; margin-left: 5px;">
<script type="text/javascript">
var dzone_url = 'http://martinaharris.com/2009/10/neat-multiset-in-google-collections-api/';
var dzone_title = 'Neat multiset in google collections API';
var dzone_blurb = '';
var dzone_style = '2';
</script>
<script language="javascript" src="http://widgets.dzone.com/links/widgets/zoneit.js"></script>
</div>]]></content:encoded>
			<wfw:commentRss>http://martinaharris.com/2009/10/neat-multiset-in-google-collections-api/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Testing java equals and hashcode methods</title>
		<link>http://martinaharris.com/2009/10/testing-java-equals-and-hashcode-methods-essential/</link>
		<comments>http://martinaharris.com/2009/10/testing-java-equals-and-hashcode-methods-essential/#comments</comments>
		<pubDate>Sat, 24 Oct 2009 21:44:35 +0000</pubDate>
		<dc:creator>Martin Harris</dc:creator>
				<category><![CDATA[java]]></category>
		<category><![CDATA[software quality]]></category>
		<category><![CDATA[testing]]></category>
		<category><![CDATA[equals]]></category>
		<category><![CDATA[hashcode]]></category>
		<category><![CDATA[junit]]></category>
		<category><![CDATA[quality]]></category>

		<guid isPermaLink="false">http://www.koitok.net/?p=27</guid>
		<description><![CDATA[Equals and hashcode bugs can be difficult to track down.  So why not test them?  This blog shows how easy it is to code some tests <a href="http://martinaharris.com/2009/10/testing-java-equals-and-hashcode-methods-essential/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<h3>Write a java test for the equals method!  What is the point in wasting time on that?</h3>
<p>All good java programmers know the equals and hashcode methods are vitally important.  I have seen some unpredictable behavior through bugs in these two methods.</p>
<p>If your about to click away to something more interesting fine, but first read my page with an <a href="http://www.koitok.net/2009/10/ide-generation-of-equals-methods-has-its-moments/">example equals bug</a>.  See if you can spot the problem before I show the solution.</p>
<h4>Writing a test for the equals method</h4>
<p>Writing a test for equals is so easy its tedious.  Which is perhaps why so much code gets written and not tested.  First from the javadoc what are the specifications for a good equals and hashcode implementations?</p>
<p><span id="more-27"></span></p>
<p><strong><cite>Suns javadoc for the equals method</cite></strong></p>
<ul>
<li>It is reflexive: for any non-null reference value x, x.equals(x) should return true.</li>
<li>It is symmetric: for any non-null reference values x and y, x.equals(y) should return true if and only if y.equals(x) returns true.</li>
<li>It is transitive: for any non-null reference values x, y, and z, if x.equals(y) returns true and y.equals(z) returns true, then x.equals(z) should return true.</li>
<li>It is consistent: for any non-null reference values x and y, multiple invocations of x.equals(y) consistently return true or consistently return false, provided no information used in equals comparisons on the objects is modified.</li>
<li>For any non-null reference value x, x.equals(null) should return false.</li>
</ul>
<p><strong><cite>Suns javadoc for the hashcode method</cite></strong></p>
<ul>
<li>Whenever it is invoked on the same object more than once during an execution of a Java application, the hashCode method must consistently return the same integer, provided no information used in equals comparisons on the object is modified. This integer need not remain consistent from one execution of an application to another execution of the same application.</li>
<li>If two objects are equal according to the equals(Object) method, then calling the hashCode method on each of the two objects must produce the same integer result.</li>
<li>It is not required that if two objects are unequal according to the equals(java.lang.Object) method, then calling the hashCode method on each of the two objects must produce distinct integer results. However, the programmer should be aware that producing distinct integer results for unequal objects may improve the performance of hashtables.</li>
<h4>Simple implementations for equals and hashcode</h4>
<p>These two implementations were built using the generator in netbeans.  Arguably some further optimisation could be done, especially if the class were made fully immutable.  They are fine for the purpose of this blog.</p>
<pre class="brush: java; gutter: false; wrap-lines: false">
public final class SimpleBean {
    private Integer goodInt = 0;

    public SimpleBean(final Integer goodInt) {
        this.goodInt = goodInt;
    }

    @Override
    public boolean equals(Object obj) {
        if (obj == null) {
            return false;
        }
        if (getClass() != obj.getClass()) {
            return false;
        }
        final SimpleBean other = (SimpleBean) obj;
        if (this.goodInt != other.goodInt
            &amp;&amp; (this.goodInt == null
                                || !this.goodInt.equals(other.goodInt))) {
            return false;
        }
        return true;
    }

    @Override
    public int hashCode() {
        int hash = 7;
        hash = 41 * hash + (this.goodInt != null ? this.goodInt.hashCode() : 0);
        return hash;
    }
}</pre>
<h4>Test class for SimpleBean just showing the equals and hashcode tests</h4>
<pre class="brush: java; gutter: false;wrap-lines: false">
import org.junit.Test;
import static org.junit.Assert.*;

public class TestSimpleBean {

    static final class Fixture {

        static SimpleBean x = new SimpleBean(new Integer(100));
        static SimpleBean y = new SimpleBean(new Integer(100));
        static SimpleBean z = new SimpleBean(new Integer(100));
        static SimpleBean notx = new SimpleBean(new Integer(1));
    }

    @Test
    /**
     * A class is equal to itself.
     */
    public void testEqual_ToSelf() {

        assertTrue("Class equal to itself.", Fixture.x.equals(Fixture.x));
    }

    /**
     * x.equals(WrongType) must return false;
     *
     */
    @Test
    public void testPassIncompatibleType_isFalse() {
        assertFalse("Passing incompatible object to equals should return false", Fixture.x.equals("string"));
    }

    /**
     * x.equals(null) must return false;
     *
     */
    @Test
    public void testNullReference_isFalse() {
        assertFalse("Passing null to equals should return false", Fixture.x.equals(null));
    }

    /**
     * 1. x, x.equals(x) must return true.
     * 2. x and y, x.equals(y) must return true if and only if y.equals(x) returns true.
     */
    @Test
    public void testEquals_isReflexive_isSymmetric() {

        assertTrue("Reflexive test fail x,y", Fixture.x.equals(Fixture.y));
        assertTrue("Symmetric test fail y", Fixture.y.equals(Fixture.x));

    }

    /**
     * 1. x.equals(y) returns true
     * 2. y.equals(z) returns true
     * 3. x.equals(z) must return true
     */
    @Test
    public void testEquals_isTransitive() {

        assertTrue("Transitive test fails x,y", Fixture.x.equals(Fixture.y));
        assertTrue("Transitive test fails y,z", Fixture.y.equals(Fixture.z));
        assertTrue("Transitive test fails x,z", Fixture.x.equals(Fixture.z));
    }

    /**
     * Repeated calls to equals consistently return true or false.
     */
    @Test
    public void testEquals_isConsistent() {

        assertTrue("Consistent test fail x,y", Fixture.x.equals(Fixture.y));
        assertTrue("Consistent test fail x,y", Fixture.x.equals(Fixture.y));
        assertTrue("Consistent test fail x,y", Fixture.x.equals(Fixture.y));
        assertFalse(Fixture.notx.equals(Fixture.x));
        assertFalse(Fixture.notx.equals(Fixture.x));
        assertFalse(Fixture.notx.equals(Fixture.x));

    }

    /**
     * Repeated calls to hashcode should consistently return the same integer.
     */
    @Test
    public void testHashcode_isConsistent() {

        int initial_hashcode = Fixture.x.hashCode();

        assertEquals("Consistent hashcode test fails", initial_hashcode, Fixture.x.hashCode());
        assertEquals("Consistent hashcode test fails", initial_hashcode, Fixture.x.hashCode());
    }

    /**
     * Objects that are equal using the equals method should return the same integer.
     */
    @Test
    public void testHashcode_twoEqualsObjects_produceSameNumber() {

        int xhashcode = Fixture.x.hashCode();
        int yhashcode = Fixture.y.hashCode();

        assertEquals("Equal object, return equal hashcode test fails", xhashcode, yhashcode);
    }

    /**
     * A more optimal implementation of hashcode ensures
     * that if the objects are unequal different integers are produced.
     *
     */
    @Test
    public void testHashcode_twoUnEqualObjects_produceDifferentNumber() {

        int xhashcode = Fixture.x.hashCode();
        int yhashcode = Fixture.notx.hashCode();

        assertTrue("Equal object, return unequal hashcode test fails", !(xhashcode == yhashcode));
    }
}</pre>
<h3>Conclusions</h3>
<p>To me the benefit is clear.  Its very easy to break these two methods.  Converting one of the attribute types can easily break equals and possibly hashcode.  Its essential to have a test in place to prevent the bug going unnoticed.</ul>
<h3>Note on nulls</h3>
<p>In some cases extra tests may be required for null checking on both sides.  For instance in the case where an object relies upon an inner class to provide it a key, and its possible for this key to be null.:</p>
<pre class="brush: java; gutter: false;wrap-lines: false">
   /**
     * x.key = null, y.key = null, must return false.
     */
    @Test
    public void testKeysNull_NotEqual() {

        Thing noKeyAvailableA = new Thing();
        Thing noKeyAvailableB = new Thing ();
        assertFalse(noKeyAvailableA.equals(noKeyAvailableB));
    }

    /**
     * x.key= null, y.key != null, must return false.
     */
    @Test
    public void testKeyNearsideNullFarsideNotNull_NotEqual() {
        Fixture fixture = new Fixture();
        Thing noKeyAvailable = new Thing ();
        assertFalse(noKeyAvailable.equals(fixture.x));
    }

    /**
     * y.key = null, x.key != null, must return false.
     */
    @Test
    public void testKeyFarsideNotNullFarsideNull_NotEqual() {
        Fixture fixture = new Fixture();
        Thing noKeyAvailable = new Thing ();
        assertFalse(fixture.x.equals(noKeyAvailable));
    }
</pre>
<div class="lightsocial_container"><a class="lightsocial_a" href="http://digg.com/submit?url=http%3A%2F%2Fmartinaharris.com%2F2009%2F10%2Ftesting-java-equals-and-hashcode-methods-essential%2F&amp;title=Testing+java+equals+and+hashcode+methods" target="_blank"><img class="lightsocial_img" src="http://martinaharris.com/wp-content/plugins/light-social/digg.png" alt="Digg This" title="Digg This" /></a>&nbsp;&nbsp;<a class="lightsocial_a" href="http://www.reddit.com/submit?url=http%3A%2F%2Fmartinaharris.com%2F2009%2F10%2Ftesting-java-equals-and-hashcode-methods-essential%2F&amp;title=Testing+java+equals+and+hashcode+methods" target="_blank"><img class="lightsocial_img" src="http://martinaharris.com/wp-content/plugins/light-social/reddit.png" alt="Reddit This" title="Reddit This" /></a>&nbsp;&nbsp;<a class="lightsocial_a" href="http://www.stumbleupon.com/submit?url=http%3A%2F%2Fmartinaharris.com%2F2009%2F10%2Ftesting-java-equals-and-hashcode-methods-essential%2F&amp;title=Testing+java+equals+and+hashcode+methods" target="_blank"><img class="lightsocial_img" src="http://martinaharris.com/wp-content/plugins/light-social/stumbleupon.png" alt="Stumble Now!" title="Stumble Now!" /></a>&nbsp;&nbsp;<a class="lightsocial_a" href="http://buzz.yahoo.com/buzz?targetUrl=http%3A%2F%2Fmartinaharris.com%2F2009%2F10%2Ftesting-java-equals-and-hashcode-methods-essential%2F&amp;headline=Testing+java+equals+and+hashcode+methods" target="_blank"><img class="lightsocial_img" src="http://martinaharris.com/wp-content/plugins/light-social/yahoo_buzz.png" alt="Buzz This" title="Buzz This" /></a>&nbsp;&nbsp;<a class="lightsocial_a" href="http://www.dzone.com/links/add.html?title=Testing+java+equals+and+hashcode+methods&amp;url=http%3A%2F%2Fmartinaharris.com%2F2009%2F10%2Ftesting-java-equals-and-hashcode-methods-essential%2F" target="_blank"><img class="lightsocial_img" src="http://martinaharris.com/wp-content/plugins/light-social/dzone.png" alt="Vote on DZone" title="Vote on DZone" /></a>&nbsp;&nbsp;<a class="lightsocial_a" href="http://www.facebook.com/sharer.php?t=Testing+java+equals+and+hashcode+methods&amp;u=http%3A%2F%2Fmartinaharris.com%2F2009%2F10%2Ftesting-java-equals-and-hashcode-methods-essential%2F" target="_blank"><img class="lightsocial_img" src="http://martinaharris.com/wp-content/plugins/light-social/facebook.png" alt="Share on Facebook" title="Share on Facebook" /></a>&nbsp;&nbsp;<a class="lightsocial_a" href="http://delicious.com/save?title=Testing+java+equals+and+hashcode+methods&amp;url=http%3A%2F%2Fmartinaharris.com%2F2009%2F10%2Ftesting-java-equals-and-hashcode-methods-essential%2F" target="_blank"><img class="lightsocial_img" src="http://martinaharris.com/wp-content/plugins/light-social/delicious.png" alt="Bookmark this on Delicious" title="Bookmark this on Delicious" /></a>&nbsp;&nbsp;<a class="lightsocial_a" href="http://www.dotnetkicks.com/kick/?title=Testing+java+equals+and+hashcode+methods&amp;url=http%3A%2F%2Fmartinaharris.com%2F2009%2F10%2Ftesting-java-equals-and-hashcode-methods-essential%2F" target="_blank"><img class="lightsocial_img" src="http://martinaharris.com/wp-content/plugins/light-social/dotnetkicks.png" alt="Kick It on DotNetKicks.com" title="Kick It on DotNetKicks.com" /></a>&nbsp;&nbsp;<a class="lightsocial_a" href="http://dotnetshoutout.com/Submit?title=Testing+java+equals+and+hashcode+methods&amp;url=http%3A%2F%2Fmartinaharris.com%2F2009%2F10%2Ftesting-java-equals-and-hashcode-methods-essential%2F" target="_blank"><img class="lightsocial_img" src="http://martinaharris.com/wp-content/plugins/light-social/dotnetshoutout.png" alt="Shout it" title="Shout it" /></a>&nbsp;&nbsp;<a class="lightsocial_a" href="http://www.linkedin.com/shareArticle?mini=true&amp;url=http%3A%2F%2Fmartinaharris.com%2F2009%2F10%2Ftesting-java-equals-and-hashcode-methods-essential%2F&amp;title=Testing+java+equals+and+hashcode+methods&amp;summary=&amp;source=" target="_blank"><img class="lightsocial_img" src="http://martinaharris.com/wp-content/plugins/light-social/linkedin.png" alt="Share on LinkedIn" title="Share on LinkedIn" /></a>&nbsp;&nbsp;<a class="lightsocial_a" href="http://www.technorati.com/faves?add=http%3A%2F%2Fmartinaharris.com%2F2009%2F10%2Ftesting-java-equals-and-hashcode-methods-essential%2F" target="_blank"><img class="lightsocial_img" src="http://martinaharris.com/wp-content/plugins/light-social/technorati.png" alt="Bookmark this on Technorati" title="Bookmark this on Technorati" /></a>&nbsp;&nbsp;<a class="lightsocial_a" href="http://twitter.com/home?status=Reading+http%3A%2F%2Fmartinaharris.com%2F2009%2F10%2Ftesting-java-equals-and-hashcode-methods-essential%2F" target="_blank"><img class="lightsocial_img" src="http://martinaharris.com/wp-content/plugins/light-social/twitter.png" alt="Post on Twitter" title="Post on Twitter" /></a>&nbsp;&nbsp;<a class="lightsocial_a" href="http://www.google.com/buzz/post?url=http%3A%2F%2Fmartinaharris.com%2F2009%2F10%2Ftesting-java-equals-and-hashcode-methods-essential%2F" target="_blank"><img class="lightsocial_img" src="http://martinaharris.com/wp-content/plugins/light-social/google_buzz.png" alt="Google Buzz (aka. Google Reader)" title="Google Buzz (aka. Google Reader)" /></a>&nbsp;&nbsp;</div><div class="dzone_button" style="float: right; margin-left: 5px;">
<script type="text/javascript">
var dzone_url = 'http://martinaharris.com/2009/10/testing-java-equals-and-hashcode-methods-essential/';
var dzone_title = 'Testing java equals and hashcode methods';
var dzone_blurb = '';
var dzone_style = '2';
</script>
<script language="javascript" src="http://widgets.dzone.com/links/widgets/zoneit.js"></script>
</div>]]></content:encoded>
			<wfw:commentRss>http://martinaharris.com/2009/10/testing-java-equals-and-hashcode-methods-essential/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>IDE Generation of equals methods has its moments</title>
		<link>http://martinaharris.com/2009/10/ide-generation-of-equals-methods-has-its-moments/</link>
		<comments>http://martinaharris.com/2009/10/ide-generation-of-equals-methods-has-its-moments/#comments</comments>
		<pubDate>Sat, 24 Oct 2009 21:26:29 +0000</pubDate>
		<dc:creator>Martin Harris</dc:creator>
				<category><![CDATA[java]]></category>
		<category><![CDATA[software quality]]></category>
		<category><![CDATA[compareto]]></category>
		<category><![CDATA[eclipse]]></category>
		<category><![CDATA[equals]]></category>
		<category><![CDATA[generation]]></category>
		<category><![CDATA[ide]]></category>
		<category><![CDATA[netbeans]]></category>
		<category><![CDATA[quality]]></category>

		<guid isPermaLink="false">http://www.koitok.net/2009/10/ide-generation-of-equals-methods-has-its-moments/</guid>
		<description><![CDATA[This blog entry looks at the code generated by Eclipse and Netbeans and demonstrates why its a good idea to both test the code and review it thoroughly. <a href="http://martinaharris.com/2009/10/ide-generation-of-equals-methods-has-its-moments/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<h3>Generating java bugs in equals methods using an IDE</h3>
<p>Its no revelation that Eclipse, Netbeans and others can generate code.  Its particularly useful if getters, setters or constructors are required.  Implementing an interface is very simple indeed as these IDE will stub out the interface methods.  More complex methods though require some thought.  Generation of the equals method is such a case.</p>
<p>How to write a good equals method is well documented by Joshua Bloch in <a href="http://www.amazon.com/Effective-Java-2nd-Joshua-Bloch/dp/0321356683/ref=sr_1_1?ie=UTF8&#038;s=books&#038;qid=1254412228&#038;sr=8-1" target="_blank">Effective Java, Chapter 3 by Joshua Bloch</a>.</p>
<h3>Eclipse V Netbeans who generates the best code?</h3>
<p>Before we get deeper into the code here are two efforts at generating the equals method for this class:</p>
<pre class="brush: java; gutter: false;">
public class SimpleBean  {
    private final BigDecimal bigDecimal;
    public SimpleBean(BigDecimal bigDecimal) {
        this.bigDecimal = bigDecimal;
    }
}
</pre>
<p><span id="more-19"></span></p>
<p>The results for even such a simple class are interesting.</p>
<p><strong>Netbeans</strong></p>
<pre class="brush: java; gutter: false;highlight: 6">
      @Override
      public boolean equals(Object obj) {
          if (obj == null) {
              return false;
          }
          if (getClass() != obj.getClass()) {
              return false;
          }
          final SimpleBean other = (SimpleBean) obj;
          if (this.bigDecimal != other.bigDecimal &#038;&#038;
                (this.bigDecimal == null ||
                !this.bigDecimal.equals(other.bigDecimal))) {
              return false;
          }
          return true;
     }
</pre>
<p>The Netbeans attempt is reasonable at first sight.  Even with the above there are a few observations and a bug which I will come to later on.  Can you spot it?</p>
<ul>
<li>The <strong>getClass</strong> system for checking that our object can be tested for equality is a little inflexible.  For classes that implement a common interface its nice to be able to compare across implementations.  This is often done using the <strong>if (!(obj instanceof MyType))</strong> check.  GetClass is optimal, but it would be good to have an option in the generation.</li>
<li>The style of the value check is a little compressed for some tastes.</li>
</ul>
<p><strong>Eclipse</strong></p>
<pre class="brush: java; gutter: false;highlight: 7">
  @Override
  public boolean equals(Object obj) {
      if (this == obj)
	  return true;
      if (obj == null)
	  return false;
      if (getClass() != obj.getClass())
          return false;
      SimpleBean other = (SimpleBean) obj;
      if (bigDecimal == null) {
        if (other.bigDecimal != null)
          return false;
       } else if (!bigDecimal.equals(other.bigDecimal))
          return false;
       return true;
}
</pre>
<p>Eclipse generates very similar code.  The bug is still there though, can you see it yet?</p>
<ul>
<li>Eclipse has extra options.  You can switch out that <strong>getClass</strong> for the more flexible <strong>instanceof</strong> check.</li>
<li>The style above is better and can be improved with the introduction of blocks on all if statements.</li>
<li>Eclipse does more optimization assuming that more often than not an object is passed in. </li>
</ul>
<h3>Neither are good! The generated equals bug exposed!</h3>
<p>It should be clear when I write a test that will fail for either of the above implementations.</p>
<pre class="brush: java; gutter: false; wrap-lines: false">
@Test
    public void testObjectInconsistantWithEquals_Equals() {
        SimpleBean testSimpleBean = new SimpleBean(new BigDecimal("0"));
        SimpleBean expectedEqualSimpleBean = new SimpleBean(new BigDecimal("0.0"));
        assertTrue("Equality Test Fail", testSimpleBean.equals(expectedEqualSimpleBean));
    }
}
</pre>
<p>The above test fails because BigDecimal has an equals implementation that will return false when it checks <strong>100</strong> against <strong>100.00</strong>.  Its implementation of the compare method is declared as being inconsistent with equals.  This in itself is interesting but for this example it means we can modify the generated code to provide a fix using <strong>this.bigDecimal.compareTo(other.bigDecimal) != 0</strong> instead of relying on the generated use of equals.</p>
<h3>Recommendations</h3>
<p>In light of the above I would suggest the following points.</p>
<ul>
<li>Apart from primitive and well known objects generated equals methods can be very bad indeed.</li>
<li>Always write a test for equals, do not rely on an IDE.</li>
<li>If you change your object, remember to re-visit the equals method.</li>
</ul>
<div class="lightsocial_container"><a class="lightsocial_a" href="http://digg.com/submit?url=http%3A%2F%2Fmartinaharris.com%2F2009%2F10%2Fide-generation-of-equals-methods-has-its-moments%2F&amp;title=IDE+Generation+of+equals+methods+has+its+moments" target="_blank"><img class="lightsocial_img" src="http://martinaharris.com/wp-content/plugins/light-social/digg.png" alt="Digg This" title="Digg This" /></a>&nbsp;&nbsp;<a class="lightsocial_a" href="http://www.reddit.com/submit?url=http%3A%2F%2Fmartinaharris.com%2F2009%2F10%2Fide-generation-of-equals-methods-has-its-moments%2F&amp;title=IDE+Generation+of+equals+methods+has+its+moments" target="_blank"><img class="lightsocial_img" src="http://martinaharris.com/wp-content/plugins/light-social/reddit.png" alt="Reddit This" title="Reddit This" /></a>&nbsp;&nbsp;<a class="lightsocial_a" href="http://www.stumbleupon.com/submit?url=http%3A%2F%2Fmartinaharris.com%2F2009%2F10%2Fide-generation-of-equals-methods-has-its-moments%2F&amp;title=IDE+Generation+of+equals+methods+has+its+moments" target="_blank"><img class="lightsocial_img" src="http://martinaharris.com/wp-content/plugins/light-social/stumbleupon.png" alt="Stumble Now!" title="Stumble Now!" /></a>&nbsp;&nbsp;<a class="lightsocial_a" href="http://buzz.yahoo.com/buzz?targetUrl=http%3A%2F%2Fmartinaharris.com%2F2009%2F10%2Fide-generation-of-equals-methods-has-its-moments%2F&amp;headline=IDE+Generation+of+equals+methods+has+its+moments" target="_blank"><img class="lightsocial_img" src="http://martinaharris.com/wp-content/plugins/light-social/yahoo_buzz.png" alt="Buzz This" title="Buzz This" /></a>&nbsp;&nbsp;<a class="lightsocial_a" href="http://www.dzone.com/links/add.html?title=IDE+Generation+of+equals+methods+has+its+moments&amp;url=http%3A%2F%2Fmartinaharris.com%2F2009%2F10%2Fide-generation-of-equals-methods-has-its-moments%2F" target="_blank"><img class="lightsocial_img" src="http://martinaharris.com/wp-content/plugins/light-social/dzone.png" alt="Vote on DZone" title="Vote on DZone" /></a>&nbsp;&nbsp;<a class="lightsocial_a" href="http://www.facebook.com/sharer.php?t=IDE+Generation+of+equals+methods+has+its+moments&amp;u=http%3A%2F%2Fmartinaharris.com%2F2009%2F10%2Fide-generation-of-equals-methods-has-its-moments%2F" target="_blank"><img class="lightsocial_img" src="http://martinaharris.com/wp-content/plugins/light-social/facebook.png" alt="Share on Facebook" title="Share on Facebook" /></a>&nbsp;&nbsp;<a class="lightsocial_a" href="http://delicious.com/save?title=IDE+Generation+of+equals+methods+has+its+moments&amp;url=http%3A%2F%2Fmartinaharris.com%2F2009%2F10%2Fide-generation-of-equals-methods-has-its-moments%2F" target="_blank"><img class="lightsocial_img" src="http://martinaharris.com/wp-content/plugins/light-social/delicious.png" alt="Bookmark this on Delicious" title="Bookmark this on Delicious" /></a>&nbsp;&nbsp;<a class="lightsocial_a" href="http://www.dotnetkicks.com/kick/?title=IDE+Generation+of+equals+methods+has+its+moments&amp;url=http%3A%2F%2Fmartinaharris.com%2F2009%2F10%2Fide-generation-of-equals-methods-has-its-moments%2F" target="_blank"><img class="lightsocial_img" src="http://martinaharris.com/wp-content/plugins/light-social/dotnetkicks.png" alt="Kick It on DotNetKicks.com" title="Kick It on DotNetKicks.com" /></a>&nbsp;&nbsp;<a class="lightsocial_a" href="http://dotnetshoutout.com/Submit?title=IDE+Generation+of+equals+methods+has+its+moments&amp;url=http%3A%2F%2Fmartinaharris.com%2F2009%2F10%2Fide-generation-of-equals-methods-has-its-moments%2F" target="_blank"><img class="lightsocial_img" src="http://martinaharris.com/wp-content/plugins/light-social/dotnetshoutout.png" alt="Shout it" title="Shout it" /></a>&nbsp;&nbsp;<a class="lightsocial_a" href="http://www.linkedin.com/shareArticle?mini=true&amp;url=http%3A%2F%2Fmartinaharris.com%2F2009%2F10%2Fide-generation-of-equals-methods-has-its-moments%2F&amp;title=IDE+Generation+of+equals+methods+has+its+moments&amp;summary=&amp;source=" target="_blank"><img class="lightsocial_img" src="http://martinaharris.com/wp-content/plugins/light-social/linkedin.png" alt="Share on LinkedIn" title="Share on LinkedIn" /></a>&nbsp;&nbsp;<a class="lightsocial_a" href="http://www.technorati.com/faves?add=http%3A%2F%2Fmartinaharris.com%2F2009%2F10%2Fide-generation-of-equals-methods-has-its-moments%2F" target="_blank"><img class="lightsocial_img" src="http://martinaharris.com/wp-content/plugins/light-social/technorati.png" alt="Bookmark this on Technorati" title="Bookmark this on Technorati" /></a>&nbsp;&nbsp;<a class="lightsocial_a" href="http://twitter.com/home?status=Reading+http%3A%2F%2Fmartinaharris.com%2F2009%2F10%2Fide-generation-of-equals-methods-has-its-moments%2F" target="_blank"><img class="lightsocial_img" src="http://martinaharris.com/wp-content/plugins/light-social/twitter.png" alt="Post on Twitter" title="Post on Twitter" /></a>&nbsp;&nbsp;<a class="lightsocial_a" href="http://www.google.com/buzz/post?url=http%3A%2F%2Fmartinaharris.com%2F2009%2F10%2Fide-generation-of-equals-methods-has-its-moments%2F" target="_blank"><img class="lightsocial_img" src="http://martinaharris.com/wp-content/plugins/light-social/google_buzz.png" alt="Google Buzz (aka. Google Reader)" title="Google Buzz (aka. Google Reader)" /></a>&nbsp;&nbsp;</div><div class="dzone_button" style="float: right; margin-left: 5px;">
<script type="text/javascript">
var dzone_url = 'http://martinaharris.com/2009/10/ide-generation-of-equals-methods-has-its-moments/';
var dzone_title = 'IDE Generation of equals methods has its moments';
var dzone_blurb = '';
var dzone_style = '2';
</script>
<script language="javascript" src="http://widgets.dzone.com/links/widgets/zoneit.js"></script>
</div>]]></content:encoded>
			<wfw:commentRss>http://martinaharris.com/2009/10/ide-generation-of-equals-methods-has-its-moments/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

