Show TOC Start of Content Area

Background documentation Build-In Types (java.lang)  Locate the document in its SAP Library structure

Strings

Concatenation

Strings are easy to use in Java because they have a built-in concatenation operation and are thread-safe due to their immutability. This advantage can also become a major bottleneck.

The string concatenation operator + is a convenient way to combine a few strings into one. It is easy to use for generating a single line of output or for constructing the string representation of a small, fixed-size object. Unfortunately the immutability has some significant side effects:

·         For every concatenation a new string instance has to be created (creating garbage objects).

·         All characters, not only those that are added, have to be copied to the new string. This leads to quadratic complexity when concatenating in a loop.

Example: Consider the following method that constructs a string representation of a statement by concatenating a line for every item:

     public String statement() {
        String s = 
"";
        
int n = numItems();
        
for (int i =  0; i < lines; i++) {
          s += lineForItem(i);
        }
        
return s;
     }

 

This kind of implementation will have to perform copy-character operations during the creation of a result string s of length n. Therefore the method performs very badly with a large number of items. By concatenating the strings using a StringBuffer the complexity is reduced to just n:

     public String statement() {
        
final int n = numItems();
        
final StringBuffer s new StringBuffer(n * ESTIMATED_LINE_WIDTH);
        
for (int i = 0; i < n; i++) {
           s.
append(lineForItem(i));
        }
        
return s.toString();
     }

 

Process documentation

The JLin rule String Concatenation will find improper use of the string concatenation operator in your source code.

Creation

It is not necessary to create new string instances explicitly (new String(“text”)), except in some very rare cases where equal strings are considered different when they belong to different objects (the == operator is used for comparison).

Process documentation

The JLin rule String Creation will find places where strings are explicitly instantiated.

 

Accessing Individual Characters

The method substring extracts arbitrary character sequences from a string. To extract a single character though, the method charAt() should be used.

Process documentation

The JLin rule Substringwill look for method substring() where charAt() is more appropriate.

 

Arrays

Arrays have the advantage to be type-safe but have the following disadvantages:

·        There is no contains() method.

·        Arrays do not allow to insert or delete elements.

·        Arrays are not embedded in the collections framework.

·        Arrays cannot be write-protected.

By the way - type safety can also be achieved by type safe wrappers and by Java Generics in the future.

Example:

     StringTokenizer tokenizer = new StringTokenizer(poolIDs, ", ");
     String[] ids = 
new String[tokenizer.countTokens()];
     
for (int i = 0; tokenizer.hasMoreTokens(); i++) {
        ids[i] = tokenizer.nextToken();
     }
     
for(int i = 0; i < ids.length; i++) {
        addEntryToList(ids[i]); 
     }

 

In this example the only purpose of array ids is to allow iteration-by-index idiom. Here is an alternative:

     StringTokenizer tokenizer = new StringTokenizer(poolIDs, "");
     
for (int i = 0; tokenizer.hasMoreTokens(); i++) {
        addEntryToList(tokenizer.nextToken());
     }

 

Object Class

The root class Objectrepresents the basic infrastructure of the Java object model. Descended classes inherit the following methods:

·        Identitiy concept: equals

·        Support for hash codes: hashCode

·        String representation: toString

·        Duplication: clone

See book Effective Java [1] for more details and examples.

 

The equals() Method and Object Identity

The equals() method determines if two objects are equivalent. The identity concept is used to distinguish keys in maps and to avoid duplication of elements in sets. Also the containment checks of most utility classes are based on the implementation of the equals method.

As a side effect the implementation of the equals method is a hot-spot whenever the Java Collection Classes or other container classes are used. Performance is the key for the implementation of equals.

Use the following recommendations to obtain a fast implementation of the method:

·        Check first for identical objects using == and return early.

·        Use the hash-code to detect differing objects early (requires fast implementation with cached hash-codes).

·        Compare attributes with high chance to differ (broad range) first.

·        Compare attributes of basic types (==) first.

·         

Note

The default implementation of equals returns true only for the same instance (x == y).

 

Example:

The following class represents a position in a text (like a bookmark). It will offer superior performance because it will return early for x.equals(x) and compares the fields first that are most likely to differ. In this case rows are more likely to be different because there are usually more rows than columns in a text.

     public class Position {
        
private int _row, _col;
        …
        
public boolean equals(final Object o) {
          
if(o == this) {  // succeed early
              
return true;
          }
          
final p = (Position) o;
          
return (_row == p._row) && (_col == p._col);
        }
     }

 

The hashCode() Method

The hash-code support of Java objects goes hand in hand with the identity concept. There is a logical relationship between the behavior of the equals method and the hashCode method.

 

Recommendation

Equal objects have equal hash codes.

For implementations of the hashCode and the equals method the following holds true:

"x,y of object type

(1)   x.equals(y)                Þ x.hashCode() == y.hashCode()

(2)       x.hashCode()!=y.hashCode() Þ !x.equals(y)

 

Statement (2) is the conclusion from (1).

 

The hashCode method is often used in classes that manage groups of objects, like the following:

·        HashMap and LinkedHashMap

·        Hashtable

·        Properties

·        HashSet

Hash codes are the quickest way to lookup objects.

 

Note

The default implementation of hashCode corresponds to the default equals implementation and therefore returns different values for different object instances.

 

Process documentation

The JLin rule Equals/Hash Code Test shows inconsistent implementations.

 

End of Content Area