Monday, January 26, 2015

Cloning an Object - Deep and Shallow Copy

In Java, Cloning is a way to create an identical object adhering to some properties. clone() is one of the methods provided by the Object class. When we look at the javadoc of the clone method, it is explained as (The definition is short and modified version).

A Clone object should follow the properties even though these are not forced. ( a is an object of any type )
  • a != a.clone() must be true. 
  • a.getClass() should be equal to a.clone().getClass()
  • a.equals(a.clone()) must be true
In addition to the above properties, to make clone method to work, the class of the object must implement Cloneable interface otherwise, a cached exception CloneNotSupportedException will be thrown. (Even thought the Cloneable interface doesn't hold the method clone() but it should be implemented to clone an object).

Shallow and Deep Copying

Java default implementation of clone method clones only primitive members and copies the references of the other class type variables. This is Shallow Coping. Just call super.clone() inside the clone method. 

Example of Shallow Copy

Rectangle.java
public class Rectangle implements Cloneable
{
    private Long length;
    private Long breadth;
    
    public Rectangle(Long l, Long b)
    {
        this.length = l;
        this.breadth = b;
    }
    //getters and setters are ignored.

    @Override
    protected Object clone() throws CloneNotSupportedException
    {
        return super.clone();
    }
    @Override
    public boolean equals(Object obj)
    {
        if(obj instanceof Rectangle)
        {
            Rectangle other = (Rectangle)obj;
            return (other.length == length && other.breadth == breadth);
        }
        return false;
    }
    @Override
    public int hashCode()
    {
        int hashCode = 0;
        if(length != null)
            hashCode += length.hashCode();
        if(breadth != null)
            hashCode += breadth.hashCode();
        return hashCode;
    }
    @Override
    public String toString()
    {
        StringBuffer buffer = new StringBuffer();
        buffer.append("Length : ");
        buffer.append(length);
        buffer.append("; Breadth : ");
        buffer.append(breadth);
        return buffer.toString();
    }
}

Sample Execution
        Rectangle r = new Rectangle(10L, 12L);
        try
        {
            Rectangle s = (Rectangle)r.clone();
            System.out.println("r is : "+r);
            System.out.println("s is : "+s);
            System.out.println("Properties");
            System.out.println("r == s : "+(r == s));
            System.out.println("r.equals(s) : "+(r.equals(s)));
            System.out.println("r.getClass() == s.getClass() : "+(r.getClass() == s.getClass()));
        } catch (CloneNotSupportedException e)
        {
            e.printStackTrace();
        }

Output looks like:
 
r is : Length : 10; Breadth : 12
s is : Length : 10; Breadth : 12
Properties
r == s : false
r.equals(s) : true
r.getClass() == s.getClass() : true

Points to be noted

  • No need to write any implementation as Java by default does the shallow copying. 
  • clone method always return object of type Object
  • clone method throws CloneNotSupportedException
  • call super.clone() when only shallow copying is required Otherwise we need to copy the remaining objects.
  • Rectangle method implemented Cloneable Interface otherwise clone() cannot be called on the object of type Rectangle. 
  • hashCode and equals methods also to be implemented otherwise equals() doesn't return true when object and it's clone are compared.

Deep Copying

If the class contains non-primitive type members, the default implementation copies the references instead of creating a copy. So, the cloned object won't be a real copy. In order to clone the object with non-primitive members, we should explicitly copy the members. 

Example of Deep Copy

Person.java
public class Person implements Cloneable
{
    private String name;
    private Address address;

    //Getters and setters ignored.

    @Override
    protected Object clone() throws CloneNotSupportedException
    {
        Person p = (Person) super.clone();
        p.setAddress((Address)getAddress().clone());
        return p;
    }
    @Override
    public int hashCode()
    {
        int hashCode = 0;
        if(name != null)
            hashCode += name.hashCode();
        if(address != null)
            hashCode += address.hashCode();
        return hashCode;
    }
    @Override
    public boolean equals(Object obj)
    {
        if(obj instanceof Person)
        {
            Person other = (Person)obj;
            return (other.getName().equals(name) && other.getAddress().equals(getAddress()));
        }
        return false;
    }
    
}

Address.java
public class Address implements Cloneable
{
    private String city;
    private String country;
    //Getters and setters are ignored.

    @Override
    protected Object clone() throws CloneNotSupportedException
    {
        return super.clone();
    }
    @Override
    public int hashCode()
    {
        int hashCode = 0;
        if(city != null)
            hashCode += city.hashCode();
        if(country != null)
            hashCode += country.hashCode();
        return hashCode;
    }
    @Override
    public boolean equals(Object obj)
    {
        if(obj instanceof Address)
        {
            Address other = (Address)obj;
            return (other.getCity().equals(city) && other.getCountry().equalsIgnoreCase(country));        
        }
        return false;
    }
}

Points to be noted

  • Person class contains an member of type Address. If clone is not called on address type, then only name of the person will be copied onto the cloned object.
  • Instead of using the clone method on the Address object, we can copy field by field. (little clumsy though, if we wish we can).
  • The three properties still hold on all the objects which are Cloneable (Person and Address both).
  • To make clone to work, either all the sub-classes need to implement Cloneable or write the logic to copy the members.
And finally, the three properties which are followed by above classes need not to be satisfied, or Java doesn't force to implement but it's always good practice to make the class to follow if it has to be cloned. Otherwise write a simple method copy to create a new copied object, instead of using Clone method. 

Happy Learning!!!!

Monday, October 13, 2014

Scala - Functions

As we know functions are group of statements to perform a piece of operation/task. We will quickly dive into the details instead of long definitions.

Syntax

def is the keyword used to define the function.
def function_name ([param1:type]{,param2:type}):returnType = {
    [Statements]
    return value;
}

Example

def sum(x:Int, y:Int) : Int =
{
   return x + y;
}

// Calling the function
val x:Int = 20;
val y:Int = 30;
var z:Int = sum(x,y);

println("Sum is "+z);
This exactly looks the way we define and call in other languages but Scala simplified the definition by making some of the tokens optional.
  • Type of the return value is optional. So function prototype can be without :returnType after arguments
  • return keyword is optional.
  • If there is only one line in the function, then braces are options. Braces required to say it's a block
Now, the above function can be defined as
def sum(x:Int, y:Int) = x + y;

Anonymous Functions

Scala provides a very simple and convenient way to define the anonymous functions. See below for an example
val sum = (x:Int, y:Int) => x + y; // val to be used instead of def keyword.

//Calling
println(sum(15,50)); //Prints 65

  • In case of anonymous functions, we don't need def keyword. We have to use val keyword instead.
  • Calling the function is same as the normal functions.
One more point here is, the parameter names are optional in case of anonymous functions. So, we can define the function as
val add5:(Int,Int)=> Int = _ + _; // No argument names

//Call the function
println(sum(15,50)); //calling is same.

Return Tuples 

Scala allows us to return multiple values as a tuple. Let's see an example of how to swap two strings using a tuple.
def swap(x:String, y:String):(String, String) = { return (y, x)}; //Returning in reverse order 
def swap2(x:String, y:String) = (y, x); //Removed optional tokens

//Calling
val (a,b) = swap("Hi","Scala");
println(a,b); //Prints Scala, Hi

val (c,d) = swap2("Hi","Scala");
println(c,d); //Prints Scala, Hi

Variable arguments 

Variable arguments can be specified to function using the operator *. Example shows the syntax and usage.
def printArgs(x:String*) = {
  for(a <- x)
  {
     println(a);
  }
}

//Calling
printArgs("Hi", "Hello", "Scala"); //Prints the strings in order.

Default and Named arguments 

Scala allows to default some of the arguments and also to pass the arguments based on the name of the parameters instead of the order
def increment(x:Int, y:Int = 1) = x + y; // Defaults the argument y to 1 if not passed

//Calling
println(increment(20)); //Increases by 1 because not passed
println(increment(20,5)); //Increases by 5 because 5 is passed

def printValues(x:String, y:Int) = {
   println(" X = "+x+" : Y = "+y);
}

//Calling
printValues(x="Hi", y=20); // Prints X = Hi : Y = 20
printValues(y=20, x="Hi"); // Prints X = Hi : Y = 20 - Even order is different because of named arguments
That's it for the current post. Happy Learning!!!

Saturday, September 27, 2014

Introduction to Scala

Scala is an acronym for Scalable Language. Scala integrates the features of both object oriented and functional languages. It's one of the languages which runs on JVM. The Scala is designed to be concise, elegant and type-safe.

Features

To keep the discussion short, i will not detail each and every feature but list some of them.
  • Object oriented
  • Functional Language
  • Statically Typed
  • Runs on JVM
  • Can execute Java Code

Getting Started

Like JDK, Scala comes with
  • scalac - Scala compiler which compiles the Scala code to byte code like javac command
  • scala - Scala interpreter and command line (called as REPL) to execute the byte code like java command
When you launch scala (without any arguments) prints the scala version and opens the scala command line, where you can execute the scala commands as below

Scala Interpretor

The interpreter helps us to be familiar with the scala language features like expressions, variables, types etc. before writing the Scala programs. The Scala Interpreter is called REPL - Read Evaluate Print Loop.


Variables and Assignments


Variables are created using var keyword and assign values with assignment operator (=).

Constants


Constants can be defined using val. Unlike variables these can't be re-assigned. These are like final keyword in Java. See below

Functions


Functions are the most important in any programming language to avoid the code duplication and organizing the code into blocks for more readability. The functions are defined in Scala using def keyword

Program Files and Running using scala command

Commands in a file


Instead of using interpreter to run the commands, write into a file with an extension .scala and call using the scala command.
The following commands are added to a file called Commands.scala
println("Hello World")
val x=20
val y=30
var z=x+y
println(z)
Run the file using scala command
# scala Commands.scala 
Hello World
50
#

Hello World using a Class


The below class is written into a file HelloWorld.scala.

object HelloWorld {
   def main(args:Array[String]) {
       if(args.length < 1)
         println("Enter your name!!!!");
       else
         println("Hello "+args(0)+"!!");
   }
}

Points to be noted 

  • HelloWorld is a class which is defined with object keyword (like class keyword in java)
  • main the method where the program start which has array of strings as an argument
  • def is the keyword to be used to define a method (rather function) 
  • The syntax is almost similar to Java language as you see in if and else conditional statement.
  • Array elements are accessed using ( unlike in Java [

Run the program

Run the program using scala command 
# scala HelloWorld.scala     
Enter your name!!!!
# scala HelloWorld.scala Veeru
Hello Veeru!!

Compile the Program


Instead, you can compile the scala program into a byte code and then run using scala command. To compile the program use scalac command.  

# scalac HelloWorld.scala 

This will create a class file called HelloWorld.class which is byte code created for the class HelloWorld.

Run the Program

Run the program using the command scala.
# scala HelloWorld      
Enter your name!!!!
# scala HelloWorld Veeru
Hello Veeru!!

As simple as that. If you have an idea of how to create and execute a Java program, Scala is almost same except the compiler and interpreter commands.


Happy Learning!!!!

Tuesday, September 23, 2014

Garbage Collection in Java

Unlike C Language, the Java allocates and de-allocates the memory automatically. De-allocation is done by garbage collector. In this post, we focus on the de-allocation (Garbage collection). Automatic garbage collection is the process of identifying the objects which are in use, then remove the unused objects and compact the memory.

The garbage collection is done by phases
  • Mark: This is the process of identifying the objects which are in use and which are not
  • Sweep: De-allocating the objects which are not in use.
  • Compact: This is to improve the performance of allocation and de-allocation. After de-allocation, the objects may spread across the memory. The compact phase brings all the referenced objects together to create the empty space at one side.
Next question that rises is, how GC knows which objects are live. If there is a reference to the still open, then it is classified as Live object (Reference Object as in the picture). Reference means referred by the program or referred by the other memory unit (Like objects in Young generation may referred by the objects in Old generation). In this case, Old generation has a fixed memory length called "card table". This card table contains the reference of the objects in Young generation which are being referred by Old generation, then GC just looks at the card table to determine the Live Object reference from Old Generation.

Garbage Collectors

There are few types of garbage collectors which are evolved over the time.  

Serial GC

Serial GC is a very old GC which can be used with the machines with single CPU. It pauses the application while going through the phases of Mark, Sweep and Compact. This GC is not performant, so may result in loosing the throughput of the application. This is the default GC on all the single CPU machines. 
Command line flag for using this GC is -XX:+UseSerialGC

Parallel GC

As the name indicates, multiple GC threads runs during the garbage collection. The number of threads created for garbage collection are equal to the number of CPUs. If there is only one CPU, its equal to the Serial GC. The number of threads can be controlled using the command line switch : -XX:ParallelGCThreads=<no_of_threads>. It's also called as "Throughput GC" as the garbage collection is done in parallel. 
The command line switch to enable the GC is : -XX:+UseParallelGC. By default, parallel threads are created for Young Generation GC, but only one thread for Old Generation GC. If we would like to add multiple threads for the Old Generation, use the command line switch : -XX:+UseParallelOldGC to enable Parallel GC with Multiple Old Generation threads (This to be used independently, not in conjunction with Parallel GC)

CMS Collector

Abbreviated to Concurrent mark sweep collector. It doesn't have an option to compact the memory after sweeping. Moreover its runs in parallel with application thread(s). 
It goes through the following phases
  • Initial Mark: First marks the objects which are very close to the class loader so the pause time of the application will be very small. 
  • Concurrent Mark: The objects referenced by the surviving objects that have just been confirmed are tracked and checked.
  • Re-mark: This step re-checks the objects which are marked in Concurrent Mark.
  • Concurrent Sweep: Here, the un-referred objects are collected to complete the garbage collection process.
Points to remember
  • All the steps runs in parallel with the application threads except "Initial Mark" step
  • After Sweep, no compaction is done to bring all the live objects together. To allocate the bigger objects in this GC, allocate more Heap because memory may not be sufficient as compaction is not done
  • This GC is used with time critical and performance required applications. 
The command line option to request the GC is : -XX:+UseConcMarkSweepGC

G1 GC

G1 GC is officially released with Java7. It was also there in Java6, but for only test purpose. In the process of the G1 Collector, we don't see the memory moving from Young to Old Generation. As shown below, the memory is allocated in blocks. Once block is full, the memory is allocated in the next block and GC will run. This is full time replacement for the CMS Collector. G1 is faster than any other type of GCs we have seen so far.

The command line to enable the GC is : -XX:+UseG1GC. To read more about G1 GC, follow the link

Happy Learning

Sunday, September 21, 2014

JSR 199 - Compiler API

JSR 199 provides the compiler API to compile the Java code inside another Java program. The following are the important classes and interfaces provided for facilitating the compilation from a Java program.
  • JavaFileObject - Represents a compilation unit, typically a class source.
  • SimpleJavaFileObject - Implementation of the methods defined in JavaFileObject
  • DiagnosticCollector - Collects the compilation errors, warning into a list of Diagnostic type
  • Diagnostic - Reports the type of the problem and details like line number, character, error reason etc. 
  • JavaFileManager - To work on the Java source and class files.
  • JavaCompiler - The compiler instance for compiling the compilation unit. 
  • CompilationTask - A sub interface of JavaCompiler which helps to compile and return the status with diagnostic when used call method on it. 

Where to start

To compile a Java code, we need the Java source. The source can be a physical file on the disk or a string inside the program. Using the source, we need create an instance type of JavaFileObject.

Using String literal

Create a class which implements JavaFileObject, here i am using SimpleJavaFileObject. We need create the path URI of the class file
package com.test;

import java.io.IOException;
import java.net.URI;

import javax.tools.SimpleJavaFileObject;

public class SampleSource extends SimpleJavaFileObject
{ 
    private String source;

    protected SampleSource(String name, String code) {
        super(URI.create("string:///" +name.replaceAll("\\.", "/") + Kind.SOURCE.extension), Kind.SOURCE);
        this.source = code ;
    }
 
    @Override
    public CharSequence getCharContent(boolean ignoreEncodingErrors)
            throws IOException {
        return source ;
    }
}
Now, create the instance of JavaFileObject and from those, create the Compilation Unit (A collection of JavaFileObject)
String str = "package com.test;"
                + "\n" + "public class Test {"
                + "\npublic static void test() {"
                + "\nSystem.out.println(\"Comiler API Test\")-;" + ""
                        + "\n}" + "\n}";

        SimpleJavaFileObject fileObject = new SampleSource("com.test.Test", str);
        JavaFileObject javaFileObjects[] = new JavaFileObject[] { fileObject };
        Iterable<? extends JavaFileObject> compilationUnits = Arrays
                .asList(javaFileObjects);

From File System

If the source is from physical location. Then create like this.
File []files = new File[]{file1, file2, file3, file4} ;
Iterable<? extends JavaFileObject> units =
           fileManager.getJavaFileObjectsFromFiles(Arrays.asList(files));

Create a JavaFileManger

We will see, how to create a fileManger now.
JavaFileManager fileManager = compiler.getStandardFileManager(
                diagnostics, Locale.getDefault(), Charset.defaultCharset());
To get the FileManger, we need
  • diagnostic - A DiagnosticCollector of JavaFileObject
  • locale - The locale of the compilation
  • charset - The charset to be used.

Compiler

Get the compiler instance using ToolProvider. Finally, create the CompilationTask from the compiler instance using diagnostics, file manager and compilation units (Optionally writer and compilation options).
JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
CompilationTask task = compiler.getTask(null, fileManager, diagnostics,
                compilationOptionss, null, compilationUnits);
The argument required to get the CompilationTask are
  • out - A writer which writes the output of the compiler. Defaults to System.err if null 
  • listener - A diagnostic listener, the errors or warning can be accessed using.
  • options - Compiler options (Ex : -d, like we give in command line using javac ) 
  • classes - Name of the classes to be processed 
  • compilationUnits - List of compilation units

Compile

Finally, call the method to compile. This method to be called only once otherwise it throws IllegalStateException on multiple calls. Once compiled, returns true for successful compilation otherwise false. We need to look the diagnosticCollector to get the error/warning details.
boolean status = task.call();

All together

Putting all together.

    public static void main(String[] args)
    {
        String str = "package com.test;"
                + "\n" + "public class Test {"
                + "\npublic static void test() {"
                + "\nSystem.out.println(\"Comiler API Test\")-;" + ""
                        + "\n}" + "\n}";

        SimpleJavaFileObject fileObject = new SampleSource("com.test.Test", str);
        JavaFileObject javaFileObjects[] = new JavaFileObject[] { fileObject };
        Iterable<? extends JavaFileObject> compilationUnits = Arrays
                .asList(javaFileObjects);

        Iterable<String> compilationOptionss = Arrays.asList(new String[] {
                "-d", "classes" });
        
        DiagnosticCollector<JavaFileObject> diagnostics = new DiagnosticCollector<JavaFileObject>();

        JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();

        JavaFileManager fileManager = compiler.getStandardFileManager(
                diagnostics, Locale.getDefault(), Charset.defaultCharset());
        CompilationTask task = compiler.getTask(null, fileManager, diagnostics,
                compilationOptionss, null, compilationUnits);
        boolean status = task.call();
        
        if(!status)
        {
            System.out.println("Found errors in compilation");
            int errors = 1;
            for(Diagnostic diagnostic : diagnostics.getDiagnostics())
            {
                printError(errors, diagnostic);
                errors++;
            }
        }
        else
            System.out.println("Compilation sucessfull");
        
        try
        {
            fileManager.close();
        } catch (IOException e){}

    }
    
    public static void printError(int number,Diagnostic diagnostic)
    {
        System.out.println();
        System.out.print(diagnostic.getKind()+"  : "+number+" Type : "+diagnostic.getMessage(Locale.getDefault()));
        System.out.print(" at column : "+diagnostic.getColumnNumber());
        System.out.println(" Line number : "+diagnostic.getLineNumber());
        System.out.println("Source : "+diagnostic.getSource());
        
    }

Output

Output with an error will be (because of an hyphen in System.out.println in main method of Test)
Found errors in compilation

ERROR  : 1 Type : illegal start of expression at column : 40 Line number : 4
Source : com.test.SampleSource[string:///com/test/Test.java]

ERROR  : 2 Type : not a statement at column : 39 Line number : 4
Source : com.test.SampleSource[string:///com/test/Test.java]
To read more about JSR 199, follow the official link.

Happy Learning!!!!