I'm developing for Android and wondered, what are the main differences between an ArrayList and a List?
For the handling of objects collection in Java, Collection interface have been provided. This is available in java.util package.
"List" is an interface, which extends collection interface, provides some sort of extra methods than collection interface to work with collections. Where as "ArrayList" is the actual implementation of "List" interface.
The ArrayList class has only a few methods in addition to the methods available in the List interface. There is not much difference in this. The only difference is, you are creating a reference of the parent interface in the first one and a reference of the class which implements the List (i.e) the ArrayList class in the second. If u use the first, you will be able to call the methods available in the List interface and you cannot make calls to the new methods available in the ArrayList class.Where as, if you use the second one, you are free to use all the methods available in the ArrayList.
EDIT:
In Java Applications development, when you are supposed to pass the collection framework objects as arguments to the methods, then it is better to go with
List tempList = new ArrayList();
somemethodcall(tempList);
because, in future due to performance constraints, if you are changing the implementation to use linkedlist or some other classes which implements List interface, instead of ArrayList, you can change at only one point (i.e) only the instantiation part. Else you will be supposed to change at all the areas, where ever, you have used the specific class implementation as method arguments.
user370305 gives an exact explanation. This may also help you understand the collections hierarchy in Java.
List is interface which ArrayList implements. If you are trying to create a method which needs a List of some kind but you are not bothered what implemntation is actually used then use List.
If you are actually instantiating a class then you have to pick some implementation of List one of which is ArrayList
List<String> l1 = new ArrayList<String>();
would be an example.
You can not instantiate an interface and so would get an error if you tried to do the following:
List<String> l2 = new List<String>();
There is a good article on wikipedia about that, where the arraylist is called "dynamic array".
If you are trying to optimize your application you should take a look at the table next to the article.
List is an interface and ArrayList is an implementation of the List interface. The ArrayList class has only a few methods in addition to the methods available in the List interface.
Have a look at the short article on JavaBeat - Difference Between List and ArrayList?
Related
List < WebElement> LElement=driver.findElements(By.tagname("a"));
In the above case the driver.findElements will return the list of WebElement and Now we have the Object of List that is "LElement" ,Now suppose if i want to get the first Element i can use below code
LElement.get(0);
But my doubt here is the get() method is present in List interface So i should Create Object of Either ArrayList or LinkedList to implement this method..But in above case i can directly get result of get method without implementing from ArrayList or Linked List and directly from interface..Can somebody explain me about this?
This question is irrespective of selenium and is a concept called polymorphism in OOP.
The List interface provides abstract methods and the class implementing List should provide an implementation body for the abstract methods. Therefore the method get() in the List interface is implemented in the class ArrayList and the other implementations of the List interface. ArrayList is a type of List, therefore we can have something like this:
List<WebElement> webElements = new ArrayList<>();
Now let's say I want to create the API findElements for Selenium. If I create the method like this:
public ArrayList<WebElement> findElements(input..){
It would be tightly coupled with ArrayList and everyone will have to use ArrayList from their end to use that API's method, which is not desirable.
A better solution would be to use some abstract concept to represent the ArrayList, which turns out to be the List interface.
public List<WebElement> findElements(input..){
List<WebElements> webElements = new ArrayList<>();
webElements.addAll(some operations to populate the list)
return webElements;
}
This one is more flexible, how? Let's say after releasing the app, we deducted the implementation of ArrayList is not the best option for us to use for that use case, and we would like to use to LinkedList instead. Using the first way of writing the API, the consumers of the API would have to make the change from their side as well. Using the better way, they do not need to do anything :)
The List is still an instance of ArrayList; in the provided example. Selenium must have implemented something similar. We are getting a concrete implementation of List when we are invoking findElements, it is just that we do not know what implementation class we are getting but we do know that it provides implementation bodies for the abstract methods found in the List interface and we can use them.
List is an interface.
List<String> list=new ArrayList<String>();
Here, lets say we are creating a reference variable of list interface and assigning it to the ArrayList object which implemets List interface.
Lets say if we want to get the size of the list. We will use list.size() which will internally invoke the size() method of ArrayList object using Runtime Polymorphism.
Simply here what I mean to say is the methods of List is implemented in ArrayList class thats why we are able to use it.
Question is,
How I am able to use size() and how the size method is being implemented in what Class ?
List<WebElement> noOfRows=driver.findElements(By.xpath(".//*[#id='leftcontainer']//tbody/tr"));
List<WebElement> noOfCol=driver.findElements(By.xpath(".//*/tr/th"));
int rowSize=noOfRows.size();
int colSize=noOfCol.size();
I hope you guys are getting my point.
When I say List<String> list= new ArrayList<String>();
That means I am going to use ArrayList methods as runtime polymorphism.
But what in this case...
driver.get("https://money.rediff.com/gainers/bse/daily/groupa?src=gain_lose");
List<WebElement> noOfRows=driver.findElements(By.xpath(".//*[#id='leftcontainer']//tbody/tr"));
List<WebElement> noOfCol=driver.findElements(By.xpath(".//*/tr/th"));
int rowSize=noOfRows.size();//How I am able to use method of a List interface
int colSize=noOfCol.size();
I am able to run the program and do everything but just want to clear the concept here . Seems like I am confused on a minor issue but want this confusion to be gone. Thankyou in advance
A variable in Java can have a type List, but it is not possible to instantiate the List interface, that is, to create an object of type List in memory. The objects in memory are of some other type that implements the List interface.
The object returned from findElements implements the interface List, but the actual class of that object is unknown to the compiler. You can query it at runtime, by using the getClass method, but that is usually not necessary because you can treat it as a List without having to know exactly what kind of List it is.
When you call size on the List returned by findElement, the JVM selects the correct size implementation to use based on the actual type of the object. So if it just happens to be an ArrayList then you'll get ArrayList.size, etc. Often the type of List returned from a method like this isn't one of the usual types from java.util but some custom implementation that is tailored to the task at hand.
This question already has answers here:
Type List vs type ArrayList in Java [duplicate]
(15 answers)
Closed 9 years ago.
Hi,I am a beginner of Java, I was taught to use "ArrayList" in OO programming in the Java lecture, however, I came across "List" today and have no idea how to use it, so what the difference between ArrayList and List? And what the same attributes of them?
something like:
List<...>list=new List<...>()
ArrayList<...>list=new ArrayList<...>()
List is an interface, whereas ArrayList is a concrete class that implements that interface
List is an interface.
ArrayList is a class that implements List.
You can't instantiate an interface, you have to instantiate one of classes which implements it.
List defines the basic contract that is expected that implementations would provide. ArrayList is a implementation of this contract that is backed by a dynamic array.
The great thing about this idea is, if you have a method that needs access to some kind of List, you can simply ask that callers pass you any implementation of List, meaning you don't need to know or care how the List is actually implemented, only that it will provide the contract described by List
You can't create an instance of List directly, you need to use one of the implementations, like ArrayList or LinkedList...
For example...
List<String> listOfStrings = new ArrayList<String>(25);
List<String> anotherListOfStrings = new LinkedList<String>();
List is an interface, essentially providing a list of operations (add, remove, get...), but no implementation (you cannot do new List). There are several classes implementing List interface, including ArrayList (using, as said, an array as internal container) and, for instance, LinkedList. You can instantiate these, instead, and write:
List<ElementType> myList = new ArrayList<ElementType>();
Using List as a type for myList reduces the effort if you want to replace ArrayList with LinkedList:
List<ElementType> myList = new LinkedList<ElementType>();
(immagine, instead, if you had to replace ArrayList with LinkedList in several places, instead). Additionally, you will hide the actual implementation lying behind, so that other programmers don't make tricky assumptions on how the List might behave.
I don't understand difference between:
ArrayList<Integer> list = new ArrayList<Integer>();
Collection<Integer> list1 = new ArrayList<Integer>();
Class ArrayList extends class which implements interface Collection, so Class ArrayList implements Collection interface. Maybe list1 allows us to use static methods from the Collection interface?
An interface has no static methods [in Java 7]. list1 allows to access only the methods in Collection, whereas list allows to access all the methods in ArrayList.
It is preferable to declare a variable with its least specific possible type. So, for example, if you change ArrayList into LinkedList or HashSet for any reason, you don't have to refactor large portions of the code (for example, client classes).
Imagine you have something like this (just for illustrational purposes, not compilable):
class CustomerProvider {
public LinkedList<Customer> getAllCustomersInCity(City city) {
// retrieve and return all customers for that city
}
}
and you later decide to implement it returning a HashSet. Maybe there is some client class that relies on the fact that you return a LinkedList, and calls methods that HashSet doesn't have (e.g. LinkedList.getFirst()).
That's why you better do like this:
class CustomerProvider {
public Collection<Customer> getAllCustomersInCity(City city) {
// retrieve and return all customers for that city
}
}
What we're dealing with here is the difference between interface and implementation.
An interface is a set of methods without any regard to how those methods are implemented. When we instantiate an object as having a type that is actually an interface, what we're saying is that it is an object that implements all of the methods in that interface... but doesn't provide is with access to any of the methods in the class that actually provides those implementations.
When you instantiate an object with the type of an implementing class, then you have access to all of relevant methods of that class. Since that class is implementing an interface, you have access to the methods specified in the interface, plus any extras provided by the implementing class.
Why would you want to do this? Well, by restricting the type of your object to the interface, you can switch in new implementations without worrying about changing the rest of your code. This makes it a whole lot more flexible.
The difference, as others have said, is that you are limited to the methods defined by the Collection interface when you specify that as your variable type. But that doesn't answer the question of why you would want to do this.
The reason is that the choice of data type provides information to the people using the code. Especially when used as the parameter or return type from a function (where outside programmers may have no access to the internals).
In order of specificity, here is what different type choices might tell you:
Collection - a group of objects, with no further guarantees. The consumer of this object can iterate over the collection (with no guarantees as to iteration order), and can learn its size, but cannot do anything else.
List - a group of objects that have a specific order. When you iterate over these objects, you will always get them in the same order. You can also retrieve specific items from the collection by index, but you cannot make any assumptions about the performance of such retrieval.
ArrayList - a group of objects that have a specific order, and may be accessed by index in constant time.
And although you didn't ask about them, here are some other collection classes:
Set a group of objects that is guaranteed to contain no duplicates per the equals() method. There are no guarantees regarding the iteration order of these objects.
SortedSet a group of objects that contains no duplicates, and will always iterate in a specific order (although that specific order is not guaranteed by the collection).
TreeSet a group of ordered objects with no duplicates, that exhibits O(logN) insert and retrieval times.
HashSet a group of objects with no duplicates, that does not have an inherent order, but provides (amortized) constant-time access.
The only difference is that you're providing access to list1 through the Collection interface, whereas you provide access to list2 through the ArrayList interface. Sometimes, providing access through a restricted interface is useful, in that it promotes encapsulation and reduces dependence on implementation details.
When you perform operations on "list1", you'll only be able to access methods from the Collection interface (get, size, etc.). By declaring "list" as an ArrayList, you gain access to additional methods only defined in the ArrayList class (ensureCapacity and trimToSize, for example.
It's typically best practice to declare the variable as the least specific class you need. So, if you only need the methods from Collection, use it. Typically in this case, that would mean using List, which lets you know it's ordered and can handle duplicates.
Using the least specific class/interface allows you to freely change the implementation later. For example, if you later learn that a LinkedList would be a better implementation to use, you could change it without breaking all your code if you define the variable to be a List.
For example:
List<String> list = new ArrayList<String>();
vs
ArrayList<String> list = new ArrayList<String>();
What is the exact difference between these two?
When should we use the first one and when should we use the second?
Use the first form whenever possible (I would even say: use Collection if sufficient). This is especially important when accepting input from client code (method arguments). Sometimes, for the convenience of the client code/library user it is better to accept the most generic input you can (like Collection) and deal with it rather than forcing the user to convert arguments all the time (user has LinkedList but the API requires ArrayList - terrible).
Use the second form only when you need to invoke methods on list variable that are defined in ArrayList but not in List (like ArrayList.trimToSize()). Also when returning data to the user consider (but this is not the rule of thumb) returning more specific types. E.g. consider List over Collection so the client code can easier deal with the result. However! Returning too specific types (e.g. ArrayList) will lock your implementation for the future, so try to find a compromise.
This is a general rule - use the most general type you can. Even more general: use common sense.
List is not a superclass, it is an interface.
By using List rather than ArrayList, you make sure that users of your list will only use methods that are defined on List. Meaning that you can change the implementation to (for example) Vector, without breaking the existing code.
So, use the first form.
The first form is the most desirable one because you hide the implementation (ArrayList) from the rest of your code and ensure your code only works with the abstraction (List). The advantage of this is that your code will be more generic and therefore easier to adapt, for example when you change from using an ArrayList to a LinkedList, Vector or own List implementation. It also means local changes are less likely to cause changes in other parts of your code ('ripple-effect'), increasing your code's maintainability.
You need the second form when you want to do things with your variable that are not offered by the List interface, for example ensureCapacity or trimToSize
EDIT: extra explanation of changing the implementation
Here is an example of declaring a variable as a Collection (an even more generic interface in java.util):
public class Example {
private Collection<String> greetings = new ArrayList<String>();
public void addGreeting(String greeting) {
greetings.add(greeting);
}
}
Now suppose you want to change the implementation in order to store unique greetings, and therefore switch from ArrayList to HashSet. Both are implementations of the Collection interface. This would be easy in this case because all the existing code treats the greetings field as a Collection:
public class Example {
private Collection<String> greetings = new HashSet<String>();
public void addGreeting(String greeting) {
greetings.add(greeting);
}
}
There is an exception. If there is code which casts the greetings field back to its implementation, this makes that code 'implementation-aware', violating the information-hiding you tried to achieve, for example:
ArrayList<String> greetingList = (ArrayList<String>) greetings;
greetingList.ensureCapacity(42);
Such code would cause a runtime error 'java.lang.ClassCastException: java.util.HashSet incompatible with java.util.ArrayList' if you change the implementation to HashSet, so this practice should be avoided if possible.
There are some advantages of using interfaces against concrete classes:
You are not stuck to concrete implementation (you can easy change it without modifying code)
Your code is clearer as no methods of concrete class are available
You need concrete implementation only in case if you USE some features of it.
E.g. we have Matrix interface and have two concrete implementations SparseMathix and FullMatrix. If you want to effectively multiply them you CAN use some implementation details of SparseMatrix otherwise performance MAY be too slow.