Ammon
Ammon

Reputation: 31

Is the Java collection method retainAll() guaranteed to leave the order of the list it modifies unaltered?

Can it depend on which collection object is using the retainAll? I'm using lists of strings.

I've searched quite a bit and I found a bunch of hints on here and elsewhere online that it should leave the order of the list unaltered, but no clear direct answer. If its already answered, please point me in the right direction.

I even found code examples of implementing the retainAll function that would indicate the order isn't touched. But as I understand these examples may not be exactly how the standard method is coded in the downloaded java package. From my own tests using the method also seems to show it stays in order. But I wanted to make more sure as the test I'm making relies specifically on the list staying in order.

To be most exact, I want this function to be true and robust.

 /**
 * This function takes the expected list and verifies it is contained within the actual list, in the expected order
 * @param expectedList {@link List} List ordered as it should be to pass criteria
 * @param actualList {@link List} List ordered as it exists in the product
 * @return {@link Boolean} returns true when the expectedList is ordered within the actualList correctly
 */
static boolean verifyOrder(List<String> expectedList, List<String> actualList)
{
    boolean ordered = false

    if (expectedList == actualList)
        ordered = true
    else
    {
        actualList.retainAll(expectedList)
        if (actualList == expectedList)
            ordered = true
    }
    return ordered
}

Upvotes: 3

Views: 1565

Answers (2)

mentallurg
mentallurg

Reputation: 5207

1) Method retainAll() is defined in the interface Collection, not in the List. In the collection basically there is no order. For instance, Set is a collections and hast this method, too. But there is no order in the Set (unless you use some very special implementatiton of Set). Order is defined only for List. That's why your question makes sense only for List, not for Collection in general.

2) If we mean List: The specification does not require to preserve the order of elements, if retainAll is called on List. The JLS definition is very vague: JLS says about List that it is An ordered collection... The user can access elements by their integer index. But there is no word about preserving the order during any manipulation. I actually would expect that the order should be preserved, but the JLS does not require that. That's why formally you should not expect that the order even in the list will be preserved.

Upvotes: 0

Andreas
Andreas

Reputation: 159124

For reference, let assume the call is:

list.retainAll(coll)

Otherwise the question makes no sense, given that list is the collection being modified, and is the one that has specified order.

Is the Java collection method retainAll() guaranteed to leave the order of the list it modifies unaltered?

The specification explicitly says that it removes elements from list that is not in coll, so the question of order depends on whether remove method is specified to retain order.

Since you said "leave the order of the list" then the answer is: Yes

But you also phrased it "Is the Java collection method retainAll()", so if list is not a List but some other collection type, then the answer is No, because not all collection types guarantee order.

Can it depend on which collection object is using the retainAll?

Since list is the one that is using the method, then: No
Well, assuming it is a List, but that has already been answered.

If you meant to refer to coll as "the one that is using the method", then: No
However performance is affected depending on the collection type of coll, because the implementation uses coll.contains() to check for matches, so you will get much better performance if coll is a Set.

Upvotes: 3

Related Questions