1. Call equals() and equalsIgnoreCase() method on known String literal rather unknown object
Always call equals() method on known String which is not null. Since equals() method is symmetric, calling a.equals(b) is same as calling b.equals(a), and that’s why many programmer don’t pay attention on object a and b. One side effect of this call can result in NullPointerException, if caller is null.
2. Why to have a private constructor?
In Java, it is possible to have a private constructor. When and why should we use private constructor is explained in detail below. Defining a constructor with the private modifier says that only the native class (as in the class in which the private constructor is defined) is allowed to create an instance of the class, and no other caller is permitted to do so.
There are two possible reasons why one would want to use a private constructor
a. You don’t want any objects of your class to be created at all
b. You only want objects to be created internally –as in only created in your class.
Private constructors can be used in the singleton design pattern
A singleton is a design pattern that allows only one instance of your class to be created, and this can be accomplished by using a private constructor.
Private constructors can prevent creation of objects
The other possible reason for using a private constructor is to prevent object construction entirely. When would it make sense to do something like that? Of course, when creating an object doesn’t make sense – and this occurs when the class only contains static members. And when a class contains only static members, those members can be accessed using only the class name – no instance of the class needs to be created.
Java always provides a default, no-argument, public constructor if no programmer-defined constructor exists. Creating a private no-argument constructor essentially prevents the usage of that default constructor, thereby preventing a caller from creating an instance of the class. Note that the private constructor may even be empty.
3. Arbitrary Number of Arguments
It means that zero or more String objects (or an array of them) may be passed as the parameter(s) for that function.
This feature is called varargs, and it's a feature introduced in Java 5. It means that function can receive multiple String arguments:
It means that zero or more String objects (or an array of them) may be passed as the parameter(s) for that function.
See the "Arbitrary Number of Arguments" section here: http://java.sun.com/docs/books/tutorial/java/javaOO/arguments.html#varargs
In your example, you could call it as any of the following:
myMethod(); // Likely useless, but possible
myMethod("one", "two", "three");
myMethod("solo");
myMethod(new String[]{"a", "b", "c"});
Note 1: The parameter(s) passed in this way is always an array - even if there's just one. Make sure you treat it that way in the method body.
Note 2: The parameter that gets the ... must be the last in the method signature. So, myMethod(int i, String... strings) is okay, but myMethod(String... strings, int i) is not okay.
4. Best Way of Looping in java
import java.util.ArrayList;
import java.util.Calendar;
import java.util.List;
public class ForLoopPerformanceTest
{
private static List<Integer> list = new ArrayList<>();
private static long startTime;
private static long endTime;
static
{
for(int i=0; i < 1_00_00_000; i++)
{
list.add(i);
}
}
@SuppressWarnings("unused")
public static void main(String[] args)
{
//Type 1
startTime = Calendar.getInstance().getTimeInMillis();
for(Integer i : list)
{
//
}
endTime = Calendar.getInstance().getTimeInMillis();
System.out.println("For each loop :: " + (endTime - startTime) + " ms");
//Type 2
startTime = Calendar.getInstance().getTimeInMillis();
for(int j = 0; j < list.size() ; j++)
{
//
}
endTime = Calendar.getInstance().getTimeInMillis();
System.out.println("Using collection.size() :: " + (endTime - startTime) + " ms");
//Type 3
startTime = Calendar.getInstance().getTimeInMillis();
int size = list.size();
for(int j = 0; j < size ; j++)
{
//System.out.println(j);
}
endTime = Calendar.getInstance().getTimeInMillis();
System.out.println("Using [int size = list.size(); int j = 0; j < size ; j++] :: " + (endTime - startTime) + " ms");
//Type 4
startTime = Calendar.getInstance().getTimeInMillis();
for(int j = list.size(); j > size ; j--)
{
//System.out.println(j);
}
endTime = Calendar.getInstance().getTimeInMillis();
System.out.println("Using [int j = list.size(); j > size ; j--] :: " + (endTime - startTime) + " ms");
}
}
When above program runs, following is the output in console:
For each loop :: 110 ms
Using collection.size() :: 37 ms
Using [int size = list.size(); int j = 0; j < size ; j++] :: 4 ms
Using [int j = list.size(); j > size ; j--] :: 1 ms
Clearly the last two ways are way ahead in terms of performance, while for each statement [type 1] is most expensive operation if compared with other three.
Update:
Reason for difference in performance
Last two flavors type 3 and 4 have a very little difference and should be considered as same. They both fetch the size of collection initially. And then uses this size value in loop for checking the condition.
Type 2 uses size() method call every time and thus on runtime it brings a little overhead. Though JVM optimizes this code as inline call and other optimizations also and size method is simply a getter for size attribute of instance of list. Even though it brings a few more statements to execute at machine level code and which makes the difference.
Type 1 is costliest one and simple reasoning is the use of iterator internally created in for each loop. Creating an iterator and calling iterator.get() adds up to most of cost which is not involved in direct access in other three types.
Always call equals() method on known String which is not null. Since equals() method is symmetric, calling a.equals(b) is same as calling b.equals(a), and that’s why many programmer don’t pay attention on object a and b. One side effect of this call can result in NullPointerException, if caller is null.
Object unknownObject = null;
//wrong way - may cause NullPointerException
if(unknownObject.equals("knownObject")){
System.err.println("This may result in NullPointerException if unknownObject is null");
}
//right way - avoid NullPointerException even if unknownObject is null
if("knownObject".equals(unknownObject)){
System.err.println("better coding avoided NullPointerException"); }
//wrong way - may cause NullPointerException
if(unknownObject.equals("knownObject")){
System.err.println("This may result in NullPointerException if unknownObject is null");
}
//right way - avoid NullPointerException even if unknownObject is null
if("knownObject".equals(unknownObject)){
System.err.println("better coding avoided NullPointerException"); }
2. Why to have a private constructor?
In Java, it is possible to have a private constructor. When and why should we use private constructor is explained in detail below. Defining a constructor with the private modifier says that only the native class (as in the class in which the private constructor is defined) is allowed to create an instance of the class, and no other caller is permitted to do so.
There are two possible reasons why one would want to use a private constructor
a. You don’t want any objects of your class to be created at all
b. You only want objects to be created internally –as in only created in your class.
Private constructors can be used in the singleton design pattern
A singleton is a design pattern that allows only one instance of your class to be created, and this can be accomplished by using a private constructor.
Private constructors can prevent creation of objects
The other possible reason for using a private constructor is to prevent object construction entirely. When would it make sense to do something like that? Of course, when creating an object doesn’t make sense – and this occurs when the class only contains static members. And when a class contains only static members, those members can be accessed using only the class name – no instance of the class needs to be created.
Java always provides a default, no-argument, public constructor if no programmer-defined constructor exists. Creating a private no-argument constructor essentially prevents the usage of that default constructor, thereby preventing a caller from creating an instance of the class. Note that the private constructor may even be empty.
3. Arbitrary Number of Arguments
public void myMethod(String... strings){
// method body
}
It means that zero or more String objects (or an array of them) may be passed as the parameter(s) for that function.
This feature is called varargs, and it's a feature introduced in Java 5. It means that function can receive multiple String arguments:
It means that zero or more String objects (or an array of them) may be passed as the parameter(s) for that function.
See the "Arbitrary Number of Arguments" section here: http://java.sun.com/docs/books/tutorial/java/javaOO/arguments.html#varargs
In your example, you could call it as any of the following:
myMethod(); // Likely useless, but possible
myMethod("one", "two", "three");
myMethod("solo");
myMethod(new String[]{"a", "b", "c"});
Note 1: The parameter(s) passed in this way is always an array - even if there's just one. Make sure you treat it that way in the method body.
Note 2: The parameter that gets the ... must be the last in the method signature. So, myMethod(int i, String... strings) is okay, but myMethod(String... strings, int i) is not okay.
4. Best Way of Looping in java
import java.util.ArrayList;
import java.util.Calendar;
import java.util.List;
public class ForLoopPerformanceTest
{
private static List<Integer> list = new ArrayList<>();
private static long startTime;
private static long endTime;
static
{
for(int i=0; i < 1_00_00_000; i++)
{
list.add(i);
}
}
@SuppressWarnings("unused")
public static void main(String[] args)
{
//Type 1
startTime = Calendar.getInstance().getTimeInMillis();
for(Integer i : list)
{
//
}
endTime = Calendar.getInstance().getTimeInMillis();
System.out.println("For each loop :: " + (endTime - startTime) + " ms");
//Type 2
startTime = Calendar.getInstance().getTimeInMillis();
for(int j = 0; j < list.size() ; j++)
{
//
}
endTime = Calendar.getInstance().getTimeInMillis();
System.out.println("Using collection.size() :: " + (endTime - startTime) + " ms");
//Type 3
startTime = Calendar.getInstance().getTimeInMillis();
int size = list.size();
for(int j = 0; j < size ; j++)
{
//System.out.println(j);
}
endTime = Calendar.getInstance().getTimeInMillis();
System.out.println("Using [int size = list.size(); int j = 0; j < size ; j++] :: " + (endTime - startTime) + " ms");
//Type 4
startTime = Calendar.getInstance().getTimeInMillis();
for(int j = list.size(); j > size ; j--)
{
//System.out.println(j);
}
endTime = Calendar.getInstance().getTimeInMillis();
System.out.println("Using [int j = list.size(); j > size ; j--] :: " + (endTime - startTime) + " ms");
}
}
When above program runs, following is the output in console:
For each loop :: 110 ms
Using collection.size() :: 37 ms
Using [int size = list.size(); int j = 0; j < size ; j++] :: 4 ms
Using [int j = list.size(); j > size ; j--] :: 1 ms
Clearly the last two ways are way ahead in terms of performance, while for each statement [type 1] is most expensive operation if compared with other three.
Update:
Reason for difference in performance
Last two flavors type 3 and 4 have a very little difference and should be considered as same. They both fetch the size of collection initially. And then uses this size value in loop for checking the condition.
Type 2 uses size() method call every time and thus on runtime it brings a little overhead. Though JVM optimizes this code as inline call and other optimizations also and size method is simply a getter for size attribute of instance of list. Even though it brings a few more statements to execute at machine level code and which makes the difference.
Type 1 is costliest one and simple reasoning is the use of iterator internally created in for each loop. Creating an iterator and calling iterator.get() adds up to most of cost which is not involved in direct access in other three types.