Zach
Zach

Reputation: 4079

Java - How to check if two ArrayLists are unique objects (even if they have the same values)?

I have a case where I want to know if a given ArrayList is a different object than another ArrayList, even if both contain the same objects in their list. I am testing some copying logic of a parent object that contains an ArrayList, and I want to make sure future developers here do not simply reassign the array list during the logic.

For example, if I have a Model class that contains an ArrayList property containing Integer objects named values, I want to do this:

// Create the original value
Model model1 = ...

// Copy the original value into a new object
Model model2 = modelCopier(model1);

// Check that they are not equal objects
assertNotEquals(model1, model2);

// Check that their values properties are not equal objects 
assertNotEquals(model1.values, model2.values);

// Check that their values properties contain the same values though!
assertEquals(model1.values.size(), model2.values.size());

Integer value1 = model1.values.get(0);
Integer value2 = model2.values.get(0);

assertEquals(value1, value2);

Which should prove that we are copying the Model objects, and their values properties, but the values in the list are equal.

Right now this fails because assertNotEquals(model1.values, model2.values) fails, which makes sense since the List class overrides the equals method as such:

Compares the specified object with this list for equality. Returns true if and only if the specified object is also a list, both lists have the same size, and all corresponding pairs of elements in the two lists are equal. (Two elements e1 and e2 are equal if (e1==null ? e2==null : e1.equals(e2)).) In other words, two lists are defined to be equal if they contain the same elements in the same order. This definition ensures that the equals method works properly across different implementations of the List interface.

https://docs.oracle.com/javase/7/docs/api/java/util/List.html

Upvotes: 1

Views: 334

Answers (3)

davidxxx
davidxxx

Reputation: 131526

To address your requirement, you have to combine assertions on object references with an assertion on the content of the objects.

Note that this assertion about the content of the collection is not strong enough :

assertEquals(model1.values.size(), model2.values.size());

Integer value1 = model1.values.get(0);
Integer value2 = model2.values.get(0);

assertEquals(value1, value2);

Asserting only the first element of the collections is clearly not enough but if you assert first that you expect a single element in the cloned collection. Which is not the case.
Instead, you should rely on the equals() method of the collection that will apply the equals() on the set of the elements.

Use Assert.assertNotSame() to assert that both Model and Model.values don't refer the same object.
Then use Assert.assertEqual() to assert that the Model.values collections are equal in terms of contained elements.

// Create the original value
Model model1 = ...

// Copy the original value into a new object
Model model2 = modelCopier(model1);

// 1) Check that they don't refer the same object
Assert.assertNotSame(model1, model2);

// 2)  Check that they don't refer the same object
Assert.assertNotSame(model1.values, model2.values);

// 3) Check that their values properties contain the same values though!   
Assert.assertEquals(model1.values, model2.values);

Upvotes: 1

mentallurg
mentallurg

Reputation: 5207

Compare the references:

assertTrue(model1.values != model2.values);

Upvotes: 0

Marvin
Marvin

Reputation: 14415

You are looking for assertNotSame:

Asserts that expected and actual do not refer to the same object.

Upvotes: 4

Related Questions