Showing posts with label Java. Show all posts
Showing posts with label Java. Show all posts

Saturday, 3 January 2015

How to check whether String class is mutable or immutable programmatically in java

We can use hashCode() to check whether two string object have same hash code.
In this example, we have created a new String class object with value "Mutable".
Later, we have used  replace() to change the string str and resulting value is updated in str reference variable.
Now, if previous hashcode for str is equal to new hash code for str, then String class will be mutable otherwise it will be immutable.

public class StringMutable
{
    public static void main(String[] args)
{
String str = new String("Mutable");
int previousStrHashCode = str.hashCode();
str = str.replace('u', 'a');  // A new string object is created
int newHashCode = str.hashCode(); //  a new String object will have a new hashcode
System.out.println("prev "+previousStrHashCode + "   new : "+newHashCode );
if(previousStrHashCode == newHashCode)
{
System.out.println("Mutable");
}
else
{
System.out.println("Immutable");
}
}
}

Output:
prev -1216934138   new : -1789517158
Immutable

Here, hash code is different for string object before modification and after modification. Hence, a new object was created created instead of updating the previous String object.
This proves that String class is immutable. 



Equals and hascode method in java

Example of equals and hashcode method in java


This document explains :Why equals and hashcode methods are require and how to implement them.

If you want to use a class as a key in MAP/SET, provide proper hashcode() and equals() method implementation for that class.

Reason: If you don't provide implementation for these  methods class will inherit these from superclass implementation of these methods(generally Object class) and map/set may behave incorrectly.
Lets’ take an example of employee class

Employee.java

public class Employee
{
       String employeeId;
       enum EmpType{FULLTIME, PARTTIME, INTERN};
       String type;
       String joiningYear;
      
       public Employee(String empId, String type, String jy)
       {
              this.employeeId = empId;
              this.type = type;
              this.joiningYear = jy;
       }
      
       public void show()
       {
              System.out.println("Employee ID : "+employeeId + "  Employee Type "+ type+" joining year  "+joiningYear);
       }
      
       @Override
       public String toString()
       {
              return employeeId + "  "+type + "   "+joiningYear;
       }
}


 MainClass1.java

import java.util.HashMap;
import java.util.Map;
public class MainClass1 {
                public static void main(String[] args)
                {
                                Map<Employee,Float> map = new HashMap<Employee, Float>();
                                Employee e1 = new Employee("Mayank Sharma", EmpType.FULLTIME.toString(), "2013");
                                Employee e2 = new Employee("Nikhil Kumar", EmpType.INTERN.toString(), "2014");
                                Employee e3 = new Employee("Love Sharma", EmpType.PARTTIME.toString(), "2013");               
                                Employee e4 = new Employee("Kapil Kumar", EmpType.FULLTIME.toString(), "2002");                                   Employee e5 = new Employee("Neeraj Panwar", EmpType.INTERN.toString(), "2014");
                                Employee e6 = new Employee("David Buther", EmpType.PARTTIME.toString(), "2011");
                                Employee e7 = new Employee("David Buther", EmpType.PARTTIME.toString(), "2011");
                                map.put(e1, (float) 500000);
                                map.put(e2, (float) 50000);
                                map.put(e3, (float) 400000);
                                map.put(e4, (float) 1500000);
                                map.put(e5, (float) 50000);
                                map.put(e6, (float) 80000);
                                map.put(e7, (float) 90000);
                                for(Employee employee: map.keySet())
                                {
                                                employee.show();
                                                System.out.println(map.get(employee));
                                }
                }
}

Output:

Employee ID : David Buther  Employee Type PARTTIME joining year  2011
90000.0
Employee ID : Neeraj Panwar  Employee Type INTERN joining year  2014
50000.0
Employee ID : Kapil Kumar  Employee Type FULLTIME joining year  2002
1500000.0
Employee ID : Nikhil Kumar  Employee Type INTERN joining year  2014
50000.0
Employee ID : Love Sharma  Employee Type PARTTIME joining year  2013
400000.0
Employee ID : David Buther  Employee Type PARTTIME joining year  2011
80000.0
Employee ID : Mayank Sharma  Employee Type FULLTIME joining year  2013
500000.0

Here object “e7” and “e6” have same hash code, but e7 should have override the e6 but map contains both e6 and e7 which shows that but e6 and e7 should be same since they have same value set.

