I am new to Java and I finally faced with a problem that I have been postponing for a long time.
I was learning LinkedLists in Java and have the following confusion, please check:
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
public class LinkedListDemo {
public static void main(String[] args) {
List<Integer> myList = new LinkedList<Integer>();
myList.add(1);
myList.add(22);
myList.add(42);
Iterator it = myList.iterator();
while(it.hasNext()){
if((int)(it.next()) == 42)
System.out.println("We found 42");
}
myList.remove();
System.out.println(myList);
}
}
Here myList.remove(); gives the following error: "cannot resolve the method 'remove'."
however, if I instantiate myList variable like this
LinkedList<Integer> myList = new LinkedList<Integer>();
I don't have the same error and my code compiles successfully.
I just want to know the working behind this. I mean sometimes I declare ArrayList variables with
List myList = new ArrayList<>();
should I instead declare like this?
ArrayList myList = new ArrayList<>();
thank you
Separate abstraction from implementation allows to code thinking in "I know I'll need here and there a List
, but I still don't know/want to choose which kind of List
at this moment" or: "I'd like to keep my options open to any List
implementation here and there in my code". This is good thing to ease coding.
LinkedList
and ArrayList
are less abstract than List
, which means that these are different implementations of List
. Usually you will prefer to use more abstract classes, like List
on this case, to separate abstraction from implementation, which is usually a good thing, eg to play with different implementations without changing the rest of your code. So:
List<Integer> myCoolList = new LinkedList<Integer>()
is usually better (as it promotes separation between abstraction and implementation, which is a good habit for your code) than:
LinkedList<Integer> myCoolList = new LinkedList<Integer>()
Now, if you choose to separate abstraction from implementation, of course you will lose the power to use methods specific for each implementation. But usually the most general class (in this case, List
) will give enough alternatives to replace the lost methods ( the LinkedList.remove()
method in this case)
Typically your remove method should have parameters.
The List interface doesn't have any remove() method without params.
So when your compiler statically checks your code, cannot find a matching method.
On the other hand, LinkedList has it. So that's why your code works.
Check the java docs for List and the LinkedList .
You can check the original code of the link, you can see that it has a remove() method that does not contain any parameters:
/**
* Retrieves and removes the head (first element) of this list.
*
* @return the head of this list
* @throws NoSuchElementException if this list is empty
* @since 1.5
*/
public E remove() {
return removeFirst();
}
However, this remove() method does not exist in the List class, the parent class of LinkedList, so when you declare in this way:
List<Integer> myList = new LinkedList<Integer>();
You will not be able to use the remove() method.
But if you use LinkedList initialization, then you will be able to use it, because remove() is unique to the subclass LinkedList.
LinkedList<Integer> myList = new LinkedList<Integer>();
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.