I always learn when we declare a collection we should do, Interface ob = new Class(), if i want to use for example a LinkedList i'll do List ob = new LinkedList(), but then i can't have access to all methods from LinkedList.. Isn't LinkedList ob = new LinkedList() 100% correct?
Isn't LinkedList ob = new LinkedList() 100% correct?
Well I'd suggest using the generic form, but sure - if you want to use functionality which is specific to LinkedList, you need to declare the variable accordingly.
You might want to check whether the Deque<E> or Queue<E> interfaces have what you want though. If they do, use those in-keeping with the idea of describing what you need rather than what implementation you'll use.
Yes,
LinkedList<...> items = new LinkedList<...>();
is perfectly correct if you know that items will depend on methods of LinkedList<T> that are not captured in the List<T> interface.
You should always try to keep the declaration at the highest level possible, meaning that you should stop at the highest level that provides all the functionality that you need: if List methods are not enough, you're perfectly fine with your LinkedList declaration.
If you actually have a need to use methods that are not on the List interface, there is certainly nothing wrong with using LinkedList's API. The general rule of programming to the List interface recognizes that 1) it's pretty rare to need those methods, and 2) in most people's experience, it's way more likely that I discover I need to sort the list and/or use a lot of random access, and decide to switch to an ArrayList, than it is I need one of the methods only LinkedList has.
It may be also that you could be programming to the Queue interface, if you find List isn't giving you what you need.
The rule "always code to interfaces" must be taken with some flexibility. What you are suggesting is fine, and as you came to the conclusion, the only option.
As a side note, coding to concrete classes like this is faster is most JVMs. Deciding whether the performance is worth breaking the rule is the hard thing to decide.
LinkedList is a generic. You should be doing:
LinkedList<String> linkedList = new LinkedList<String>();
(or whatever else you need to store in there instead of String)
Not exactly 100% correct.
A preferred way to declare any collection is to include the data type it's holding. So, for your example, it'd be LinkedList<Integer> ob = new LinkedList<Integer>();.
Nope.. This would be wrong, at the later stages if he wants to change his implementation from linked list to any other implementation of list type he will go wrong... So better to use the interface level declaration.
I won't always suggest you to use generics .....
Coz sometimes you may need to wrap different objects as here....
String str="a string";
boolean status=false;
LinkedList ll = new LinkedList();
ll.add(str);
ll.add(status);
In some situations like case of RMI, u can only send serialized data.....and suppose you want to send a class object(which is unserialized).......There you can wrap the members of the class(primitives) in a LinkedList and pass that object as a whole.......not worrying about the huge number of arguments......
Consider for eg:
public Class DataHouse
{
public int a;
public String str;
.
.
.
}
Now Somewhere u need to pass the objects....
You can do the following....
DataHouse dh =new DataHouse();
LinkedList ll = new LinkedList();
ll.add(dh.a);
ll.add(dh.str);
// Now the content is serialized and can pass it as a capsuled data......
you can still have access to LinkedList methods by using List, all you have to do is to type cast
for example
((LinkedList)ob).add()
The point of using generic List and not LinkedList is because in case you simply change the type of lists you are using (let's say double linked list) your program will still work Generics are to simplify your code to be more portable and more "changeable"
Actually it would be better if it would be parametrized as both are raw types.
Related
I have seen some people using the topmost parent class as a variable type to hold the child instance and some people use just parent class only. For example:
Collection obj = new ArrayList();
Or
List obj = new ArrayList();
Here, List comes under the Collection only then can’t we use above first line instead of second?
Again, we can't use everywhere in collection framework the reference variable of Collection class only to hold any instance of the class under Collection?
Is this a good practice?
So, I wanted to know which comes under the best practices and why?
If someone could justify technically like performance concerns etc. would be greatly appreciated.
It really really depends on your needs. In your example it doesn't really changes much for basic needs but if you inspect the two interfaces there are some changes. Look :
https://docs.oracle.com/javase/7/docs/api/java/util/Collection.html
and
https://docs.oracle.com/javase/7/docs/api/java/util/List.html
We can notice that the List gives you access to methods Collection doesn't.
set(int index, E element) for instance is defined in the List interface and not in Collection.
This is because every classes inheriting from Collection don't need to implement all the same methods.
Performance wise it have no impact.
Always use the top-most parent class that have all the functionalities you need. For your example there is no need to go higher than List .
There is no so called "best practice" for choosing the class to be used for the reference type. In fact, the class in the highest hierarchy is the Object class. Do you use Object as the reference type for everything you do? No, but generally you may choose the higher class with the all the methods available for your needs.
Instead of following the so called "best practice", apply what suits best for your situation.
These are some pros and cons for using higher hierarchy classes as reference type:
Advantage
Allows grouping of object which shares the same ancestor (super class)
Allows all instances of the given class to be assigned to it
Animal dog = new Dog();
Animal cat = new Cat();
Allows polymorphism
dog.makeNoise();
cat.makeNoise();
It is only an advantage when you are accessing common behaviours or members.
Disadvantage
Requires casting when you are accessing behaviours which exist in one object but not the other.
dog.swim(); //error, class Animal do not have swim()
((Dog)dog).swim();
As you start dumping various objects in the common parent class, you may have a hard time trying to figure out which members belongs to which class.
(Cat(cat)).swim(); //error, class Cat do not have swim()
The general idea is hiding as much as you can so things are easier to change. If you need indexing for instance (List.get(int index) then it MUST be a list because a collection does not support .get(index). If you don't need indexing, then hiding the fact you're using a list, means you can switch to other collections that might not be a list later without any trouble.
For example, maybe one month later I want to use a set instead of list. But Set doesn't support .get(index). So anybody who uses this List might use the indexing features of a list and it would make it difficult to switch to a set because every where someone else used .get(), would break.
On the other hand, excessively hiding your types can cause accidental performance issues because a consumer of your method didn't know the type. Suppose you return a List that's actually a linkedlist (where indexing is O(n)). Suppose the consumer of this list does a lookup for each entry in another list. That can be O(n*m) performance which is really slow. If you advertised that it was a linked list in the first place, the consumer of the linkedlist would realize that it's probably not a good idea to make multiple indexes into this list and the consumer can make a local copy.
Library code (suppose the one you're designing)
public class Util {
public static List<String> makeData() {
return new LinkedList(Arrays.asList("dogs", "cats", "zebras", "deer"));
}
}
Caller's code (suppose the one that's using your library or method)
public static void main(String [] args) {
List<String> data = Util.makeData();
int [] indicesToLookUp = {1,4,2,3,0};
for( int idx : indicesToLookUp ) {
if(idx < data.size()) {
// each index (LinkedList.get()) is slow O(N)
doSomethingWithEntry(idx, list.get(idx));
}
}
}
You could argue it's the caller's fault because he incorrectly assumed the List is an ArrayList<> and should have made a local copy of the list.
I was looking at this old question and its chosen answer.
The chosen answer was originally,
ArrayList<ArrayList<Individual>> group = new ArrayList<ArrayList<Individual>>(4);
But was later modified to recommend this instead
List<List<Individual>> group = new ArrayList<List<Individual>>(4);
I didn't see an explanation for this on the page, can someone please explain why the second one is recommended over the first one? (I'm assuming it has to do with polymorphism)
This is code to interface. Here you can see the assignment is done to a List interface not the ArrayList class which is implementing the List. ArrayList, LinkedList implements List interface, the same way, you can have your own List implementing Class as well. So, in future if you want to change the implementation in such a way that instead of ArrayList object you want some other List implementation like LinkedList then you can easily modify the code like this -
List<List<Individual>> group = new ArrayList<List<Individual>>(4);
to
List<List<Individual>> group = new LinkedList<List<Individual>>(4)
This change will have no impact on the other part of your code which uses group variable as for other this is a List object not an Arraylist or LinkedList object. It is not going to break your code and you don't have to waste your time to modify your code to accomodate this change.
I have the following question:
if I have the following line of code:
List<Position> allPos = posDBM.getAllPos();
Position is an object
posDBM is a SQLite Database Manager class, which manages the SQLite database,
getAllPos() returns all database data.
The return type of getAllPos() is List<Position>.
If I want to initialize a List<> like this List<Position> pos = new, I have to specify the type of the List (ArrayList, LinkedList, etc.) .
So back to my question, what kind of List do I have, after I filled the list from the database?
I would guess it's an ArrayList , but I can't find any source to back this up. It's just a matter of interest...
You don't have to know; that's the point. The interface is what matters to you, not the implementation.
You can't know without looking at the source of that method. But even if you do, it's immaterial to your client. All you call are List methods.
That you will find in getAllPos() source code. List<Position> due to Polymorphism will accept all classes implementing List interface.
It you are just curious, then one way to find out is to do something like this:
List<Position> allPos = posDBM.getAllPos();
System.out.println("The class is " + allPos.getClass().getName());
Of course, you don't need to know ... because you don't need to instantiate the list implementation class yourself. The database management code deals with that.
The returned List<Position> is a generic or a Strongly Typed list. The option that you were asking is about ArrayList which specifies a list that can take up any object. This will require an overhead of Boxing and Unboxing when writing / reading using the ArrayList.
Ideally you should not worried about the actual implementation , once you have List returned from the method call , you can just iterate over it like this .
List<Position> allPos = posDBM.getAllPos();
for(Position position : allPos){
//Your code goes here
}
And if you want to initialize a new list you can do it in many ways by using different implementations of List interface , now which implementation you want to choose very much depends on your requirement.
I would suggest you to add a breakpoint and see allPos variable after posDBM.getAllPos(), the debugger should tell you the Type.
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.
I have a list of Strings and I want to perform the same operation on all of the Strings in the list.
Is it possible without performing a loop?
Well something's got to loop, somewhere - if you want to abstract that into your own method, you could do so, but I don't believe there's anything built into the framework.
Guava has various methods in Iterables to perform projections etc, but if you want to modify the list on each step, I'm not sure there's any support for that. Again, you could write your own method (extremely simply) should you wish to.
When Java eventually gets closures, this sort of thing will become a lot more reasonable - at the moment, specifying the "something" operation is often more effort than it's worth compared with hard-coding the loop, unfortunately.
You could do it recursively, but I don't see why you'd want to. You may be able to find something similar to Python's map function (which, behind the scenes, would either be a loop or a recursive method)
Also note that strings are immutable - so you'll have to create 'copies' anyway.
No. You must loop through the list.
for(String s:yourlist){
dooperation(s);
}
Why do you not want to perform a loop?
If it's computational complexity, then no, it's unavoidable. All methods will essentially boil down to iterating over every item in the list.
If it's because you want something cleaner, then the answer depends on what you think is cleaner. There are various libraries that add some form of functional map, which would end up with something like:
map(list, new Mapper<String, String>() {
public String map(String input) {
return doSomethingToString(input);
}
);
This is obviously more long winded and complex than a simple loop
for (int i = 0; i < list.size(); i += 1) {
list[i] = doSomethingToString(list[i]);
}
But it does offer reusability.
map(list, new DoSomethingToStringMapper());
map(otherlist, new DoSomethingToStringMapper());
But probably you don't need this. A simple loop would be the way to go.
You could use apache commons util.
sorry, you have to iterate through the list somehow, and the best way is in a loop.
Depending on what you mean by no loop, this may interest you:
a map function for java.
http://www.gubatron.com/blog/2010/08/31/map-function-in-java/
...there's still a loop down inside of it.
In Java you'll need to iterate over the elements in the Collection and apply the method. I know Groovy offers the * syntax to do this. You could create an interface for your functions e.g. with an apply method and write a method which takes your Collection and the interface containing the function to apply if you want to add some general API for doing this. But you'll need the iteration somewhere!
Use divide and conquer with multithreaded traversal. Make sure you return new/immutable transformed collection objects (if you want to avoid concurrency issues), and then you can finally merge (may be using another thread which will wake up after all the worker threads finished transformer tasks on the divided lists?).
If lack of memory in creating these intermediate collections, then synchronize on your source collection. Thats the best you can do.
No you have to use a loop for that.
You have to perform the operation on each reference variable to the Strings in the List, so a loop is required.
If its at the List level, obviously there are some operations (removeAll, etc.).
The java API provides special class to store and manipulate group of objects. One Such Class is Arraylist
Note that Arraylist class is in java.util.ArrayList
Create an ArrayList as you would any objects.
import java.util.ArrayList;
//..
ArrayList ajay = new ArrayList();
Here
ArrayList -> Class
ajay -> object
You can optionally specify a capacity and type of objects the Arraylist will hold:
ArrayList ajay<String> = new ArrayList<String>(10);
The Arraylist class provides a number of useful methods for manipulating objects..
The add() method adds new objects to the ArrayList.And remove() method remove objects from the List..
Sample code:
import java.util.ArrayList;
public class MyClass {
public static void main(String[ ] args) {
ArrayList<String> ajay = new ArrayList<String>();
ajay.add("Red");
ajay.add("Blue");
ajay.add("Green");
ajay.add("Orange");
ajay.remove("Green");
System.out.println(colors);
}
}
Output for this Code:
[Red,Blue,Orange]
Accepted answer link is broken and solution offered is deprecated:
CollectionUtils::forAllDo
#Deprecated
public static <T,C extends Closure<? super T>> C forAllDo(Iterable<T> collection, C closure)
Deprecated. since 4.1, use IterableUtils.forEach(Iterable, Closure) instead
Executes the given closure on each element in the collection.
If the input collection or closure is null, there is no change made.
You can use IterableUtils::forEach(Closure c)
Applies the closure to each element of the provided iterable.