Java: null of default value of object is better - java

The first case:
There is a class that has another class as its data member. When this class is instantiated, what we should do with the data member?
(A) In constructor: this.anotherClass = new AnotherClass();
(B) left it null, no need to instantiate it.
The second case:
There is a class that has an ArrayList as its data member. When this class is instantiated, what we should do with the ArrayList?
(A) In constructor: this.bulidingList = new ArrayList< Building >();
(B) left it null, no need to instantiate it.
The third case:
when we create a method in which its return type is a collection, for example
public ArrayList< Building > getBuildingList(){
/// Bah Bah Bah..
}
if there is no Building, we should return the empty ArrayList "new ArrayList< Building >()" "or null.

I would prefer not using null to avoid potential NullPointerException's. To avoid creating unnecessary objects you could construct a single static instance to return, as long as it's immutable. As for an empty ArrayList, you can use Collections.emptyList() to do this for you.
In the end it's up to you how you want to define how your API works. Either way you should clearly document it so the caller knows what to expect.

What are your needs? My general preference is to return null when possible as this avoids creating another object in memory.
Provided that you ensure the documentation clearly states that the method may return null and it is the responsibility of calling code to handle that, I don't see a problem.

There is no concrete answer. It is a case of your API, or, speaking simpler, the expectations of the surrounded code.
Try to think in details about your getBuildingList(). Is it ok to return null? Or null is forbidden and you should return empty list?
Anyway, docuemtn you thoughts in javadoc for the method.

Given the destructive nature of Nulls in Java, I think it's a good practice to return empty collections rather then null collections.
For Objects, you should return "null" if the object has no values set internally.

Is a default-initialized object meaningful, as an empty ArrayList certainly is? Then instantiate it. Don't optimize prematurely.
On the other hand, if a default AnotherClass makes no sense, then leave the member as null.
Finally, if you run into performance or memory usage problems, consider revising the design.

In my opinion, it is best to design your APIs to avoid returning a null if there is a better alternative.
For collections, return an empty collection; e.g. Collections.emptyList() or new ArrayList() ... depending on the API requirements.
For arrays, return an array of length zero.
For objects, consider whether it is feasible to use a distinguished instance of the class, or to design the API so that the result can't be null in the first place.
If you do need to return null, or accept null as a method parameter, make sure that the javadoc clearly states that this is a valid result / argument ... and what it means.
The problem with APIs that use null is that developers forget about the null case and the result is an unexpected NullPointerException. You could say that's not the API designer's fault - the API user should have read the documentation. But that doesn't really address the issue. A better approach is to avoid returning the null in the first place, especially in cases where there is a simple alternative.
The other point is that a non-null value is generally easier for the caller to deal with. A null typically has to be dealt with as a special case by the calling code. A non-null value doesn't. For example, you can iterate over an empty collection or array using a for loop, but a null has to be tested for explicitly.

