Thursday, April 30, 2009

Reversing String in Java

This post is about String manipulation. I have provided solutions to some problems/teasers such as how to reverse a String without using the reverse method, how to reverse individual words in a sentence without reversing the sentence and how to reverse a sentence without reversing the words in it. There are many ways to do it and I have presented one or two. It was pure fun doing this exercise.

And remember unless there is a real need to rewrite core functionality don't do it.

import java.util.Stack;
import java.util.StringTokenizer;

public class MyStringTests {

/**
* Reverses word and if a sentence is provided, reverses
* the sentence and all words in the sentence.
* @param s is the input string
* @return the modified string
* eg:
* HELLOO WORLD
* becomes
* DLROW OOLLEH
* eg:
* HELOO becomes
* OOLEH
*/
public static String reverseWord(String s) {
if (s == null || s.length() <= 1) return s;
char[] a = s.toCharArray();
int len = a.length - 1;
char temp;
for(int i = 0, j = len; i <= j; i++,j--) {
temp = a[i];
a[i] = a[j];
a[j] = temp;
}
return new String(a);
}

/**
* Ideal way to reverse a string in Java is to use
* the reverse method of StringBuffer. Unless there
* is a real need to rewrite core functionality don't
* do it.
* @param s is the input string
* @return the modified string
* eg:
* HELLOO WORLD
* becomes
* DLROW OOLLEH
* eg:
* HELOO becomes
* OOLEH
*/
public static String reverseWordUsingReverse(String s) {
if (s == null || s.length() <= 1) return s;
StringBuffer sb = new StringBuffer(s);
return sb.reverse().toString();
}

/**
* Reverses a sentence without reversing individual
* words in it
* @param s is the input string
* @return the modified string
* eg:
* HELLOO WORLD
* becomes
* WORLD HELLO
*/
public static String reverseSentence(String s) {
if (s == null || s.length() <= 1) return s;
StringTokenizer strtok = new StringTokenizer(s);
if (strtok.countTokens() <= 1) return s;
Stack<String> stack = new Stack<String>();
while (strtok.hasMoreTokens()) {
stack.push((String)strtok.nextToken());
}
StringBuffer sb = new StringBuffer();
while (!stack.isEmpty()) {
sb.append(stack.pop());
sb.append(" ");
}
return sb.toString();
}

/**
* Reverses a sentence without reversing individual
* words in it
* @param s is the input string
* @return the modified string
* eg:
* HELLOO WORLD
* becomes
* WORLD HELLO
*/
public static String reverseSentenceUsingSplit(String s) {
if (s == null || s.length() <= 1) return s;
String[] sa = s.split(" ");
if (sa.length <= 1) return s;
StringBuffer newString = new StringBuffer();
for(int i = 0, j = (sa.length - 1); i <= j; i++,j--) {
newString.append(sa[j]).append(" ").append(sa[i]);
}
return newString.toString();
}

/**
* Reverses each word in a sentence but not the
* sentence
* @param s is the input string
* @return the modified string
* eg:
* HELLOO WORLD
* becomes
* OOLLEH DLROW
*/
public static String reverseWordInSentence(String s) {
if (s == null || s.length() <= 1) return s;
StringTokenizer strtok = new StringTokenizer(s);
StringBuffer sb = new StringBuffer();
while (strtok.hasMoreTokens()) {
sb.append(reverseWord(
(String)strtok.nextToken()));
sb.append(" ");
}
return sb.toString();
}


public static void main(String[] args) {
//Test
String s = "HELLOO WORLD";
print(s);
print(reverseWord(s));
print(reverseWordUsingReverse(s));
print(reverseSentence(s));
print(reverseSentenceUsingSplit(s));
print(reverseWordInSentence(s));
}

//Helper print method
public static <T> void print(T s) {
System.out.println(s);
}


}



The output is:
HELLOO WORLD
DLROW OOLLEH
DLROW OOLLEH
WORLD HELLOO
WORLD HELLOO
OOLLEH DLROW

Friday, April 24, 2009

Serializing non-serializable objects using readObject and writeObject

Basic serialization is pretty straightforward, just make the class implement the Serializable interface. Serializable is a marker interface, so pretty much it involves nothing i.e. implementing no methods. Also if one of the super classes of the class is serializable then the class is automatically serializable. Here the basic assumption is that all the member variables of the class are serializable. However that isn't always the case. Class sometimes contains one or more member variables that are not serializable. In such cases, one of the mechanisms to make the class serializable is to do the following:
- Mark the non-serializable fields transient. So these are not saved as part of the object state.
- Implement the following methods in the class:
private void writeObject(ObjectOutputStream out) throws IOException;
private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException;

When the above methods are implemented first call the defaultReadObject/defaultWriteObject to save the state of the serializable member fields and then proceed to read/write the transient variables. Here is an example:

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;

