Monday, April 11, 2011

StringBuffer and StringBuilder

StringBuffer and StringBuilder

StringBuffer is used to store character strings that will be changed (String objects cannot be changed). It automatically expands as needed. Related classes: String, CharSequence.

StringBuilder was added in Java 5. It is identical in all respects to StringBuffer except that it is notsynchronized, which means that if multiple threads are accessing it at the same time, there could be trouble. For single-threaded programs, the most common case, avoiding the overhead of synchronization makes the StringBuilder very slightly faster.

No imports are necessary because these are both in the java.lang package.

StringBuffer and StringBuilder methods and constuctors

Assume

StringBuffer sb = new StringBuffer();
StringBuffer sb2;
int i, offset, len;
char c;
String s;
char chararr[];

Constructors

sb =

new StringBuffer();

Creates new, empty, StringBuffer

sb =

new StringBuffer(n);

Creates new StringBuffer of size n

sb =

new StringBuffer(s);

Creates new StringBuffer with initial value s

Building StringBuffer

sb2 =

sb.append(x)

appends x (any primitive or object type) to end of sb.

sb2 =

sb.append(chararr,offset, len)

appends len chars from chararr starting at index offset.

sb2 =

sb.insert(offset, x)

inserts x (char, int, String, ...) at position offset.

sb.setCharAt(index, c)

replaces char at index with c

Deleting from StringBuffer

sb2 =

sb.delete(beg, end)

deletes chars at index beg thru end.

sb.setLength(n)

Sets the length of the content to n by either truncating current content or extending it with the null character ('\u0000'). Use sb.setLength(0); to clear a string buffer.

Extracting from StringBuffer

c =

sb.charAt(i)

char at position i.

s =

sb.substring(start)

substring from position start to end of string.

s =

sb.substring(start, end)

substring from position start to the char before end.

s =

sb.toString()

Returns String.

Searching

i =

sb.indexOf(s)

Returns position of first (leftmost) occurrence of s in sb.

i =

sb.lastIndexOf(s)

Returns position of last (rightmost) occurrence of s in sb.

Misc

i =

sb.length()

length of the string s.

sb2 =

sb.reverse()

reverses the contents.

Converting values

An interesting aspect of the append() and insert() methods is that the parameter may be of any type. These methods are overloaded and will perform the default conversion for all primitive types and will call thetoString() method for all objects.

Chaining calls

Some StringBuffer methods return a StringBuffer value (eg, append(), insert(), ...). In fact, they return the same StringBuffer that was used in the call. This allows chaining of calls. Eg,

sb.append("x = ").append(x).append(", y = ").append(y);

Efficiency of StringBuffer compared to String

Because a StringBuffer object is mutable (it can be changed), there is no need to allocate a new object when modifications are desired. For example, consider a method which duplicates strings the requested number of times.

// Inefficient version using String.
public static String dupl(String s, int times) {
String result = s;
for (int i=1; i result = result + s;
}
return result;
}

If called to duplicate a string 100 times, it would build 99 new String objects, 98 of which it would immediately throw away! Creating new objects is not efficient. A better solution is to use StringBuffer.

// More efficient version using StringBuffer.
public static String dupl(String s, int times) {
StringBuffer result = new StringBuffer(s);
for (int i=1; i result.append(s);
}
return result.toString();
}

This creates only two new objects, the StringBuffer and the final String that is returned. StringBuffer will automatically expand as needed. These expansions are costly however, so it would be better to create the StringBuffer the correct size from the start.

// Much more efficient version using StringBuffer.
public static String dupl(String s, int times) {
StringBuffer result = new StringBuffer(s.length() * times);
for (int i=0; i result.append(s);
}
return result.toString();
}

Because this StringBuffer is created with the correct capacity, it will never have to expand. There is no constructor which allows both an initial capacity to be specifed and an initial string value. Therefore the loop has one extra iteration in it to give the correct number of repetitions.

Copyleft 2004 Fred Swartz MIT License

Final Classes in Java(tm)

Final Classes in Java(tm)

In Java, a class organization such as:

class A {}

class B extends A {}

results in a superclass (A) and a subclass (B). References to B objects may be assigned to A references, and if an A reference "really" refers to a B, then B's methods will be called in preference to A's. All of this is a standard part of the object-oriented programming paradigm offered by Java.

But there is a way to modify this type of organization, by declaring a class to be final. If I say:

final class A {}

then that means that A cannot be further extended or subclassed.

This feature has a couple of big implications. One is that it allows control over a class, so that no one can subclass the class and possibly introduce anomalous behavior. For example, java.lang.String is a final class. This means, for example, that I can't subclass String and provide my own length() method that does something very different from returning the string length.

There is also a big performance issue with final classes. If a class is final, then all of its methods are implicitly final as well, that is, the method is guaranteed not be overridden in any subclass. A Java compiler may be able to inline a final method. For example, this program:

final class A {
private int type;
public int getType() {return type;}
}

public class test {
public static void main(String args[])
{
int N = 5000000;
int i = N;
int t = 0;
A aref = new A();
while (i-- > 0)
t = aref.getType();
}
}

runs about twice as fast when the class is declared final.

Of course, much of the time it's desirable to use the superclass / subclass paradigm to the full, and not worry about wringing out the last bit of speed. But sometimes you have heavily used methods that you'd like to have expanded inline, and a final class is one way of achieving that.

Friday, April 1, 2011

