Tuesday, January 8, 2013

Best Practice: String concatenation with Java


Introduction:
Exercise extra caution when choosing a technique for string concatenation in Java™ programs. Simply using the "+=" operator to concatenate two strings creates a large number of temporary Java objects, since the Java String object is immutable. This can lead to poor performance (higher CPU utilization) since the garbage collector has additional objects to collect. Use the Java StringBuffer object to concatenate strings because it is more efficient.

Recommendation:
String concatenation using the "+" operator creates many temporary objects and increases garbage collection. Using the StringBuffer class is more efficient.The servlet code sample shows how this can be implemented. Lab tests have shown up to a 2.3X times increase in throughput using StringBuffer class over the immutable String class.
The StringBuffer class represents a mutable string of characters. Unlike the String class, it can process text in place. Instead of the "+=" operator, the StringBuffer uses the append method, as shown below:
                    
res.setContentType("text/HTML");
PrintWriter out = res.getWriter();
String aStudent = "James Bond";
String aGrade = "A";
StringBuffer strBuf = new StringBuffer();
strBuf.append(aStudent);
strBuf.append("received a grade of");
strBuf.append(aGrade);
System.out.println (strBuf);

Alternative
The String class is created by the Java compiler when it encounters characters contained within double quotes in an object. The String class is immutable; there are no methods provided that allow you to manipulate the contents of the string once it is created. Methods that operate on a string return a new string not an updated copy of the old one.
You can concatenate a string to create a dynamic string of data to be used in a println statement. In this example, several additional String objects are created. The "+=" operator is used to concatenate strings in this servlet example:
String typical_string;
Res.setContentType("text/HTML");
PrintWriter out = res.getWriter();
String aStudent = "James Bond";
String aGrade = "A";
typical_string += aStudent;
typical_string += "received a grade of ";
typical_string += aGrade;
System.out.println (typical_string);



Monday, December 31, 2012

SoftHashMap - hashmap with soft values


The biggest problem with WeakHashMap is, it will only weakly reference the keys but not the values. This may lead to memory issues if we are using weakhashmap as a cache.

We can try this!!



import java.lang.ref.ReferenceQueue;
import java.lang.ref.SoftReference;
import java.util.AbstractMap;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.Map;
import java.util.Set;



public class SoftHashMap<K, V> extends AbstractMap<K, V> {

/** The internal HashMap that will hold the SoftReference. */
private final Map<K, SoftValue<V>> hash = new HashMap<K, SoftValue<V>>();

/** The number of "hard" references to hold internally. */
private final int HARD_SIZE;

/** The FIFO list of hard references, order of last access. */
private final LinkedList<V> hardCache = new LinkedList<V>();

/** Reference queue for cleared SoftReference objects. */
private final ReferenceQueue queue = new ReferenceQueue();

public SoftHashMap() {
this(150);
}

public SoftHashMap(int hardSize) {
HARD_SIZE = hardSize;
}

public V get(Object key) {
V result = null;
// We get the SoftReference represented by that key
SoftReference<V> soft_ref = hash.get(key);
if (soft_ref != null) {
// From the SoftReference we get the value, which can be
// null if it was not in the map, or it was removed in
// the processQueue() method defined below
result = soft_ref.get();
if (result == null) {
// If the value has been garbage collected, remove the
// entry from the HashMap.
hash.remove(key);
} else {
// We now add this object to the beginning of the hard
// reference queue. One reference can occur more than
// once, because lookups of the FIFO queue are slow, so
// we don't want to search through it each time to remove
// duplicates.
hardCache.addFirst(result);
if (hardCache.size() > HARD_SIZE) {
// Remove the last entry if list longer than HARD_SIZE
hardCache.removeLast();
}
}
}
return result;
}

/**
* We define our own subclass of SoftReference which contains not only the
* value but also the key to make it easier to find the entry in the HashMap
* after it's been garbage collected.
*/
private static class SoftValue<V> extends SoftReference<V> {
private final Object key; // always make data member final

private SoftValue(V obj, Object key, ReferenceQueue queue) {
super(obj, queue);
this.key = key;
}
}

/**
* Here we go through the ReferenceQueue and remove garbage collected
* SoftValue objects from the HashMap by looking them up using the
* SoftValue.key data member.
*/
private void processQueue() {
SoftValue sv;
while ((sv = (SoftValue) queue.poll()) != null) {
hash.remove(sv.key); // we can access private data!
}
}

/**
* Here we put the key, value pair into the HashMap using a SoftValue
* object.
*/
public V put(K key, V value) {
processQueue(); // throw out garbage collected values first
SoftValue<V> softValue = new SoftValue<V>(value, key, queue);
SoftValue<V> put = hash.put(key, softValue);
if (put != null) {
return put.get();
}
return null;
}

public V remove(Object key) {
processQueue(); // throw out garbage collected values first
SoftValue<V> remove = hash.remove(key);
if (remove != null)  {
return remove.get();
}
return null;
}

public void clear() {
hardCache.clear();
processQueue(); // throw out garbage collected values
hash.clear();
}

public int size() {
processQueue(); // throw out garbage collected values first
return hash.size();
}

public Set entrySet() {
throw new UnsupportedOperationException();
}
}