public class MySerializationTest implements Serializable{

private static final long serialVersionUID = 1L;
transient Color color;
int length;

public MySerializationTest(String color, int length) {
this.color = new Color(color);
this.length = length;
}

//Deserialization
private void readObject(ObjectInputStream ois) throws IOException, ClassNotFoundException {
ois.defaultReadObject();
color = new Color((String)ois.readObject());
}

//Serialization
private void writeObject(ObjectOutputStream oos) throws IOException {
oos.defaultWriteObject();
oos.writeObject(color.getColor());
}

@Override
public String toString() {
StringBuffer str = new StringBuffer();
str.append("Color:" + color.getColor());
str.append(" length:" + length);
return str.toString();
}

public static void main(String[] args) throws IOException, ClassNotFoundException {
String filename = "Ser.ser";
MySerializationTest mySer = new MySerializationTest("Green", 20), mySer2;
ObjectOutputStream oos = null;
ObjectInputStream ois = null;
try {
oos = new ObjectOutputStream(new FileOutputStream(filename));
//Write serialized object to file
oos.writeObject(mySer);
ois = new ObjectInputStream(new FileInputStream(filename));
//read the serialized object
mySer2 = (MySerializationTest)ois.readObject();
System.out.println(mySer2);
} finally {
oos.close();
ois.close();
}


}

}

//Non serialized class
class Color {

private String color;

public Color(String color) {
this.color = color;
}

public void setColor(String color) {
this.color = color;
}

public String getColor() {
return color;
}

}


Output:
Color:Green length:20

Tuesday, April 21, 2009

Oracle buys Sun Microsystems

There has been a lot of articles discussing Oracle buying Sun. It was discussed by Michael Krasny in forum yesterday. It was quite good and so I am posting a link to the recording here.

Sunday, April 19, 2009

Interesting article about Google App Engine

Here is a very nice article by Dion Hinchcliffe. In this post, Dion summarizes the offerings and the missing pieces of GAE. If you are interested in cloud computing, specially GAE it is worth reading.

Wednesday, April 15, 2009

Chaining Properties file

In Java, one way of instantiating a Properties object is with Properties(Properties defaults) constructor. The "defaults" parameter allows property files to be stacked together and it is searched only when a particular property is not found. This feature is quite useful during development and testing when we often have conflicting settings. In such cases, editing a single properties file proves to be error-prone and inefficient. Having more than 1 properties file with only properties that need to be different and chaining them together proves to be more safe and easy. Here is an example:

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.Properties;

public class LayeringProperties {

public static final String appPropFile = "Props";
public static final String userPropFile = "UserProperties";

public static void main(String[] args) throws IOException{

try {
//Load application's properties from a file
Properties myProps = new Properties();
myProps.load(new FileInputStream(appPropFile));

//Load the user's properties from a file
Properties userProps = new Properties(myProps);
userProps.load(new FileInputStream(userPropFile));

//List the user properties as key=value pairs
System.out.println("User properties");
userProps.list(System.out);

//List the application's properties
System.out.println("Application properties");
myProps.list(System.out);

} catch (FileNotFoundException fe) {
fe.printStackTrace();
} catch (IOException ie) {
ie.printStackTrace();
}
}
}


Here is the output. Notice how the property value for property "admin.name" is different in the 2 Properties object.
User properties
-- listing properties --
admin.contact=phone email
application.name=My Properties
application.version=1.0
admin.name=akku
Application properties
-- listing properties --
application.name=My Properties
application.version=1.0
admin.name=Kutty

Friday, April 10, 2009

Java support for Google App Engine

On the morning of april 7, 2009, Google announced Java support for App Engine. There is a catch, only a list of core Java classes are supported so there is bound to be a debate about it.

I was very excited to hear this news. Google restricted access to the first 10,000 developers who sign up. I wanted to test drive it so I signed up for an account on 7th evening. I was actually surprised to get my account approved the next day. I thought I was late in signing up but looks like I was not.

I downloaded the AppEngine Java SDK and the Google plugin for Eclipse on my Windows laptop. I am a heavy Eclipse user, so was very happy to see the plugin. I followed the directions for installation and setup. It was pretty straightforward unlike some problems I ran into with the Python App Engine installation and setup on Mac last time. I wanted to do it on my mac but it was indisposed at that time. I went ahead and created a project with a simple servlet as per the instructions, uploaded it to my account and everything worked like a charm.

Google also has a running list of frameworks, lanaguages and libraries which will run on the App Engine. Lot of JVM based languages like Jython, Groovy etc are supported. So now a wider community will embrace Google App Engine.

Friday, April 3, 2009

Tim Bray on what's next in Java Web development

I recently listened to a very interesting podcast on the future of Java Web development by Tim Bray who is the Director of Web Technologies at Sun. Tim Bray talks about cloud computing, concurrency challenges, running dynamic languages like Jython on JVM, REST and other emerging Web technologies.

I think it is a nice podcast and if you are interested in these technologies, you might find the talk interesting too.