What is serialVersionUID?

What is serialVersionUID?

August 6, 2009 - Author: Miron Sadziak

Most people learn about serialVersionUID after they write their first serializable object (I know I did). You add ‘implements Serializable’ and in the next moment your IDE starts complaining… so what’s up?

Lets look at a simple example to see what meaning that variable has. In the example we will use the class SerializeMe shown below:

1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:

class SerializeMe implements Serializable {
private static final long serialVersionUID = 1L;

private int data;

public SerializeMe (int data) {
this.data = data;
}

public int getData() {
return data;
}
}

Field data represents some information stored in the class. Class implements the Serializable interface, so my IDE automatically offered me to declare the serialVersionUID field. Lets start with value 1 set there.

We will also need some class that will serialize and deserialize the SerializeMe class. Here it is:

1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:

public class UIDTester {
public static void main(String... strings) throws Exception {
File file = new File("out.ser");
FileOutputStream fos = new FileOutputStream(file);
ObjectOutputStream oos = new ObjectOutputStream(fos);

SerializeMe serializeMe = new SerializeMe(1);
oos.writeObject(serializeMe);
oos.close();

FileInputStream fis = new FileInputStream(file);
ObjectInputStream ois = new ObjectInputStream(fis);

SerializeMe dto = (SerializeMe) ois.readObject();
System.out.println("data : " + dto.getData());
ois.close();
}
}

This code will serialize an instance of class SerializeMe to a file and then deserialize it back. Now let’s run the main function! You should get output that says:

data : 1

It means that our object was properly serialized and deserialized. Note that the file “out.ser” was created on disk and it is still there even after the program finished. Let’s see if we can read that file once again, this time without creating it first. To do that, comment out lines from 4 to 9 in the UIDTester class:

1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:

public class UIDTester {
public static void main(String... strings) throws Exception {
File file = new File("out.ser");
//FileOutputStream fos = new FileOutputStream(file);
//ObjectOutputStream oos = new ObjectOutputStream(fos);

//SerializeMe serializeMe = new SerializeMe(1);
//oos.writeObject(serializeMe);
//oos.close();

FileInputStream fis = new FileInputStream(file);
ObjectInputStream ois = new ObjectInputStream(fis);

SerializeMe dto = (SerializeMe) ois.readObject();
System.out.println("data : " + dto.getData());
ois.close();
}
}

This way, the main method starts right away with reading the file from the disk and deserializing data stored in it. As the file is exactly the same and our class didn’t changed either, we should get exactly the same output:

data : 1

Now, let’s see what happens, when we change the serialVersionUID value and try to deserialize once again our file. Change the line 2 in the class SerializeMe so that serialVersionUID contains now 2 instead of 1:

2:

private static final long serialVersionUID = 2L;

Now let’s run again our program (just like one step before, with commented out lines writing the file). We should get an exception like this:

Exception in thread "main" java.io.InvalidClassException:
SerializeMe; local class incompatible: stream classdesc
serialVersionUID = 1, local class serialVersionUID = 2

As you can see, this time the deserialization didn’t go well. ObjectInputStream complained about the serialVersionUID being changed. How does he know that it changed? If serialVersinUID is static, then it should not have been serialized in the first place, and there should be no information about the previous value 1 during the deserialization, right? Well, serialVersionUID is an exception to the rule that “static fields don’t get serialized”. ObjectOutputStream writes every time the value of serialVersionUID to the output stream. ObjectInputStream reads it back and if the value read from the stream does not agree with the serialVersionUID value in the current version of the class, then it throws the InvalidClassException. Moreover, if there is no serialVersionUID officially declared in the class to be serialized, compiler automatically adds it with a value generated based on the fields declared in the class.

So what is it for after all? Let’s suppose that there is some file storing a serialized object of some class A. The deserialization of that object does not necessarily have to occur exactly after serialization. It can occur after a few months or on a completely different JVM (i.e. sending an object through net using serialization). In both cases, there is a chance that the class declaration has changed between serialization and deserialization. It would be nice to have some kind of versioning system for every serializable class – and serialVersionUID does exactly that. It checks if the data read from the input stream is compatible with the current definition of the class.

If so, then why is it recommended to specify your own serialVersionUID ? It gives us simply more control. Default rules for generating serialVersionUID can be too strict in some cases. For example when the visibility of a field changes, the serialVersionUID changes too. Value generated automatically can differ between various Java implementations. There is a chance that some object serialized on one Java implementation will not deserialize on some other Java implementation, even if the class definition is exactly the same. Furthermore, sometimes you just want for some reason to forbid deserialization of old serialized objects, and in this case you just have to change the serialVersionUID.

Now that you know that specifying your own serialVersionUID is recommended, you might tend to write it once for every serializable class ( or have it generated by the IDE ) and forget about it. WRONG !!! If you write it once and don’t take care to update it when necessary, you loose all the merits of serialVersionUID. All your classes will get deserialized without exceptions even when using outdated data. What you should do is to change serialVersionUID (for example increase it by 1 or make your IDE generate automatically a new value) every time there is some change in the definition of data stored in the class. For example if you change data types, variable names or add new data – hence every time you want to have ‘backward incompatibility’ for deserialization.

Pasted from <http://www.javablogging.com/what-is-serialversionuid/comment-page-1/>

123passportphoto is a very easy to use passport photo website that provides six enhanced photos. I have never had an issue while using this ...