I think the reason your example works is that you're using String-typed variables.
I think the JVM might cache static references to strings, i.e. not create duplicate
objects in memory for strings having the same text value. If that's right, then
you're really not comparing two objects with equals() behavior, but one real
object with == behavior, which is why I think it worked.
I have another example that uses another object:
// Simple Object that implements equals()
public class Hey {
private String id;
public Hey( String id ) { this.id = id; }
public boolean equals( Object obj ) {
System.out.println("--- Hey.equals() called!");
Hey otherHey = (Hey) obj;
if( otherHey.id.equals( this.id ) )
return true;
return false;
}
public String toString() { return id; }
}
// Example
import org.apache.commons.collections.*;
import java.util.*;
public class Test {
public static void main( String[] args ) {
Hey objOne = new Hey("one");
Hey objTwo = new Hey("two");
Hey objThree = new Hey("three");
Hey objA = new Hey("a");
Hey objB = new Hey("b");
Hey objC = new Hey("c");
Hey extra = new Hey("two"); // another object functionally equivalent to objTwo
ArrayList listOne = new ArrayList();
ArrayList listTwo = new ArrayList();
listOne.add( objOne );
listOne.add( objTwo );
listOne.add( objThree );
listTwo.add( objA );
listTwo.add( objB );
listTwo.add( objC );
listTwo.add( extra );
// Commons Way
System.out.println("=== org.apache.commons.collections.CollectionUtils ===");
Collection intsec = CollectionUtils.intersection( listOne, listTwo );
System.out.println("Number of objects in intersection: " + intsec.size());
// java.util approach
System.out.println("=== java.util.Collection ===");
listOne.retainAll( listTwo );
System.out.println("Number of objects in intersection: " + listOne.size());
}
}
Here's the result:
=== org.apache.commons.collections.CollectionUtils ===
Number of objects in intersection: 0
=== java.util.Collection ===
--- Hey.equals() called!
--- Hey.equals() called!
--- Hey.equals() called!
--- Hey.equals() called!
--- Hey.equals() called!
--- Hey.equals() called!
--- Hey.equals() called!
--- Hey.equals() called!
--- Hey.equals() called!
--- Hey.equals() called!
--- Hey.equals() called!
--- Hey.equals() called!
Number of objects in intersection: 1
Note that when I tried CommonUtils.intersection() none was found, and
neither was Hey.equals(). If equals() had been called 'objTwo' and 'extra'
would have been found to be equivalent. When I use java.util.Collection.retainAll()
I get the result I expected since this implementation does in fact call
equals().
This is the difference in behavior that I was referring to. Whether or not
this is a bug or feature I leave to others. :-)
Regards,
Greg
Peter Ko�ek wrote:
----- Original Message -----
From: "Greg Zoller"
I have a question about some CollectionUtils methods that operateI live in hope that CollectionUtils behaves as equivalent as possible to
semantically diferently
from the java.util.Collection methods they are augmenting.
The java.util.Collection methods use equals() when doing set operations
(retainAll(), etc.).
Because it appears to be implemented largely using HashMap gets for
cardinality counting,
CollectionUtils methods such as intersection() behave according to
object comparision
using == not equals().
java.util.Collection . Given two collections
Collection _c = new ArrayList();
_c.add(("a").toUpperCase());
_c.add("X");
Collection _d = new LinkedList();
_d.add(("a").toUpperCase());
_d.add("Y");
what should be the intersection of them both? I would suggest a collection
containing one element "A". Do you agree? I have derived a snippet from the
CollectionUtils test cases to show that.
-peter
-------------------------
import java.util.*;
import org.apache.commons.collections.CollectionUtils;
public class TestCollectionUtils {
public TestCollectionUtils(String testName) {
System.out.println("And now we test feature " + testName + ".");
setUp();
}
public static void main(String args[]) {
TestCollectionUtils aTest = new TestCollectionUtils("testIntersection");
aTest.testIntersection();
System.out.println("OK - End of test");
}
private Collection _a = null;
private Collection _b = null;
private Collection _c = null;
private Collection _d = null;
public void setUp() {
_a = new ArrayList();
_a.add("a");
_a.add("b");
_a.add("b");
_a.add("c");
_a.add("c");
_a.add("c");
_a.add("d");
_a.add("d");
_a.add("d");
_a.add("d");
_b = new LinkedList();
_b.add("e");
_b.add("d");
_b.add("d");
_b.add("c");
_b.add("c");
_b.add("c");
_b.add("b");
_b.add("b");
_b.add("b");
_b.add("b");
_c = new ArrayList();
_c.add(("a").toUpperCase());
_c.add("X");
_d = new LinkedList();
_d.add(("a").toUpperCase());
_d.add("Y");
}
public void assertNull(Object o) {
if (o != null) throw new RuntimeException("assertNull: " + o.toString() +
" should be null, but it isn't.");
}
public void assertEquals(Object o1, Object o2) {
if (o1 == null && o2 == null) return;
if (o1 == null) throw new RuntimeException("assertEquals: The first object
is null, and " + o2.toString() + " isn't.");
if (!(o1.equals(o2))) throw new RuntimeException("assertEquals: " +
o1.toString() + " isn't equal to " + o2);
}
public void assertIdentity(Object o1, Object o2) {
if (o1 != o2) throw new RuntimeException("assertIdentity: " + o1 + " is
not identical with " + o2);
}
public void assertDifference(Object o1, Object o2) {
if (o1 == o2) throw new RuntimeException("assertDifference: " + o1 + " is
identical with " + o2);
}
public void testIntersection() {
Collection col = CollectionUtils.intersection(_a,_b);
Map freq = CollectionUtils.getCardinalityMap(col);
assertNull(freq.get("a"));
assertEquals(new Integer(2),freq.get("b"));
assertEquals(new Integer(3),freq.get("c"));
assertEquals(new Integer(2),freq.get("d"));
assertNull(freq.get("e"));
Collection col2 = CollectionUtils.intersection(_b,_a);
Map freq2 = CollectionUtils.getCardinalityMap(col2);
assertNull(freq2.get("a"));
assertEquals(new Integer(2),freq2.get("b"));
assertEquals(new Integer(3),freq2.get("c"));
assertEquals(new Integer(2),freq2.get("d"));
assertNull(freq2.get("e"));
assertEquals("A", "A");
assertEquals("A" + "B", "A" + "B");
assertIdentity("A" + "B", "A" + "B");
assertEquals(("A" + "B").toLowerCase(), ("A" + "B").toLowerCase());
assertDifference(("a").toUpperCase(), ("a").toUpperCase());
System.out.println("We create the string A via method call to get
different objects.");
Collection col3 = CollectionUtils.intersection(_c,_d);
Map freq_c = CollectionUtils.getCardinalityMap(_c);
Map freq_d = CollectionUtils.getCardinalityMap(_d);
System.out.println("frequency of A in _c: " + freq_c.get("A"));
System.out.println("frequency of A in _d: " + freq_d.get("A"));
Map freq3 = CollectionUtils.getCardinalityMap(col3);
System.out.println("frequency of A in intersection(_c, _d): " +
freq3.get("A"));
assertEquals(new Integer(1),freq3.get("A"));
assertEquals(new Integer(1), new Integer(col3.size()));
System.out.println("The intersection between _c and _d is " +
col3.iterator().next());
}
}
-- To unsubscribe, e-mail: <mailto:[EMAIL PROTECTED]> For additional commands, e-mail: <mailto:[EMAIL PROTECTED]>
