List<Kevin> kevin = new ArrayList<Kevin>();
I have an List of Objects of Type Kevin, now does it make any difference on what i am passing to my method?.
void method1(List<Kevin>)
void method2(ArrayList<Kevin>)
It seems that both are working, is there any difference apart from that i would have access to List interface related methods on method1 and array list related methods on method2. I am just not sure whether we need to send List or ArrayList of objects.
They will both behave the same way. It's generally preferable to code to interfaces where possible, so prefer List<Kevin> (or even Iterable<Kevin> if you just need to iterate over the collection). If your method will only function properly if it's an ArrayList<Kevin>, that's fair enough... but otherwise, it's better not to restrict the caller to force them to pass in an ArrayList.
method1 will work fine for other implementations of List as well (e.g. LinkedList), while method2 is stricter and accept only one implementation. In general, try to make your method arguments as general as possible, for re-usability reasons.
In most cases, it doesn't practically matter. An ArrayList IS a List so any functionality you get from a List you will also get from an ArrayList. And I should note, by the same principal, you may not actually get an ArrayList but rather some subclass that inherits from ArrayList (just like if you said List).
That said, it is typically considered best practice to require the most general type you need. So, if you only need methods that List provides, then pass a List object, however, if there is something specific to ArrayList that you require then pass that.
Passing an ArrayList would prevent you (or at least, make it more difficult) to change your mind and use another kind of List later, because method2() would rely on the list to be of type ArrayList, and not simply List.
Among the other List implementations that you could want to pass are LinkedList, CopyOnWriteArrayList, Arrays.asList(), Collections.synchronizedList(), or, often, Collections.unmodifiableList().
The best practice is thus to program on interfaces, and pass a List (or even a Collection or Iterable if calling methods should not even assume it's a List).
For a private method inside the same class, it doesn't matter much. But if the method is part of a public API, then passing an ArrayList could really hurt you at some time.
Related
I have an ArrayList where I want to call two methods on the first two objects in the list, and different methods on the rest, how can I do this the easiest way?
So far I have this
ArrayList<Material> materials = new ArrayList();
StyklisteMetodeKlasse.fillArray(materials);
for(Material materialer: materials.subList(0, 1)){
int brugerInput = 0; // this is only a temporary varible
materialer.setAmount(Material.calculatePlanks(brugerInput, materialer.getLength()));
materialer.setAmount(Material.calculatePlanks(brugerInput, materialer.getLength()));
//here is some code where i call different methods on the rest of the materials
When I call a method on the "materialer" does it apply for all the objects or just the first, then the second?
The best approach would most likely be the simplest one. Using polymorphism, and try and get the type of the object at runtime and select what you need to do, would be a sleek solution, but as you said, it might get complicated, especially if you do not have control over the structure and nature of the objects being passed to you.
Alternatively, you could make your classes implement an interface which abstracts the operation that you would need to do. This would allow you to always call the same method, without having to worry about who is what.
As it has been pointed out in the comments, having hardcoded index values could potentially cause more trouble than it will ever solve, since it assumes that who ever is consuming your method has inside knowledge of it how specifically works, as opposed to what it should do.
Most likely, the best approach would be to change your method to take 2 lists, as opposed to 1. This approach is easier to understand and also gives you more control and has you make less assumptions, which is usually always a good thing.
I'm creating a library to be used by people but why should my method return a List instead of an ArrayList?
Because if the user knows the real type is an ArrayList he will use the accessor [] in a loop instead of iterator but if he doesn't know he will use an iterator.
Same question for LinkedList, if the return type is a List he won't be able to use the correct accessor.
Am I right?
Returning List will make it possible for users of your library to use anything that implements a List interface, while using an ArrayList will force them to use an ArrayList.
If in the future, you as a library creator decide to change your internal implementation, that changes will be hidden from the end user by the generic interface to your library.
Because the users of your library should never know that you are using an ArrayList internally.
For example, say you return an ArrayList and lots of people have started using your library. Now if you suddenly realize a LinkedList better suits your purpose, then you break compatibility for all the folks who are presently using your code.
This is why it is always better to code to an interface, not an implementation, and even more so when you are writing code that is specifically meant to be re-used. The interface (List in this case) acts as a contract between your code and the client's code. It tells them what your code does (interface), without telling them how it does it (by not exposing the implementation).
Return an interface (or failing that a super class?) if possible. This way the method can have a broader application if overriden. This might prevent some class-specific methods from being available on the returned object but there's nothing stopping a programmer taking the List data and copying it to whatever Collection they prefer to use.
List myList = new MyLibrary().getList();
ArrayList myArrayList = new ArrayList(myList);
LinkedList myLinkedList = new LinkedList(myList);
They don't have to use an iterator - the List interface supports get(int index) as a method. If you want flexibility to change the underlying container to anything supporting the list interface, use List. If specific ArrayList methods are required on what you return, use ArrayList.
Because your user can make from your List either ArrayList or LinkedList, you will leave him a choice. It's called Programming to Interface. You should give users of your API as much freedom as you can and this technique is one of the ways how to achieve it.
1. Its the concept of Interface Polymorphism.
2. Its better to have List<My_Obj> arr = new ArrayList<My_Obj>;
3. Suppose you want to use LinkedList instead of ArrayList as somepoint, then you donot
need to worry abt how to do it..
If You are returning List then it is possible for users of your library to use anything that implements a List interface. It may be Array List or Linked List.
I typically choose the most general type possible. In this case, you could return a type that's even more general than a List, such as Collection or Iterable.
By returning Iterable, the compiler will prevent the calling code from attempting to add elements to your list. This is much stronger than relying on Collections.unmodifiableList() to fail at runtime.
Using more general types also gives you more room to manoeuvre in the future. Perhaps your method's going to load your data from a streaming source rather than an in-memory source: then Iterable becomes a much more suitable than List.
This question already has answers here:
Type List vs type ArrayList in Java [duplicate]
(15 answers)
Closed 10 years ago.
What are the fundamental differences between the two objects? Is one more efficient? Does one have more methods?
List is in interface while ArrayList is a class.
See ArrayList, and List.
E.g, you can't use this setup:
List<String> list = new List<String>();... Because it's an interface.
However, this works:
ArrayList<String> arrayList = new ArrayList<String>();
Also... You can do as duffymo says below, which is more or less the same as implementing the List interface (making your own list implementation).
Consider a line like the following:
List<String> names = new ArrayList<String>();
If you're new to object-oriented architectures, you might have expected instead to see something like ArrayList<String> names = new ArrayList<String>();. After all, you've just said that it's a new ArrayList, so shouldn't you store it in a variable of type ArrayList?
Well, you certainly can do that. However, List is an interface--like a template of sorts--that ArrayList is said to inherit. It is a contract that says "anytime you use a List implementation, you can expect these methods to be available". In the case of List, the methods are things like add, get, etc.
But ArrayList is only one implementation of List. There are others, such as LinkedList. The two have the same interface, and can be used the same way, but work very differently behind the scenes. Where ArrayList is "random" access, meaning that it directly finds a specific element of the array without iterating through the whole list, LinkedList does have to start from the first element and go one-by-one until it gets to the element you need.
The thing is, while you do need to specify which you want when you create the object, you generally only need to communicate no more than the fact that it is a List, so you simply say that's what it is. List communicates that you have a collection that is intended to be in the order that it is given. If you don't need to communicate that much, you might consider passing it around as a Collection, which is another interface (a super-interface of List). Or, if all you need to communicate is that you can iterate over it, you might even call it an Iterable.
List is an interface; ArrayList is a class that implements the List interface.
Interfaces define the method signatures that are required, but say nothing about how they are implemented.
Classes that implement an interface promise to provide public implementations of methods with the identical signatures declared by the interface.
A List defines the interface that ArrayList uses, that allows it to implement methods that will allow all other classes that implement List to be used together or in a similar way. An ArrayList is always also a List, but an List isn't necessarily an ArrayList.
That is, ArrayList implements List (among a few other interfaces).
How to use List and ArrayList, or other implementation of List, is Polymorphism and Inheritance, and also the reason why for using languages such as Java.
In simplicity, Polymorphism is many forms while Inheritance is reuse.
There can be many kinds of concrete and ready to us List that is available to you, such as ArrayList, Vector, LinkedList and Stack. The decision to use which comes from you, and if you look at the List API, you would notice that all of these List implementations extend in one way or another from List.
According to the java docs, List is just an interface, and ArrayList is one of the classes that implement it. There is no inherent efficiency advantage to using ArralyList specifically instead of List-typed references to an ArrayList object.
However, when it comes to "efficiency", there can be a difference between different implementations of the List interface. For instance there can be a small efficiency difference between a LinkedList and an ArrayList, depending on how you're using them.
To quote the java docs on the ArrayList page,
The add operation runs in amortized constant time, that is, adding n elements requires O(n) time. All of the other operations run in linear time (roughly speaking). The constant factor is low compared to that for the LinkedList implementation.
In other words, the performance difference will probably be negligible, but you may see some advantage from using an ArrayList (as opposed to a LinkedList).
In case you're interested, ArrayList is implemented with an array that is resized from time to time (most likely whenever your collection doubles in size), which is quite different from the implementation of a LinkedList (see wikipedia for details).
This has been bugging me for a while and have yet to find an acceptable answer. Assuming a class which is either a subclass or implements an interface why would I use the Parent class or Interface as the Type i.e.
List list = new ArrayList();
Vehicle car = new car();
In terms of the ArrayList this now only gives me access to the List methods. If I have a method that takes a List as a parameter then I can pass either a List or an ArrayList to it as the ArrayList IS A List. Obviously within the method I can only use the List methods but I can't see a reason to declare it's type as List. As far as I can see it just restricts me to the methods I'm allow to use elsewhere in the code.
A scenario where List list = new ArrayList() is better than ArrayList list = new ArrayList() would be much appreciated.
You write a program that passes lists around several classes and methods. You now want to use it in a multi threading environment. If you were sensible and declared everything as List, you can now make a single change to one line of code:
List list = Colllections.synchronizedList(new ArrayList());
If you had declared the list as an ArrayList, you would instead have to re-write your entire program. The moral of the story - always program to the least restrictive interface that your code requires.
Using the interface or parent type is generally recommended if you only need the functionality of the parent type. The idea is to explicitly document that you don't really care about the implementation, thus making it easier to swap out the concrete class for a different one later.
A good example are the Java collection classes:
If you always use List, Set etc. instead of e.g. ArrayList, you can later switch from ArrayList to LinkedList if you find that it gives e.g. better performance. To do that, just change the constructors (you don't even have to change them all, you can mix). The rest of the code still sees an instance of List and continues working.
If you actually used ArrayList explicitly, you'd have to change it everywhere it's used. If you don't actually need an ArrayList specifically, there's nothing to be gained from using it over the interface.
That's why it's generally recommended (e.g. in "Effective Java" (J.Bloch), Item 52: "Refer to Objects by their interfaces".) to only use interfaces if possible.
Also see this related question: Why classes tend to be defined as interface nowadays?
The key is exactly that the interface or base class restricts what you can do with the variable. For example, if you refactor your code later to use another implementation of that interface or base class, you won't have anything to fear -- you didn't rely on the actual type's identity.
Another thing is that it often makes reading the code easier, e.g. if your method's return type is List you might find it more readable to return a variable of type List.
An interface specifies a contract (what does this thing do), an implementation class specifies the implementation details (how does it do it).
According to good OOP practice, your application code should not be tied to implementation details of other classes. Using an interface keeps your application loosely coupled (read: Coupling)
Also, using an interface lets client code pass in different implementations and apply the decorator pattern using methods like Collections.synchronizedList(), Collections.unmodifiableList() etc.
A scenario where List list = new
ArrayList() is better than ArrayList
list = new ArrayList() would be much
appreciated.
One concrete example: if it's a field declaration and you have a setList(), which of course should take a List parameter to be flexible.
For local variables (and fields with no setters), there is very little concrete benefit in using the interface type. Many people will do it anyway on general principle.
You were right. In these cases, the variables are fields or local variables, they are not public interface, they are implementation details. Implementation detail should be detailed. You should call an ArrayList an ArrayList, because you just deliberately chose it for your implementation.
People who recycle cliches: look at your post and think a little bit more. It's nonsense.
My previous answer that was downvoted to death:
Use interface or type for variable definition in java?
I have method List<Foo> getFoos () which gets the data from remote server and returns it.
Of course, user shouldn't change number of items of the list because he'll get data not synchronized with data on the server (and if he want change number of items he has special methods like addFoo ()).
First approach was to return array and change method's signature to Foo[] getFoos (). But it's more common in java and more convenient to user to operate with collections so I changed signature to List<Foo> getFoos (). This method always returns
Collections.unmodifiableList (originalList)
So, when user try to change the list he will get RuntimeException.
Are there any recommendations about api design in similar cases?
Collections.unmodifiableList is perfectly acceptable and should be faster (no need to create an array).
Edit - In terms of API design, you should just make your JavaDoc clear! People who use a method without reading its doc deserve the surprise :p
I'd also say it is perfectly acceptable and much better than returning an array (which some suggest should be treated as a deprecated type altogether). If you want to be more explicit about it in the API however, you could consider returning an ImmutableList from Google Collections.
I virtually never return a naked list or array. If you have a collection of something, it nearly always has SOME code somewhere associated with it that should be a part of that collection. By not having a class around the collection you are forcing yourself to duplicate that code across different places where the collection is used.
There is also, generally, a variable or two that are associated with the collection. You'll find you pass them whenever you pass the collection. These belong in the business logic class that wraps the collection.
If you want a custom, specialized property from an existing object, or List in this case why not try extending or contain it and make the relevant accessors to throw an exception?
The reason is because you may wish to allow some other client objects to modify the list; it depends on how close to the application level is the returned data.
If you have complete freedom and it seems you do, then you should not have to choose between array or List, rather return an iterator. This would also help if you need uniqueness so instead of returning Set - still return iterator.