Now override equals method in Employee class:
       @Override
       public boolean equals(Object o)
       {
              if(o == this)
                     return true;
              if(!(o instanceof Employee1))
              {
                     return false;
              }
              Employee1 employee1 = (Employee1)o;
              return this.employeeId.equals(employee1.employeeId)
                     && this.type.equals(employee1.type)
                     && this.joiningYear.equals(employee1.joiningYear);
       }

Add try to run the same program.
You will get same output. It is because hashcode() is not overridden in employee class and we are using the same previous hashcode which says that two different object will have same hashcode.
Now lets, override the hashcode() in Employee class :
       @Override
       public int hashCode()
       {
              return 42;
       }

All the objects have same hash code, so they all will added in a particular entry of linked list and hence form a linked list.
Now run the program.
Wow. You will get the desired output.
Output:

Employee ID : Mayank Sharma  Employee Type FULLTIME joining year  2013
500000.0
Employee ID : Nikhil Kumar  Employee Type INTERN joining year  2014
50000.0
Employee ID : Love Sharma  Employee Type PARTTIME joining year  2013
400000.0
Employee ID : Kapil Kumar  Employee Type FULLTIME joining year  2002
1500000.0
Employee ID : Neeraj Panwar  Employee Type INTERN joining year  2014
50000.0
Employee ID : David Buther  Employee Type PARTTIME joining year  2011
90000.0
There is no duplicate entry for employee with employee name : David Buther
You can provide following implementation of hashcode for better performance:
       @Override
       public int hashCode()
       {
              int result  =17;
              result = 31* result + employeeId.hashCode();
              result = 31*result +  type.hashCode() ;
              result = result* 31 +joiningYear.hashCode();
              return result;
       }

This method avoid collision and final map will not looks like a linked list as in the previous case.
Where the equals and hashcode methods are use?
Let’s take the HashMap put method implementation:
    public V put(K key, V value) {
        if (table == EMPTY_TABLE) {
            inflateTable(threshold);
        }
        if (key == null)
            return putForNullKey(value);
        int hash = hash(key);
        int i = indexFor(hash, table.length);
        for (Entry<K,V> e = table[i]; e != null; e = e.next) {
            Object k;
            if (e.hash == hash && ((k = e.key) == key || key.equals(k))) {
                V oldValue = e.value;
                e.value = value;
                e.recordAccess(this);
                return oldValue;
            }
        }

        modCount++;
        addEntry(hash, key, value, i);
        return null;
    }

And here is the implementation of hash() :

    final int hash(Object k) {
        int h = hashSeed;
        if (0 != h && k instanceof String) {
            return sun.misc.Hashing.stringHash32((String) k);
        }

        h ^= k.hashCode();

        // This function ensures that hashCodes that differ only by
        // constant multiples at each bit position have a bounded
        // number of collisions (approximately 8 at default load factor).
        h ^= (h >>> 20) ^ (h >>> 12);
        return h ^ (h >>> 7) ^ (h >>> 4);
    }





Processing SQL Statements with JDBC

Processing SQL Statements with JDBC


We have to follow following steps in any SQL statement with JDBC:

1. Establishing a connection.
2. Create a statement.
3. Execute the query.
4. Process the ResultSet object.
5. Close the connection.

1. Establishing Connections
Establish a connection with the data source you want to use.
A data source can be a DBMS, a legacy file system, or some other source of data with a corresponding JDBC driver.
This connection is represented by a Connection object.

2. Creating Statements
A Statement is an interface that represents a SQL statement.
You execute Statement objects and they generate ResultSet objects which is a table of data representing a database result set.
You need a Connection object to create a Statement object.

There are three different kinds of statements:
Statement: Used to implement simple SQL statements with no parameters.
PreparedStatement: (Extends Statement.) Used for precompiling SQL statements that might contain input parameters.
CallableStatement: (Extends PreparedStatement.) Used to execute stored procedures that may contain both input and output parameters.


3.Executing Queries
To execute a query, call an execute method from Statement such as the following:

execute: Returns true if the first object that the query returns is a ResultSet object. Use this method if the query could return one or more ResultSet objects. Retrieve the ResultSet objects returned from the query by repeatedly calling Statement.getResultSet.
executeQuery: Returns one ResultSet object.
executeUpdate: Returns an integer representing the number of rows affected by the SQL statement. Use this method if you are using INSERT, DELETE, or UPDATE SQL statements.