The third case: when we create a
method in which its return type is a
collection, for example
public ArrayList< Building > getBuildingList(){ /// Bah Bah Bah.. }
This is awful, a public member should never return an implementation type. The signature should be:
public List< Building > getBuildingList()
That way you can (and should) return Collections.emptyList() if your data is empty.

The first case: There is a class that has another class as its data member. When this class is instantiated, what we should do with the data member?
(A) In constructor: this.anotherClass = new AnotherClass();
(B) left it null, no need to instantiate it.
I would prefer (C) In constructor: require a non-null AnotherClass parameter.
If you need a default constructor and you always expect the caller to also call setAnotherClass() afterwards you could leave it null in the constructor and check for null when you actually use the field, otherwise you should probably create a default AnotherClass object in the constructor.
The second case: There is a class that has an ArrayList as its data member. When this class is instantiated, what we should do with the ArrayList?
(A) In constructor: this.bulidingList = new ArrayList< Building >();
(B) left it null, no need to instantiate it.
I would always instantiate it, but if the list is read-only I'd declare it this way instead:
List<Building> buildingList = Collections.emptyList();
The third case: when we create a method in which its return type is a collection, for example
public ArrayList< Building > getBuildingList(){ /// Bah Bah Bah.. }
if there is no Building, we should return the empty ArrayList "new ArrayList< Building >()" "or null.
I'm not especially proud about it, but I do sometimes return null when I want an additional return value, something like getBuildingsListAndReturnNullIfThereAreNoTenants. When you just want to say "I haven't found any buildings" it's always better to return an empty list instead.
Sometimes you can do an upfront check and return Collections.emptyList() instead of creating a new ArrayList<Building> instance, but I wouldn't go out of my way to do it.

Related

How should I go about making a List method return a String value?

Not sure how else to word it. Basically I have a method that returns a List, but if the list is empty then I want a String returned. What is the best way of doing this?
if(list.isEmpty()){
return "index";
}else{
return list;
}
One of the main Java advantages is that it is strongly typed language, and you should avoid attempts to break it (if this is problem for you, use weakly typed languages like JavaScript, where type can be changed at runtime easily).
If you need a String to be returned, wrap it with immutable list of 1 element:
return list.isEmpty() ? Arrays.asList("index") : list;
Another way is to return the most general type: Object, but I see it absolutely senseless.
First, the only way to return a List or a String is to return an Object. But that forces the caller to determine the actual type of the returned object.
What is the purpose of returning a String here? It looks like it's to inform the caller of an error. If so, then the proper procedure here is to throw an exception. Instead of returning "index", throw some kind of exception, either built-in or of a type you create. Then you can just have the method's return type be List (or List<SomeDataType>).

When to return empty collections and when not too?

This question regards to the function public List inorderTraversal ().
Assume a case the root is null, the returned List is empty, ie size = 0. I am confused now since this is same as Collections.emptyList(). When should we use Collections.emptyList ? Is this inorderTraversal right place to use it instead of list with size 0 ?
public static void main(String[] args) {
List l = Collections.emptyList();
l.clear(); // No NPE
List p = null;
p.clear(); // NPE
}
So, prefer returning emptyList rather than returning null..
Collections.emptyList is a very useful means of storing a reference to an empty list (which I guess is kind of obvious).
The benefit of using it is that it's only going to occupy the memory required for a single list. Using it saves you the memory that you would use if you had multiple empty lists lying around. Also, as it's static, this List instance will always exist, whether you use it once, a thousand times or not at all.
You should use it when you wish to return a "static" list containing no objects. I use the term "static" here to indicate that the list is empty and will not be populated by any means. For example, if you have a data-access object and do a database-retrieval that yields no objects then your accessor should return a Collections#emptyList
However, if you have a list that is being used dynamically (and becomes empty as part of this), such as to back a data-structure like your own List implementation, then you should not use it as you need to keep a reference to the active list.
Additionally, if (as you should) you return defensive copies of internal arrays, then you will be able to use Collections#emptyList for when the internal list is empty.
I would return an empty collection whenever it makes sense to do so. If you need to distinguish between an empty collection and "uninitialised" or some null state, then you can return null.
You can check the size of a resulting List just before return. If the size is 0, you can return Collections.emptyList(), so your empty ArrayList will become orphaned, and will be garbage collected.
Empty lists IMO a preferable to null, since they cat prevent NullPointerException
Put simply: yes. This way, if root is null you can avoid creating ArrayList (and consuming memory unnecessarily) .
Although this is not what you ask about, but generally returning empty collection is preferred over returning null - it prevents many NPEs.
Please note that Collections.emptyList() returns an immutable list, which means that adding to it, or removing from it will fail.
http://docs.oracle.com/javase/7/docs/api/java/util/Collections.html#emptyList()

Best way to check collections not null & null conditions

we use collections like ArrayList,hashmap & many more.
Number of times we have check condition like whether list is null or not.
We have many ways to chek whether our collection is null or not.
Different ways.
1. if(list==null)
2. if(list.size()==0)
3. if(list.isEmpty())
Also sometimes we also need to check whether list is not null , so we normally check it by these ways
1. if(list!=null)
2. if(list.size()>0)
3. if(!list.isEmpty())
Which is best condition or do we need to make some combination of
these considering performance of program execution?
Best combination would be
if(list!=null && !list.isEmpty()){
//Yeah ,do something
}
One for null check, and then any thing there or not check
1. if(list!=null)
You should make sure that is never the case!!
Read Effective Java 2nd Edition by Joshua Bloch
Item 43: Return empty arrays or collections, not nulls
[...] In summary, there is no reason ever to return null from an array- or
collection-valued method instead of returning an empty array or
collection. The null-return idiom is likely a holdover from the C
programming language, in which array lengths are returned separately
from actual arrays. In C, there is no advantage to allocating an array
if zero is returned as the length.
In short, let your methods return Collections.emptyList() instead of null and you've got one thing less to worry about.
2. if(list.size()>0)
3. if(!list.isEmpty())
That depends. For a simple collection such as ArrayList, they are equivalent. But what if your Collection is actually a live view of a Database query? Calling size() might me a very expensive operation, whereas isEmpty() will always be O(1). I'd say use isEmpty().
Also see Jon Skeet's answer here: https://stackoverflow.com/a/11152624/342852
In Java8 you can use Optional to handle null cases properly. For example, both lists animalsNull and animalWithNullElements would be properly handled by the function filterList:
List<String> animalsNull = null;
List<String> animalWithNullElements = new ArrayList<String>();
animalWithNullElements.add(0, null);
animalWithNullElements.add(1, "Guybrush Threepwood");
animalWithNullElements.add(2, null);
private static List<String> filterList(List<String> animals) {
return Optional.ofNullable(animals)
.orElseGet(Collections::emptyList)
.stream()
.filter(Objects::nonNull)
.collect(Collectors.toList());
}
It really depends on what you want to do. If you want to be sure that a list exist AND has some elements then you would use
if (list != null && !list.isEmpty())
If I may give some advice, while returning collections, return by default an empty collection. That way you will avoid nulls.
Number of times we have check condition like whether list is null or not.
For a start, a null collection and an empty collection are different things. If you need to test if a collection is null you need a different test to if you are trying to test if the collection is empty.
Secondly, if a collection could be either null or empty (and they "mean" the same thing, per your application design) then you have a problem in your design. You should most likely represent ... whatever it is you are trying to represent ... one way, and not either / both ways.
Thirdly, it is generally best to use an empty collection rather than a null, because you can treat an empty and non-empty collection uniformly. By contrast, a null always needs to be handled as a special case. (And if you forget to handle the null case, then you've got a potential for NullPointerExceptions.)
Having said that ...
Which is best condition or do we need to make some combination of these considering performance of program execution?
If you really need to deal with the case of a null, then you've no choice but to test for null.
For isEmpty() versus size() == 0:
the two predicates should give the same answer (unless you have an infinite lazy collection ...), but
in some cases isEmpty() could be faster, at least in theory.
The latter depends on the implementation of the collection type: specifically, on whether the size() method needs to count the collection elements. (I don't think that any of the standard collection classes have this property, but that's not to say that you won't find some class that does ...)
So the optimal predicate is most likely either:
c != null && !c.isEmpty()
or
!c.isEmpty()
depending on whether you (really) need to cater for nulls.
And the obvious corollary is that your application is likely to be more efficient ... as well as simpler and more robust ... if you don't use null to represent empty collections. (If you need immutable empty collection objects, you can get them for free from methods / statics defined by the Collections class.)
There is a useful util class called CollectionUtils from Apache commons-collections bundle. With using it the code will look like:
if(CollectionUtils.isEmpty(collection))
It looks nice and under the hood it has the same invocation:
public static boolean isEmpty(Collection coll) {
return coll == null || coll.isEmpty();
}
null means list is initialized with null. null list size or isEmpty will throw NullPointerException. But, not null list can be empty or size==0
(list!=null) != (list.size()==0)
size==0 and isEmpty is equivalent.
(list.size()==0) == list.isEmpty()
There can be multiple approaches to handle this:
1: If code makes sure that collection cannot be null by initializing it either in constructor or as field initializaiton then caller need not to ideally check for null everywhere. Only isEmpty check should suffice:
private List<Integer> numbers = new ArrayList<Integer>(); //or in constructor
// caller can then safely use
if(numbers.isEmpty)
2: Alternatively write a utility method to have null and empty check, no need for size check as it already happens inside isEmpty call. Use this utility method elsewhere in code.
public static boolean empty(Collection<?> col) {
return col == null || col.isEmpty();
}
It depends on your program structure. For example, I have a helper class called ArrayUtils, in which I have an API that looks like this:
public static <E> boolean isEmpty(final Collection<E> collection)
{
return collection == null || collection.isEmpty();
}
I use this one when I know that I may get a null list, but when I'm absolutely sure it's not null, I use only if ( collection.isEmpty ). Improves code readability, too.
collection.size() > 1 is redundant, because you have the other APIs at your disposal.
If it you are owner of the codebase, I would avoid using such logic at all.
Instead try to follow the model when your collection supplier can't return null but has a reference to Collections.emptyXXX or just regular empty container empty.
You can do it with two predicates as below :
public static final Predicate<String> NULL_OR_EMPTY = (in) -> null == in || "".equals(in);
public static final Predicate<List<String>> STRING_LIST_NULL_OR_EMPTY = (strList) -> strList.stream().filter(NULL_OR_EMPTY).collect(Collectors.toList()).size() > 0;

Always avoid in-out parameters in Java?

There's no doubt that in-out parameters leads to confused code since they may increase unexpected/unpredictabled side-effects.
So, many good programmers say :
Avoid in-out parameters for changing mutable method parameters. Prefer to keep parameters unchanged.
For a perfectionist programmer who expects his code to be the most clean and understandable, does this "rule" must be applied in all case ?
For instance, suppose a basic method for adding elements to a simple list, there's two ways :
First way (with in-out parameter):
private void addElementsToExistingList(List<String> myList){
myList.add("Foo");
myList.add("Bar");
}
and the caller being :
List<String> myList = new ArrayList<String>();
//.......Several Instructions (or not) .....
addElementsToExistingList(myList);
Second way without out parameter :
private List<String> addElementsToExistingList(List<String> originalList){
List<String> filledList = new ArrayList<String>(originalList); //add existing elements
filledList.add("Foo");
filledList.add("Bar");
return filledList;
}
and the caller being :
List<String> myList = new ArrayList<String>();
//.......Several Instructions (or not) .....
myList.addAll(addElementsToExistingList(myList));
Pros of second way :
Parameter are not modified => no risk of unexpected side-effects for a new code reader.
Cons of second way :
Very verbose and very less readable ...
Of course, you would tell me that for a code as simple as this one, first way is really more convenient.
But, if we don't consider the difficulty of any concept/code, I juge the second way more logical and obvious for any readers (beginners or not).
However, it violates the CQS principle that consider "command" methods having void return with potential (but allowed since it's the convention) side-effects and "query" methods having a return type and without side-effects.
So, what should a motivate programmer adopt ? Mix of two accorging to the code case ? Or keep the "law" expecting to always avoid in-out parameters...
(Of course, method for adding Element is named for expliciting the example, and would be a bad name choice in real code).
I think the law should be:
Use what is more straight-forward, but always, always document the behavior of your methods extensively.
Your second example is a very nice case where without documentation you would have a guaranteed bug: the name of the method is addElementsToExistingList, but the method does not add elements to the existing list - it creates a new one. A counter-intuitive and misleading name, to say the least...
There is a third way. Wrap List<String> into a class that knows how to add elements to itself:
class ElementList {
private List<String> = new ArrayList<String>();
public void addElements(Element... elements);
}
I like this approach because it keeps the List implementation private. You don't have to worry if someone passes an immutable list to your method or whether parameters are modified. The code is simpler. Long method names like addElementsToExistingList are code smells that an object is trying to do something another object should be doing.
You should always document when mutating an object that is a parameter because otherwise this can have unintended side effects for the caller. In the first case I agree with the others that have commented that the method name is sufficient documentation.
In your second example, the elements that are already present in myList seem to be added twice. In fact you could entirely remove the parameter of the addElementsToExistingList method and rewrite it as:
private List<String> getElements() {
List<String> filledList = new ArrayList<String>();
filledList.add("Foo");
filledList.add("Bar");
return filledList;
}
List<String> myList = new ArrayList<String>();
//.......Several Instructions (or not) .....
myList.addAll(getElements());
Note that this code is not equivalent to your second example because the elements are only added once, but I think this is actually what you intended. This is the style that I usually prefer. This code is easier to understand and more flexible than the first example without adding extra code (it may degrade performance very slightly but this usually isn't a concern). The client of getElements() can now also do other things with the element list besides adding it to an existing collection.
It's fine to change/mutate parameters as long as it's documented. And of course with a method name of "addElementsToExistingList", what else should someone expect? However, as someone previously pointed out, your second implementation returns a copy and doesn't modify the original, so the method name is now misleading. Your first way is a perfectly acceptable way of doing things. The only other additional improvements is to possibly add a true/false value to the return indicating true if only all the elements were added to the list.
In the case of your example the name makes it clear - "addElementsToExistingList" to me seems pretty clearly to hint that you're going to .. er.. you know. But your concern would be justified with a less obvious name.
For example, in ruby this is commonly handled with naming conventions
"a".upcase => gives you the uppercase of the variable, leaves the original unchanged
"a".upcase! => alters the original variable

Best Practice for Returning Object References

Consider this code snippet:
class MyClass{
private List myList;
//...
public List getList(){
return myList;
}
}
As Java passes object references by value, my understanding is that any object calling getList() will obtain a reference to myList, allowing it to modify myList despite it being private. Is that correct?
And, if it is correct, should I be using
return new LinkedList(myList);
to create a copy and pass back a reference to the copy, rather than the original, in order to prevent unauthorised access to the list referenced bymyList?
I do that. Better yet, sometimes I return an unmodifiable copy using the Collections API.
If you don't, your reference is not private. Anyone that has a reference can alter your private state. Same holds true for any mutable reference (e.g., Date).
It depends on what you want.
Do you want to expose the list and make it so people can edit it?
Or do you want to let people look at it, but not modify it?
There is no right or wrong way in this case. It just depends on your design needs.
There can be some cases when one would want to return the "raw" list to the caller. But in general, i think that it is a bad practice as it breaks the encapsulation and therefore is against OO.
If you must return the "raw" list and not a copy then it should be explicitly clear to the users of MyClass.
Yes, and it has a name.. "Defensive copy". Copying at the receiving end is also recommended. As Tom has noted, behavior of the program is much easier to predict if the collection is immutable. So unless you have a very good reason, you should use an immutable collection.
When Google Guava becomes part of the Java standard library (I totally think it should), this would probably become the preferred idiom:
return ImmutableList.copyOf(someList);
and
void (List someList){
someList = ImmutableList.copyOf(someList);
This has an added bonus of performance, because the copyOf() method checks whether the collection is already an instance of immutable collection (instanceof ImmutableList) and if so, skips the copying.
I think that the pattern of making fields private and providing accessors is simply meant for data encapsulation. If you want something to be truly private, don't give it accessor methods! You can then write other methods that return immutable versions of your private data or copies thereof.

Categories