#1. You can use Optional instead of simply returning null in some specific cases:
Insted of:/** * Can return null in specific cases... but it's * hard to remember */ public static String someMethod() { String returnValue = null; if (new Date().getTime() % 2 == 0) { returnValue = "time % 2 == 0"; } return returnValue; } public static void main(String[] args) { String str = someMethod(); str.contains("%") // will crash }use this:
/** * Explicite shows, that method can * return empty (null) value */ public static Optional< String > someMethod() { Optional< String > returnValue = Optional.absent(); if (new Date().getTime() % 2 == 0) { returnValue = Optional.of(new String()); } return returnValue; } public static void main(String[] args) { Optional< String > str = someMethod(); if(str.isPresent()) { // here you know that value is not null } // or you can operate on given value or a default one str.or("default value").contains("%"); }
#2 You can use firstNonNull from Guavas Objects class insted of write "if else"
Insted of:public T foo() { ... ... if(first != null) { return first; } else { return second; } }use this:
import static com.google.common.base.Objects.firstNonNull; ... public T foo() { ... ... return firstNonNull(first, second); }
#3 You can use Guava Strings class methods to deal with null or empty Strings
Insted of:if(str == null) { str = ""; } if("".equals(str)) { str = null; } if(str == null || str.length() == 0) { // is null or empty }use this:
import static com.google.common.base.Strings.*; str = nullToEmpty(str); str = emptyToNull(str); if(isNullOrEmpty(str)) { // is null or empty }
#4 You can use Object.equals(a, b) to check equality safely
Insted of:a.equals(b); // will crash if a is nulluse this:
import static com.google.common.base.Objects.equal; ... equal(a, null); // return false equal(null, null); // return true equal(a, b); // return true if a is equal b
#5 You can use Joiner to join Strings
Insted of:StringBuffer buffer = new StringBuffer(); for (String str : strs) { if (str != null) { buffer.append(str); buffer.append(", "); } } if (buffer.length() >= 2) { buffer.substring(0, buffer.length() - 2); } return buffer.toString();use this:
import com.google.common.base.Joiner; ... return Joiner.on(", ").skipNulls().join(strs);
#6 You can use Splitter to split String
Insted of:String str = "abc, bcd,, cde ,zsa"; String[] split = str.split(","); // What with trimming? Whitespaces? Empty strings???use this:
import com.google.common.base.Splitter; ... Splitter.on(',') .trimResults() .omitEmptyStrings() .split("abc, bcd,, cde ,zsa");
#7 You can use Multiset to count object occurences
Insted of:Map< String, Integer > countMap = new HashMap< String, Integer >(); for (String word : words) { if(!countMap.containsKey(word)) { countMap.put(word, 0); } countMap.put(word, countMap.get(word) + 1); }use this:
import com.google.common.collect.HashMultiset; import com.google.common.collect.Multiset; ... Multiset< String > wordsMultiset = HashMultiset.create(); wordsMultiset.addAll(words);
#8 You can use Multimap insted of map with List or Set as values
Insted of:Map< String, List< String > > languagesMap = new HashMap< String, List< String >>(); for (Programmer programmer : programmers) { if (languagesMap.get(programmer.getLanguage()) != null) { languagesMap.put(programmer.getLanguage(), new ArrayList< String >()); } languagesMap.get(programmer.getLanguage()).add(programmer.getEmail()); }use this:
import com.google.common.collect.HashMultimap; import com.google.common.collect.Multimap; ... Multimap< String, String > languagesMap = HashMultimap.create(); for (Programmer programmer : programmers) { languagesMap.put(programmer.getLanguage(), programmer.getEmail()); }
...next simple, but usable examples soon...
This comment has been removed by the author.
ReplyDeleteI am puzzled as to why you think that this has anything to do with the size of a project. In fact, libraries such as these (Apache Commons Lang comes to mind) keeps your codebase focussed on business logic and not utility functions such as these.
DeleteVery odd. They fit perfectly in any size project! We're happily using some of these Guava patterns in a very very large deployment...
DeleteGoogle Guava is developed and used by Google themselves on their Java projects (that's how it was born).
DeleteIn large projects, a common error that is thrown is NullPointerException, which can be avoided by using the above techniques.
Waiting for description of full opportunities.
ReplyDeleteBest patterns framework. I have used Apache Commons before but this is more elegant.
ReplyDeleteabout Arash comment really what are you smoking?, This patterns are used by Google what could be more big deployments than that?.
Unfortunately firstNotNull does not work the way you've described. This unfortunate method works following way:
ReplyDeleteif(first != null) {
return first;
} else if(second != null)
return second;
} else {
throw new NullPointerException(); // yup, it's THAT counter-intuitive.
}
Try it with firstNotNull(null, null) to check.
Some time ago I started some discussion about it, I wasn't the only one pointing out it's useless, but guava devs know better.
Line 3 of your non guava multimap example has a bug. It should check that it equals null rather than not equals.
ReplyDeleteNice examples. Thanks for sharing!
ReplyDelete