4. Processing ResultSet Objects

You access the data in a ResultSet object through a cursor.
This cursor is a pointer that points to one row of data in the ResultSet object.
Initially, the cursor is positioned before the first row. You call various methods defined in the ResultSet object to move the cursor.

5. Closing Connections
When you are finished using a Statement, call the method Statement.close to immediately release the resources it is using.
When you call this method, its ResultSet objects are closed.

Example:

    public void doSqlQuery(String query)
    {

    Statement stmt = null;
    try
{
            stmt = con.createStatement();
            ResultSet rs = stmt.executeQuery(query);
            while (rs.next())
            {
                String name= rs.getString("name");
                int ID = rs.getInt("ID");
                float price = rs.getFloat("PRICE");
            }
         }
         catch (SQLException e )
         {
             e.printStackTrace();
         }
         finally
         {
             if (stmt != null)
             {
                 stmt.close();
             }
         }
      }


Prepared Statement:

The Prepared Statement is a slightly more powerful version of a Statement, and should always be at least as quick and easy to handle as a Statement.
The Prepared Statement may be parametrized Most relational databases handles a JDBC / SQL query in four steps:
1.Parse the incoming SQL query
2. Compile the SQL query
3. Plan/optimize the data acquisition path
4. Execute the optimized query / acquire and return data

A Statement will always proceed through the four steps above for each SQL query sent to the database.
A Prepared Statement pre-executes steps (1) - (3) in the execution process above. Thus, when creating a Prepared Statement some pre-optimization is performed immediately. The effect is to lessen the load on the database engine at execution time.

Advantages of a Prepared Statement:


1. Precompilation and DB-side caching of the SQL statement leads to overall faster execution and the ability to reuse the same SQL statement in batches.

2. Automatic prevention of SQL injection attacks by builtin escaping of quotes and other special characters.


Why do we use connection pool:
Reason :Creating a new database connection is very costly.

Explanation:
Think about the amount of memory being allocated per DB Connection. What things must be allocated? According to MySQL 5.0 Certification Study Guide, page 357:
The server maintains several buffers for each client connection. One is used as a communications buffer for exchanging information with the client. Other buffers are maintained per client for reading tables and performing join and sort operations.
What settings govern the per-connection buffers?
join_buffer_size
sort_buffer_size
read_buffer_size
read_rnd_buffer_size
tmp_table_size / max_heap_table_size
net_buffer_length / max_allowed_packet
thread_stack
It takes time to allocate and deallocate these buffers when a connection comes into being. Don't forget to multiple the sum of those values by max_connections. As a side note, please refrain from usingmysql_pconnect as PHP and MySQL's persistent connections do not get along well. Here are two informative links on this topic:
Open bug on PHP Not Cleanly Closing MySQL Connections on Apache Death.
Requesting a Persistent ssh Connection.
In heavy-read, heavy-write environment, such as OLTP, this would be expensive in terms of RAM usage and possible inhibition due to swapping in the OS. On a low-write, low_read website, I would not worry as much.

for above terms use link : http://dev.mysql.com/doc/refman/5.5/en/server-system-variables.html#sysvar_join_buffer_size

The process of handshake spanning across multiple machines (if your db server is hosted over the network) which takes place on creating (establishing) a new connection makes it expensive. Thats why its recommended to use a connection pool, or in your case the session. This could include host lookup, initial connection, and subsequent control commands.

Checked v/s unchecked exception

Exception in java:there are three types of Exceptions:

1. Checked Exception
2. Unchecked Exception
3. Error


Checked Exception:
These are exceptional conditions that a well-written application should anticipate and recover from.
All exceptions directly inherited from Exception class are checked exception.
Please note: checked Exception is not concerned with compiler time.
We can only get compile time error and not compile time exception.

For example: FileNotFoundException: it can possible that user have entered a wrong name: possibility to enter correct name.
  
Unchecked Exception:These are exceptional conditions that are internal to the application, and that the application usually cannot anticipate or recover from.
These usually indicate programming bugs, such as logic errors or improper use of an API.
Example: NullPointerException: Let say we want to call a function for from object.But let say object is not initialized, we should not initialized that object because it can be possible that reference is of interface and it may be inherited by n number of classes/ interface.Now which implementation to initialize, how to decide that.

