This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
When to use LinkedList<> over ArrayList<>?
I saw the API for the ArrayList and LinkedList and it seems to be same. Apart from their performance difference is there any difference in terms of adding, deleting and iterating the List.
List arrList = new ArrayList();
List linList = new LinkedList();
The List arrList or linList reference is actually implementing the corresponding class. What does this actually mean?
As far as your first question goes: their performance and their memory usage the only differences that will matter to you (the third one, their actual implementation details, aren't your concern.) LinkedLists use more memory, and getting, say, the 22nd element by walking through the list from the head is very slow; but they're terrific as far as adding and removing elements in the middle of the list. ArrayLists use less memory, and getting the 22nd element is very fast -- but inserting or removing an element in the middle takes time proportional to the size of the list.
As far as your second question goes: the statement that the reference is "actually implementing the list" is just wrong, so I don't really know how to answer it. The reference variable refers to an object that implements the List interface; both of these two classes implement that interface, so a reference of type List can refer to objects of either class.
I am not 100% sure what you mean when you ask "What does this actually mean?", but here is a guess.
Consider code like this:
interface Interface
{
void foo();
}
class Implementation
implements Interface
{
public void foo() { }
public void bar() { }
}
public class Main
{
public static void main(final String[] argv)
{
Interface a;
Implementation b;
a = new Implementation();
b = a;
a.foo();
b.foo();
a.bar(); <- won't compile
b.bar();
}
}
Interface a; and Implementation b; both point at the same object, but only the reference to "b" has access to the "bar" method.
So, in your example, any methods that are in the List interface are accessible to both arrList and linList, but any methods that they provide in addition to the List interface wont be callable without a cast. You can (and should in most cases) treat ArrayList and LinkedList as a List.
For the specifics of inserting/adding/deleting from the different lists, you generally should not care. Both behave the same way from the point of view of the end result (eg. the same sequence of method calls with the same data will result in the same result, just the internal layout will be different).
There's a good discussion of the pros and cons of these two List implementations in the Java tutorial. See the topic on List Implementations.
ArrayList is backed by an array which is resized when needed. LinkedList is made of of element nodes with references pointing to the previous and next node. There are numerous posts on this site discussing the differences, just search for them.
Related
In class, I've implemented my own LinkedList class with a private Node class so I've never run into this issue before. But now I'm trying to re-do a problem using Java's built-in LinkedList library and am running into trouble. (its also been a few years since I last used Java).
Lets say I had this simple skeleton. How would I pass the head Node into the function?
public static void main(String[] args)
{
LinkedList<Integer> test = new LinkedList<Integer>();
doSomething(test.get(0));
}
private static void doSomething(Node a)
{
//stuff
}
Also could someone remind me what the difference is between these two? I know the first you're basically casting the list as a LinkedList but why do so?
List<E> test = new LinkedList<E>();
LinkedList<E> test = new LinkedList<E>();
Looking at the documentation for LinkedList, there are no methods that expose the nodes of the list. In fact, LinkedList might even be implemented in a completely different way and not use nodes at all and still have all the properties and performance guarantees of a linked list. It's an implementation detail.
The standard library LinkedList class uses encapsulation to avoid exposing implementation details (like how list nodes are implemented) to the user of the class (you).
There is no way you can get a reference to the internal list node, save for using advanced techniques like reflection that break encapsulation.
Instead of playing around with list nodes and pointers between them, you use the methods the LinkedList class provides to add and retrieve the list elements. For example:
LinkedList<Integer> test = new LinkedList<Integer>();
test.add(314);
test.add(879);
Integer first = test.getFirst(); // returns 314
Integer first = test.get(1); // returns 879
The benefit from encapsulation is that JVM implementors are free to change the internal implementation of LinkedList completely without fear of breaking your program.
You get the same benefit in your own program if you use the List interface instead LinkedList class by writing:
List<E> test = new LinkedList<E>();
If you do this, you are free to change test from LinkedList to ArrayList or any other list implementation at a later point with no other changes to the code, for example if the application requirements change or if you find that ArrayList gives you better performance.
Java's native linked class has some issues. Iterators can be used to access nodes, but are limited as noted below. There is no way to move nodes within a list or from list to list, such as C++ std::list::splice.
https://en.cppreference.com/w/cpp/container/list/splice
For Java, "moving" nodes requires removing and inserting nodes, which involves deallocation for any node removed, and allocation for any node inserted.
Java's iterators can't be shallow copied. An assignment just sets another variable to point to the same iterator object. (C++ iterators don't have this issue).
Any removal or insertion of nodes from a list will invalidate all iterators to that list (except for the iterator used to do the remove or insert). (C++ iterators function as expected).
I have to create a class named Myset which includes methods like IsEmpty(), Insert(Object O) etc. I thought to use a Linked list of objects to implement the Myset class. But as I am new to Java, I am stuck with creating the object itself i.e. I am not clear even how to start with. I thought of something like this:
public class Myset {
LinkedList<Object> LL = new LinkedList<Object>();
}
I further have to write a method: public Myset Union(Myset a): Returns a set which is the union of the current set with the set a. This can be done by iterating through a, if the element at a particular index in a is not contained in LL then we add that element to LL. But how do I write this in a Java code? PS: This is an assignment question and we aren't allowed to use Sets implementation.
Some starting points.
You should either use "true" generics:
class MySet<T> {
private final LinkedList<T> objects = new LinkedList<T>();
or leave generics completely out, like:
class MySet {
private final LinkedList objects = new LinkedList();
You see, your solution
LinkedList<Object> LL = new LinkedList<Object>();
will allow that the user can store any kind of object in your set. So, first a String, then an Integer, and so on. Most likely, that is not what you had in mind. In general, collections in Java are about a specific sort of objects, like only Strings, or only Integer objects.
( side note: LL is a bad name for a field - so study java naming guide lines for that, too )
But there is even less sense in use <Object>. That is like using generics without using them at the same point.
And now, that you have a MySet class, you start one by one:
You add a constructor that allows instantiating an object of your class
You add methods (one by one!) that allow reasonable interaction with your class
Thing is: start slowly. Dont try to solve the big things upfront. Instead: just make sure that your class works as Set; so you can add things, you can check that they are in; and so on.
And only when all of these basic things work you should go forward and add stuff like "union".
A linked list doesn't give you any benefit for a general set. You could simply use an object array, ArrayList, Vector etc. instead, as you would have to compare each element to another specific element anyway. If you insert an element, you have to make sure, there isn't already one in it (this is part of the mathematical definition of a set), just as you have to make this sure in unions, intersections and set differences. This means you have to implement comparability, so you should use the Comparable interface instead of Object, too.
This question already has answers here:
What does it mean to "program to an interface"?
(33 answers)
Closed 6 years ago.
If we consider two implementations below, what's the actual use of the first one?
List<String> a= new ArrayList<String>();
ArrayList<String> b= new ArrayList<String>();
From what I have read in the posts, the first implementation helps in avoiding breaking change like we can change the implementation again as
a=new TreeList<String>();
But I don't understand whats the actual use of changing the implementation with treelist as we can use only the List interface methods?
But I don't understand whats the actual use of changing the implementation with treelist as we can use only the List interface methods?
Different implementations of interface List have different performance characteristics for different operations. Which implementation of List you should choose is not arbitrary - different implementations are more efficient for different purposes.
For example, inserting an element somewhere in the middle is expensive on an ArrayList, but cheap on a LinkedList, because of the way the implementations work. Likewise, accessing an element by index is cheap on an ArrayList, but expensive on a LinkedList.
It may happen that when you started writing your program, you used an ArrayList without thinking about it too much, but later you discover that a LinkedList would be more efficient.
When you've programmed against the interface List instead of a specific implementation, it's very easy to change from ArrayList to LinkedList - to the rest of the program, it still looks like a List, so you'd only have to change one line.
Lets say that you have decided to develop a more efficient List implementation of your own. Perhaps one that has better memory management internally, or may be a faster set method (insertion) implementation. You can just implement the List interface and rest of your code will continue to work without any change, except this one line. You can also extend ArrayList and write your own code.
//Old code
List<String> a = new ArrayList<String>();
a.set(0, "Test");
//New code
List<String> a = new MyCustomisedList<String>();
//Same code, but your optimized set logic. May be faster...
a.set(0, "Test");
A TreeList doesn't exist, so lets use a PersistentList as an example.
Lets say you have an #Entity that you want to save to a database:
public class MyMagicEntity {
#OneToMany
List<MyChildEntity> children;
public void setChildren(final List<MyChildEntity> children) {
this.children = children;
}
}
Now, when you create MyMagicEntity then you would do something like
final MyMagicEntity mme = new MyMagicEntity();
final List<MyChildEntity> children = new ArrayList<>();
children.add(new MyChildEntity("one"));
children.add(new MyChildEntity("two"));
children.add(new MyChildEntity("three"));
mme.setChildren(children);
//save to DB
So you created an ArrayList that you passed into your MyMagicEntity, which assigns it to the List - it doesn't care that the underlying implementation is as long as it's a List.
Now, later you do:
final MyMagicEntity mme = //load from DB
final List<Children> children = mme.getChildren();
So, what is children? Well, if we are using JPA and Hibernate it is actually a PersistentList, not an ArrayList.
As we access the members of children, Hibernate will go and pull them from the database. This List is still a List - your program doesn't have to know any of this.
Could you do this without using the List interface? No! Because:
you cannot create a PersistentList
Hibernate cannot create an ArrayList
Whilst this is an extreme example, where the underlying behaviour of the List is completely different, this applies in all sorts of other situations.
For example:
ArrayList and LinkedList have different performance characteristics, you may want to switch
Guava has an ImmutableList which you may want to use
Collections.unmodifyableList also implements List, which you may want to use
You could conceivably have a List backed by a file
The basic idea is that List defines what any list must be able to do, but not how it is done.
Here List is an Interface which contains all common operation method can perform with an List.
List Interface is parent for ArrayList , LinkedList and many more class. So, It can hold all these type of Object reference.
All these List method have different (or own type) Implementation with different class. So, whatever method you use will automatically apply according to override method definition of Object belong to the class.
List<String> a= new ArrayList<String>();
ArrayList<String> b= new ArrayList<String>();
Now , In Your case you can declare both ways is alright. but suppose a Scenario like this.
You are calling some services and you know that return any List Type (not specific) of Object. It may be a LinkedList or ArrayList or any other type of List.
at that time whatever response you get You can easily hold those responses in a List Type of Reference Variable.
and after gathering the result you can differentiate further of Object Type.
This question already has answers here:
Merge two lists in constant time in Java
(4 answers)
Closed 9 years ago.
I have two LinkedList in my code and I need to make one that have both. I will not need this Lists anymore, just the new one, which have all data I need.
I could use .addAll(), but performance is I huge issue and I cant wait to copy,adding references, everything every time..
I am looking for something like we normally do if we create our own linkedlist, just connect the last node from one to the fist from the second.. Is there a way to do that using the LinkedList class from the java api?
Merging collections is a different case, although the operation means almost the same, my issue is just regarding performance and just for linkedlists, which normally can do what I need. Also "merging" is kind of an ambiguous term, what I want is just to put then together no matter what order they are, with performance in mind.I am not looking if is possible to merge...
Another thing, my question is just regarding the API, I am not looking for building my own code (boss requirement) and that is why is different from this one: Merge two lists in constant time in Java - not useful answers there either..
If you are using LinkedList then you are most likely not interested in indexed access (since indexed access is slow... but keep in mind that a list only stores references, so for very large lists with few insert/removes you are going to be more memory efficient with an ArrayList as it doesn't need to allocate each node on the heap)
So what you actually want is something that gives you most of the List contract... or maybe not even that.
It could well be that all you want is something that gives you Iterable<String>... if that is the case then you have a very easy life:
public class UberIterable<T> implements Iterable<T> {
private final List<List<T>> lists;
public UberIterable(List<T>... lists) {
this.lists = Arrays.asList(lists);
}
public Iterator<T> iterator() {
return new Iterator<T>() {
Iterator<List<T>> metaNext = lists.iterator();
Iterator<T> next;
public boolean hasNext() {
while (true) {
if (next != null && next.hasNext()) return true;
if (metaNext.hasNext()) next = metaNext.next(); else return false;
}
}
public T next() {
if (!hasNext()) throw new NoSuchElementException();
return next.next();
}
public void remove() {
throw new UnsupportedOperation();
}
}
}
}
That is a basic implementation that will give you a merged view of many lists. If you want to get more of the contract of List you could repeat the same tricks only with a better implementation of ListIterator which will get a lot of what you are probably after, or finally by extending AbstractList and overriding the appropriate methods with your new ListIterator implementation
If you only want to iterate over the new list and you can replace List with Iterable you can use Guava's Iterable.concat as described here:
Combine multiple Collections into a single logical Collection?
I'm afraid the answer is no. The internal Entry class used by LinkedList is private, and all the public methods exposed by LinkedList work with general collections.
Your use case seems reasonable to me, but this implementation doesn't support it.
I'm afraid that the only way to do this is by using reflections... When you take a look at the source code of LinkedList, you can see that the subclass Entry<E> is private, which is a problem if you want to connect the first and last entries to other entries, in order to merge the list.
Update: Even reflections are not safe (unless you add checks), because Oracle changed the name of the subclass Entry to Node and changed the order of arguments of the constructor! in JDK 7, which is stupid IMHO.
Dirty solution: Do a whole copy paste of the source code and change the private keywords to public. However, I'm not sure this is allowed by Oracle. Check their license.
One way you could go about doing this is by using getLast() to grab the last element off the one of the lists and then use addFirst() on the other in order to add it to the front.
As has been said here, however, addAll() would not be copying anything and could be used just as easily.
If your issue is with the actual instantiation of node objects in the LinkedList, you may need to implement your own version that exposes more of the implementation mechanisms in its API.
why not create a wrapper/proxy class that implements List and contains references to the 2 sublists, then implement the List methods (or at least the ones you need downstream) - a little bit of work but if copying either of the lists is really the issue sounds like it is worth it.
import java.util.LinkedList;
public class MergeLinkedList {
public static void main(String[] args) {
LinkedList<String> mainlist = new LinkedList<String>() ;
mainlist.add("A");
mainlist.add("B");
LinkedList<String> secondlist = new LinkedList<String>() ;
secondlist.add("C");
secondlist.add("D");
mainlist.addAll(secondlist);
System.out.println(mainlist);
}
}
O/P
[A, B, C, D]
you have to use addall();
Let's say I have a class A that has a list of related elements (type of elements not relevant):
public class A {
private List<String> list;
public List<String> getList() {
return list;
}
public void addElement(String element) {
list.add(element);
}
}
Now I want access to this list from another class, Client. I need to add a new element. The question, a more phylosophical one, is how best is this done from a design point of view.
public class Client {
private A a = new A();
public void method1() {
a.getList().add("");
}
public void method2() {
a.addElement("");
}
}
If anyone could point out any advantage of any of these methods, would be much appreciated.
Thanks.
Generally your getList() method is considered bad style. If class A returns a reference to its actual List, than a caller might call clear() on that list, or add a million elements to it, or so who-knows-what-all. It's a much better idea to return only an Iterator, or only a read-only view of the List using Collections.unmodifiableList().
This means your solution 2, addElement() is better; the addElement() method might contain code to validate the added elements, limit the size of the list, or whatever. And clear() would not be accessible.
If your intention is to really expose the list, method2 is usually a better OOP-style. (Since by using method2 you'll get addAll etc for free.)
Examples of this pattern in the standard API:
HashMap.keySet
Subject.getPrincipals
The documentation should take care to say something like The object is backed by the returned collection, so modifications will ...
The drawback is that by exposing the list you allow clients to do remove and so on, so if your intention is to just collect items through add then method1 may still be a better choice.
Examples of this pattern in the standard API:
Component.addKeyListener
DefaultTableModel.addRow
I wouldn't give access to the list (i.e. getList()) its good however that you added a addElement method. That is a good idea because you can put restrictions on what can be added to the list in that method.
I would choose
public void method2() {
a.addElement("");
}
Because mantains hidden the list inside A. Of course this depends on how related is the list to A if only instances of A should get a reference to the list then this is my choice.
One other reason might be that giving away the list could lead to clients removing items, you might want to avoid clients to consider the list as their own, it's A's, keep it safe! :P
Otherwise the list does not belong to A and should be removed from it.
You should most definitely hide the underlying list in class A. A should not provide a getList() method if possible.
Class B should use a.addElement() exclusively. And, if B needs to read from the list in A, A should provide methods for accessing the list instead of giving B the entire list.
One of the main tenants of OO programming is Encapsulation. Which means that you should hide the underlying implementation of your classes, and abstract out that low-level info.
To your specific question, you will want to use method2(). You shouldn't even be able to use a.getList() from class B if you are following proper OO principles.
When coding, you should consider the maintenance process. The less the classes know about each other the better it it is.
The client should only know that A can have elements .... so I will consider the second design as being much better.
You should provide a method for adding element on class A. Returning the original List is wrong from the design point of view because the user of your class has full access to it.
method2 is better because the client doesnt need to bother with the list implementation. if class A changes its data structure, the client is not affected.