Eclipse author ${user} variable



Here is a small “hack” which can put anything you want in this ${user} variable.

Add one more variable in the eclipse.ini file with the following.
-vmargs 
-Duser.name="your name here..." 

or
Rather than having to change the template manually, add 
-vmargs -Duser.name="your name here" to the shortcut you use to run Eclipse ( by right clicking on it, selecting properties and editing the target input field) :
C:/java/eclipse/eclipse.exe -vmargs -Duser.name="your name here.."

Sunday, December 30, 2012

Force overwrite on git pull

How do I force an overwrite of local files on a git pull?


git fetch --all
git reset --hard origin/master
git fetch downloads the latest from remote without trying to merge or rebase anything. 
Then thegit reset resets the master branch to what you just fetched

Thursday, December 27, 2012

Image decorator






Here is the simple snippet to add a decorator to the image.



@Override
public Image getImage(Object element) {


if (resource instanceof Column)
{
 return decorateImage(SImageRegistry.getImage(SImageConstants.column), element);
}

}


public Image decorateImage(Image image, Object element) {
if (element instanceof Column) {
if (((Column) element).isPrimaryKeyPart()) {
DecorationOverlayIcon decorationOverlayIcon = new DecorationOverlayIcon(image,
SImageRegistry.getImageDescriptor(SImageConstants.primary_key), IDecoration.TOP_LEFT);
return decorationOverlayIcon.createImage();
}
return image;
}
return null;
}

Wednesday, December 5, 2012

Increase heap size to your eclipse

Here is the example to specify the eclipse vm arguments in eclipse.ini file to avoid eclipse memory issues during your development.

-startup
plugins/org.eclipse.equinox.launcher_1.0.100.v20080501.jar
--launcher.library
plugins/org.eclipse.equinox.launcher.gtk.linux.x86_64_1.0.100.v20080428-1330
-showsplash
org.eclipse.platform
-vm
/usr/lib/jvm/java-1.5.0-sun/jre/bin/java
-vmargs
-Xms512m
-Xmx1024m
-XX:+UseParallelGC
-XX:PermSize=512M
-XX:MaxPermSize=1024M

If you are working with eclipse plug-in development, while launching your eclipse application you have to specify the vm arguments so that it will be available for your target platform as well.
Please find the screenshot below to configure it.









Wednesday, November 28, 2012

Collections emptyList()

Can you guess the output for the below program ?
import java.util.Collections;
import java.util.List;

public class CollectionsTest {

private List<String> pool = Collections.<String> emptyList();

public List<String> call1() {
pool.add("Hello");
return pool;
}

public static void main(String[] args) {
CollectionsTest collectionsTest = new CollectionsTest();
List<String> call1 = collectionsTest.call1();
System.out.println(call1);
call1.add("one more added..");
System.out.println(call1);
}
}


Output:

Exception in thread "main" java.lang.UnsupportedOperationException
at java.util.AbstractList.add(AbstractList.java:131)
at java.util.AbstractList.add(AbstractList.java:91)
at CollectionsTest.call1(CollectionsTest.java:9)
at CollectionsTest.main(CollectionsTest.java:15)


In short:
Collections.emptyList() returns an immutable list, i.e., a list to which you cannot add or remove elements.

Then, why should we use at all ? What is the purpose of this ?


Best Regards,
Kondal Kolipaka