Tuesday, April 18, 2017

Difference between ArrayList and ArrayList<?> in Java - Raw Type vs Wildcard

One of my readers asked me about the difference between ArrayList vs ArrayList< in Java?>, which was actually asked to him on a recent Java development interview. The key difference between them is that ArrayList is not using generics while ArrayList is a generic ArrayList but they looks very similar. If a method accepts ArrayList or ArrayList<?> as a parameter then it can accept any type of ArrayList e.g. ArrayList of String, Integer, Date, or Object, but if you look closely you will find that one is raw type while other is using an unbounded wildcard. What difference that could make? Well, that makes a significant difference because ArrayList with raw type is not type safe but ArrayList<?> with the unbounded wildcard is type safe.

You can add objects of any type into raw ArrayList but you cannot do that with a generic ArrayList with unbounded wildcard i.e. ArrayList, it will be a compile-time error, as we'll see by a code example in this article.

This is one of the very interesting Java Interview questions from Generics and Collection, but unfortunately, I didn't have that one in my list of Java Generics Interview questions but will add it soon.

I really love whenever I got this kind of interesting questions which is both thoughts provoking and really test your knowledge of Java fundamentals. So, if you have such questions, please share with us too.




Difference between Raw Type vs Unbounded Wildcard ArrayList

Now, let's see a Java program to understand the point I make in above paragraph. I said, that when you use a raw type ArrayList or ArrayList with unbounded wildcard as method arguments you can accept any type of ArraList i.e. your client can pass ArrayList of String, ArrayList of Integer, or ArrayList of Date object, but if you try to add new objects to that list then raw type will allow but generics list with unbounded wildcard will not allow.

It will throw a compile-time error because it doesn't know which type of ArrayList it has received and be being type-safe it throws an error every time you try to add a new element. You cannot even add java.lang.Object into a list of unbounded wildcards. That's why Effective Java recommend using bounded wildcard and PECS pattern while creating API using generics. They make your API more flexible.

In this program, I have two methods, printWildcardList and printRawTypeList former accepts an ArrayList while later accepts a raw type ArrayList as an argument. Both methods, first prints all elements of the given ArrayList by using Java 1.5 enhanced for loop and then tries to add new elements to list. You can see that only raw type ArrayList allows that because it is not type-safe. The same operation is prohibited on ArrayList of unbounded wildcard and you will see a compile-time error there.


I know, Generic sometimes can be really confusing, especially if you have a half knowledge and that's why Interviewer wants to know during an interview. If you can explain the fact that ArrayList is a raw type and not type-safe and ArrayList is type safe but not flexible and how you can make it flexible e.g. by using bounded wildcards like ArrayList then you will score good marks.

If you are keen to learn Generics, especially core concepts like this then there is no better book than Java Generics and Collection by Maurice Naftalin. I strongly suggest every experienced Java developer read that book not once but twice to get a good knowledge of this key feature.

Difference between ArrayList and ArrayList<?> in Java



Java Program to show difference between ArrayList and ArrayList
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;


/**
 * Java Program to demonstrate difference between ArrayList and ArrayList>
 * 
 * @author WINDOWS 8
 */

public class Test {

    public static void main(String args[]) {
        
        ArrayList<String> names = new ArrayList<String>();
        names.add("Java");
        
        // you can pass any type of ArrayList of to both methods
        printRawTypeList(names);
        printWildcardList(names);
    }
        
    
    /*
     * Java method which takes an ArrayList of raw types
     * and print elements on console
     */
    public static void printRawTypeList(ArrayList rawType){
        for(Object obj : rawType){
            System.out.println(obj);
        }
        
        rawType.add(101); // OK
        rawType.add("101");  // OK
        rawType.add(121.00);  // OK
    }
    
    
    
    /*
     * Java method which prints ArrayList of unbounded wildcard
     */
    public static void printWildcardList(ArrayList<?> unbounded){
        
        // since ? doesn't specify any type, you can simply use object
        for(Object obj : unbounded){
            System.out.println(obj);
        }
        
        unbounded.add(101); // NOT OK
        unbounded.add("101");  //  NOT OK
        unbounded.add(121.00);  // NOT OK

    }
   

}

When you try to run this program in your favorite IDE or command-line you will see a lot of compile time error on the places where I have mentioned NOT OK because you cannot add new elements into an ArrayList of unknown type.

One again, if you are keen to improve your knowledge about Generics, I strongly suggest you reading following items from Effective Java which are related to Generics and Collections:



That's all on the difference between ArrayList and ArrayList in Java. Remember raw type is not type safe but ArrayList with the unbounded wildcard is type safe because you can add any type (String, Integer, Object into ArrayList of raw type, but you cannot add any element on ArrayList of unknown type.

Other Java Generics tutorials you may like to explore
  1. How Generics works internally in Java? (tutorial)
  2. How to create parameterized classes and methods in Java? (example)
  3. What is the difference between bounded and unbounded wildcards in Generics? (answer)
  4. How to implement singly linked list using Generics in Java? (tutorial)
  5. 12 Advanced Java Programming books for Experienced Programmers (books)
  6. 10 Tips to become a better Java Programmer (tips)

Thanks for reading this article. If you like this interview question then please share with your friends and colleagues. If you have any feedback, suggestion, or any interview question which you like to share with us, please drop a comment.

P.S. - Remember, the unbounded wildcard in method argument is inflexible and not recommended and I have only used here for demonstration purpose. You should always follow suggestions given in Effective Java regarding designing a generic API e.g. using bounded wildcards for method arguments.

No comments :

Post a Comment