Here is one approach which you can use sometimes, it will be slower in this artificial example with "#"+..., but main idea could be useful:
private final static String getStrOrNull(final String str) throws Exception {
// first step prepare table for different states:
// 0 - input value is null
// 1 - input value is some not null string
// in single thread application you can move this array out of the function as static variable to avoid memory allocation
final Callable<String>[] func = new Callable[2];
func[0] = new Callable<String>() {
@Override
public String call() {
return null;
}
};
func[1] = new Callable<String>() {
@Override
public String call() {
return str.toLowerCase(); // any other string modification
}
};
// now we need to convert our input variable into "state" (0 or 1)
// to do this we're inserting string into set
// if string is not null - it will be in map, final size will be 1
// if string is null - we will remove it via remove(null), final size will be 0
final Set<String> set = new HashSet<String>();
set.add(str);
set.remove(null);
return func[set.size()].call();
}
here is another method how you can convert input variable into 0 or 1:
int i = System.identityHashCode(str); // returns 0 for null, non zero for all other values, you can also use unsafe getaddr
// converts 0 to 0, any non-zero value to 1:
int b = ((i >>> 16) & 0xffff) | (i & 0xffff);
b = ((b >>> 8) & 0xff) | (b & 0xff);
b = ((b >>> 4) & 0xf) | (b & 0xf);
b = ((b >>> 2) & 0x3) | (b & 0x3);
b = ((b >>> 1) & 0x1) | (b & 0x1);
return func[b].call();
#as prefix and suffix toString? I would suggest you to take both approach and measure performance differenceANY STRING MODIFICATIONis heavy and can save cycles by caching them in map then yes, if it is light then doesn't make huge difference, benchmark bothnullas parameter and do notreturn null