Error:These are exceptional conditions that are external to the application, and that the application usually cannot anticipate or recover from.
Example: OutOfMemoryException .If JVM memory get overflow, what a programmer can do... there is no way to recover.

The Java compiler forces you to either catch checked exceptions or declare them in the method signature. It was supposed to improve program safety.

Keep in mind:
java.lang.Exception is referred to as "Checked Exception"
java.lang.RuntimeException is referred to as "Unchecked Exception"

Tuesday, 13 May 2014

Using Log4j on Eclipse

Log4j is a Reliable, Fast and Flexible Logging Framework (APIs) written in Java which is distributed under the Apache Software License.


What do you require to use log4j in eclipse project : apache-logging-log4j.jar (http://logging.apache.org/log4j/1.2/download.html )

You will get zip file for the jar. Unzip and save tge jar file in a directory and import the jar file in project.
Right click on the project and click properties.
Now click on java build path and click on Add External jars.
Add the external jar for the log4j logging.
Now you wizard should looks like this.(must have apache-logging-log4j.jar entry)





Java Files
1. StudentActivities.java

package firstLog;

import org.apache.log4j.Logger;

public class StudentActivities
{
static Logger log = Logger.getLogger(StudentActivities.class);
public void takeadmission()
{
log.info("Student has taken admission");
firstYear();
}
private void firstYear()
{
log.info("student in first year");
secondYear();
}

private void secondYear()
{
log.info("student ins second year");
thirdYear();
}

private void thirdYear()
{
log.info("student in third year");
fourthYear();
}

private void fourthYear()
{
log.info("student in fourth year");
professional();
}

private void professional()
{
log.info("Now he is a professional");
}
}

2. Run.java

// Using JUnit to run the program (can be replaced by a class with main method)

package firstLog;

import org.junit.Test;

public class Run
{
@Test
public void testStudentActivities()
{
StudentActivities studentActivities = new StudentActivities(); 
studentActivities.takeadmission();
}

}


3. log4j.properties (should be in project's src folder)


# This sets the global logging level and specifies the appenders
log4j.rootLogger=INFO, theConsoleAppender, FILE

# settings for the console appender
log4j.appender.theConsoleAppender=org.apache.log4j.ConsoleAppender
log4j.appender.theConsoleAppender.layout=org.apache.log4j.PatternLayout
log4j.appender.theConsoleAppender.layout.ConversionPattern=%-4r [%t] %-5p %c %x - %m%n
log4j.appender.FILE=org.apache.log4j.RollingFileAppender
log4j.appender.FILE.File=logs/log.txt
log4j.appender.FILE.layout=org.apache.log4j.PatternLayout
log4j.appender.FILE.layout.conversionPattern=%m%n

log4j.appender.FILE.Append=true

Now project explorer should looks like this:



Run the program and you can see the logs in /logs/log.txt

Hope this helps you :)



Thursday, 17 April 2014

Static Import

Static import
Introduced in  Java 5
Import statement was enhanced to provide greater keystroke-reduction capabilities.
 Static import is use when you want to access Class static members.
Example:
File: First.java
import static staticImport.Second.*;

public class First
{
       public static void main(String[] args)
       {
              System.out.println(firstVar);
              printfirstVar();
       }

}

File : Second.java

public class Second
{
              final static int  firstVar= 34;
             
              static void printfirstVar()
              {
                     System.out.println(firstVar);
              }
}

Output:
34
34

Problem:
Ambiguity of static members:
If we import from two classes which use same static variables then compiler will in ambiguity to decide which variable class variable to use.


Example:
File:First.java

import static staticImport.Second.*;
import static staticImport.Third.*;

public class First
{
       public static void main(String[] args)
       {
              System.out.println(firstVar);         // Error since compile not able to decide which firstVar we want to use, either of Second.java or Third.java
             

printfirstVar();                   // Error: reason is same as above
       }

}

File: second.java
public class Second
{
       final static int  firstVar= 34;
             
       static void printfirstVar()
       {
              System.out.println(firstVar);
       }
}

File: Third.java
public class Third
{
       final static int  firstVar= 34;
      
       static void printfirstVar()
       {
              System.out.println(firstVar);
       }
}