0
class A{
    private List<Item> itemsList;       

    public List<Item> getClonedItemsList{
        return new ArrayList<Item>(itemsLIst);
    }

    public int getItemsCount{
        return itemsList.size();
    }
}

Does it make sense to have both methods in this class? By getting a clone of the list the clients of my class can get its size as well. On the other hand other clients might not actually want to clone the list of items and they might only care about how many items there are in the list.

4 Answers 4

3

Why do the clients need a clone of the list at all? The issue here is that cloning a list is an expensive operation, which you don't want to perform unnecessarily. But there are other possible solutions, including returning a read-only wrapper of the list, or using an immutable list in the class itself. These possibilities should be examined first, and the optimization of including a get size method only considered if no other possibilities will work.

5
  • My question was if I should have getItemsCount method as well if my API already returns the list (copied or immutable, doesn't matter). Apr 11, 2016 at 10:39
  • It does matter, though. If you are making a copy of the list just so that clients can find out how large the size is, that's a wasteful and potentially very slow operation. Using an immutable or read-only list lets you return the list without copying it, and if you can do this, there's no need to have getItemsCount() because your clients could just call getList().size(). If you can't, then getItemsCount() is a necessary part of your API.
    – Jules
    Apr 11, 2016 at 17:51
  • but... what if i need an editable copy of the list? Actually there are a lot of reasons to clone an object Apr 13, 2016 at 9:01
  • 1
    @JoulinRouge then the client can clone the wrapped read-only list, which is close enough to being as efficient as the original code that it is unlikely to matter, but gives the client the choice of whether they want to incur the cost or not. Or if an immutable list implementation is used, they can use the standard methods that are usually provided with such lists to build a modified copy.
    – Jules
    Apr 13, 2016 at 12:43
  • @Jules that's a very good point, but then is better to put the getClonedItemsList method in the wrapper and the question is if it makes sense to have a getClonedItemsList and a getItemsCount in the same class, so the solution (very good indeed) you proposed does not answer the question. Apr 13, 2016 at 13:04
2

Your list copying is an example of defensive copying. By doing this, your client gets a copy of the managed list, and as such it won't change under them whilst they're (say) iterating over this. Note that simply providing a read-only wrapper to a collection will prevent your client from manipulating the list, but not that the list itself could be changed by other means.

Defensive copying can be a good practise to use in such instances where a client will use a collection/object that another entity can mutate simultaneously.

Is it an expensive operation ? That depends on the size and usage of the collection. In the above I'm guessing you're using Java, and as such the copying copy the references only, in which case the expense can be reduced (but don't forget you may want to ensure the referenced objects themselves cannot/will not mutate)

0

I don't think having extra method to get count is needed. The count property is a concern of the ArrayList rather than your class A's. Clients could always use the size property on the ArrayList to find the count.

If you have some use-case which mandates you to return a different value than what the size method on the ArrayList returns then it makes sense to create the count method

1
  • And even if both return the same size, one day I could change the method so that the returned size will be different. And if my clients relied on the fact that both returned the same value everything would break. Apr 13, 2016 at 8:18
0

Consider that the return value of getItemsCount could be different from the items' number in the cloned list specially in a multithread environment... You could have the need to check the size of the actual list instead of the cloned one so it could make sense to have both methods.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.