Type List vs type ArrayList in Java

(1) List<?> myList = new ArrayList<?>();

(2) ArrayList<?> myList = new ArrayList<?>();

I understand that with (1), implementations of the List interface can be swapped. It seems that (1) is typically used in an application regardless of need (myself I always use this).

I am wondering if anyone uses (2)?

Also, how often (and can I please get an example) does the situation actually require using (1) over (2) (ie where (2) wouldn't suffice..aside coding to interfaces and best practices etc.)


Almost always the first one is preferred over the second one. The first has the advantage that the implementation of the List can change (to a LinkedList for example), without affecting the rest of the code. This will be a difficult task to do with an ArrayList , not only because you will need to change ArrayList to LinkedList everywhere, but also because you may have used ArrayList specific methods.

You can read about List implementations here. You may start with an ArrayList , but soon afterwards discover that another implementation is more appropriate.


I am wondering if anyone uses (2)?

Yes. But rarely for a good reason.

And sometimes people get burned because they used ArrayList when they should have used List :

  • Utility methods like Collections.singletonList(...) or Arrays.asList(...) don't return an ArrayList .

  • Methods in the List API don't guarantee to return a list of the same type.

  • For example, in https://stackoverflow.com/a/1481123/139985 the poster had problems with "slicing" because ArrayList.sublist(...) doesn't return an ArrayList ... and he had designed his code to use ArrayList as the type of all of his list variables. He ended up "solving" the problem by copying the sublist into a new ArrayList .

    The argument that you need to know how the List behaves is largely addressed by using the RandomAccess marker interface. Yes, it is a bit clunky, but the alternative is worse.

    Also, how often does the situation actually require using (1) over (2) (ie where (2) wouldn't suffice..aside 'coding to interfaces' and best practices etc.)

    The "how often" part of the question is objectively unanswerable.

    (and can I please get an example)

    Occasionally, the application may require that you use methods in the ArrayList API that are not in the List API. For example, ensureCapacity(int) , trimToSize() or removeRange(int, int) . (And the last one will only arise if you have created a subtype of ArrayList that declares the method to be public .)

    That is the only sound reason for coding to the class rather than the interface, IMO.

    (It is theoretically possible that you will get a slight improvement in performance ... under certain circumstances ... on some platforms ... but unless you really need that last 0.05%, it is not worth doing this. This is not a sound reason, IMO.)


    You can't write efficient code if you don't know whether random access is efficient or not.

    That is a valid point. However, Java provides better ways to deal with that; eg

    public <T extends List & RandomAccess> void test(T list) {
        // do stuff
    }
    

    If you call that with a list that does not implement RandomAccess you will get a compilation error.

    You could also test dynamically ... using instanceof ... if static typing is too awkward. And you could even write your code to use different algorithms (dynamically) depending on whether or not a list supported random access.

    Note that ArrayList is not the only list class that implements RandomAccess . Others include CopyOnWriteList , Stack and Vector .

    I've seen people make the same argument about Serializable (because List doesn't implement it) ... but the approach above solves this problem too. (To the extent that it is solvable at all using runtime types. An ArrayList will fail serialization if any element is not serializable.)


    For example you might decide a LinkedList is the best choice for your application, but then later decide ArrayList might be a better choice for performance reason.

    Use:

    List list = new ArrayList(100); // will be better also to set the initial capacity of a collection 
    

    Instead of:

    ArrayList list = new ArrayList();
    

    For reference:

    在这里输入图像描述

    (posted mostly for Collection diagram)

    链接地址: http://www.djcxy.com/p/18772.html

    上一篇: 如何在保持秩序的同时从列表中删除重复项?

    下一篇: 在Java中键入列表与类型ArrayList