Java Tips, Tricks and Traps

Don't use array as Map's key
- Arrays inherit equals(Object) and hashCode() implementations from java.lang.Object, and they are based on object identity, not array contents
StringBuilder is mutable and does not override the equals(), hashcode(
- So don't use it as the map's key

Set initial size for dynamically expand objects like StringBuilder, ArrayList etc

Java Time API Use java.time.LocalDateTime/ZonedDateTime etc instead of old Date
Use DateTimeFormatter instead of SimpleDateFormate
- As these new classes are thread safe and easier to use.

yyyy-MM-dd, not YYYY-mm-dd ( YYYY is the week-based calendar year)

- is not threadsafe
- is by default lenient
Use ThreadLocal.
- Specify what time zone to use (usually utc), if not set explictly, it uses system default timezone

Explicitly set timezone to utc or specific time zone when use ZonedDateTime

Use ThreadLocalRandom

public interface GenericClass <T> {
  T get();
  void set(T data);

public static <T> T getInstance(T data)
public static <E extends Comparable<E>> E method(E[] a)
public static <E extends Comparable<? super E>> E method(E[] a)
- compile-time construct
- type erasure
- can't create an object of parameter type!
  - new E() doesn't work
- use reflection to create instances of type parameters
-- Class<E> cls, cls.newInstance()
- can't use with instanceof
- can't create arrays of Parameterized Types
- new T[10] doesn't work
- Array contains type info at runtime

animalList = dogList doesn't work
List<Dog> is not a subclass of List<Animal>

animalArray = dogArray works
Array<Dog> is a subclass of Array<Animal>
- arrays knows its element type at runtime>

The Get and Put Principle
use an extends wildcard when you only get values out of a structure, use a super wildcard when you only put values into a structure, and don’t use a wildcard when you both get and put.

public static <T> void copy(List<? super T> dest, List<? extends T> src)
<T extends Comparable<? super T>> void sort(List<T> list)

YourEnum yourEnum = Enum.valueOf(YourEnum.class, value);
Use enum to implement singleton pattern

PriorityQueue maxPQ = new PriorityQueue(size,Collections.reverseOrder());

.sort(ar, Collections.reverseOrder(new XComparator()));
.min/max(collection, comp)

- throw UnsupportedOperationException when try to add/remove elements from the returned list.

List arrayList = new ArrayList(Arrays.asList(arr));
vs List list = Arrays.asList(arr);


Arrays.binarySearch() returns ( - insertion_index - 1) in cases where the element was not found in the array

Arrays.sort(arr, Collections.reverseOrder()); Arrays.toString(array)
- syso(array), prints its address
Arrays.copyOfRange(a, 0, i)
Arrays.copyOf(original, newLength)

Arrays.fill(int[] a,int value) only works for one dimension array
-- it would fail with exception on 2-dimensions arrays - ArrayStoreException: java.lang.Integer

To fill 2-dimensions array:
int[][] target = new int[2][4];
int [] temp = new int[4];
Arrays.fill(temp, -1);
Arrays.fill(target, temp);

StringBuilder/StringBuffer doesn't overwrite equals method. so different sb are different no matter what's the content.
.setCharAt(int, char)
- No toCharArray()

char[] toCharArray()
- No reverse method

Keep only first n elements

list.subList(list.size() - N, list.size()).clear();

descendingIterator, descendingSet
first, last()
pollFirst, pollLast
lower(e), floor

headSet(e), tailSet, subSet
lower(e) - Return the greatest element in this set strictly less than the given element
floor(e) - Return the greatest element in this set less than or equal to the given element

ceiling(e) - Return the least element in this set greater than or equal to the given element
higher(e)  -  Returns the least element in this set strictly greater than the given element.
headSet/tailSet/subSet().size - O(n)

Code: java.util.TreeMap.NavigableSubMap.EntrySetView#size

- O(1) for TreeMap/Set
- O(n) for ArrayList, LinkedList(it clear all elements and links)

- red-black tree
firstEntry, lastEntry
pollFirstEntry() and pollLastEntry()
headMap(), tailMap() and subMap()
ceilingKey(), floorKey(), higherKey() and lowerKey()
ceilingEntry(), floorEntry(), higherEntry() and lowerEntry()

- first, last
- Used when need dedup and make result sorted

You need to escape ' to '' in MessageFormat.
- Cache friendly
- Compact - use less space than LinkedList(double cycle linked list)

- implement hashcode and equals for the key
- getHead: entrySet().iterator().next()
- getTail: O(n) while (iterator.hasNext()) { lastElement = }
Use apache LinkedMap which provides lastKey

Handle your special cases just once

Use ListIterator for ArrayList/LinkedList

Use Optional
- throw exception may be not good, as it forces client either handle it otherwise blown up
- return null is even worse
Using Optional to avoid null checks
Optional.of(new Outer()).map(Outer::getNested).map(Nested::getInner).map(Inner::getFoo).ifPresent(System.out::println);

InterruptedException, isInterrupted
- indication to a thread
- common for the thread to terminate.
Usually Throws InterruptedException when interrupted
- if a thread goes a long time without invoking a method that throws InterruptedException, we can call Thread.interrupted to check whether an interrupt has been received.
if (Thread.interrupted()) {
       throw new InterruptedException();
while (!Thread.interrupted()) {}

catch (InterruptedException e) {
    throw new DifferentException(e);


Group zero denotes the entire pattern
Pattern r = Pattern.compile(pattern);
Matcher m = r.matcher(text);
if (m.find()) {;;


Bytes to string
String s = new String(bytes);
Not String.value(bytes) - this will return the address of the bytes.
- it calls String.value(Object o) method which calls object.toString(). byte[] toString() is the address.

Pass List to varargs parameter
list.toArray(new SomeType[list.size()])
Vararg gotchas
passing an array of primitives
Varargs only works with reference types. Autoboxing does not apply to array of primitives.
ezFormat(new int[]{1}) // not work 

passing null
count(null); // throws java.lang.NullPointerException!!!
count(new Object[] { null }); 
count((Object) null);
adding extra arguments

ezFormat({"A"}, "Z") 

Overwrite javadoc inherited from base class
- Need put @Override after javadoc, otherwise it doesn't work
- {@inheritDoc} to include javadoc from base class
There is no / at the end of tags.
- The javadoc starts with double *: /** - NOT /*

NPE safe

matches vs find
- matches tries to match the expression against the entire string and implicitly add a ^ at the start and $ at the end of your pattern.
.*? - non greedy match
Named capturing group
(? ...)"size")

throw new UnsupportedOperationException(getClass().getSimpleName());

Boolean.valueOf never returns null
- Use BooleanUtils.toBooleanObject instead.
hashCode method may return negative value
Math.abs may return negative value

x/y and x%y rounds to 0
1/3 => 0; -1/3 => 0
Use Math.floorDiv(-1, 3) which will return -1
Collections.contains(Object o)
Same for Map.containsKey(Object o)
// always false as the collection is Collection
Findbugs/Netbeans can show warnings, Eclipse can't.

obj::method != obj::method
Don't use method reference in add/remove related methods.

Collectors.toMap IllegalStateException: Duplicate key
javadocIf the mapped keys contains duplicates (according to Object.equals(Object)), an IllegalStateException is thrown when the collection operation is performed. If the mapped keys may have duplicates, use toMap(Function, Function, BinaryOperator) instead.

Overload vs Override
- Overload is determined at compile type, override is determined at runtime.
- Polymorphism applies to overriding, not to overloading.
- Overriding is a run-time concept while overloading is a compile-time concept.

Ternary expression is more complex than if/else - jls jls2
If one of the second and third operands is of primitive type T, and the type of the other is the result of applying boxing conversion to T, then the type of the conditional expression is T.

Integer a = check? 0 : someMethodWhichMayReturnNull()
This will cause NPE when check is false
over- or underflow
Off-by-one bugs
use == , maybe should use equals

map.getOrDefault(key, 0L)++ doesn't work
Usemap.put(key, 1 + map.getOrDefault(key, 0L));

equals usually check whether type are same
Long l = 0L;
Integer i = 0;
l.equals(i), i.equals(l) // both are false

int mid = low + ((high - low) / 2);
(-10) mod 3 = (3*4 – 10) mod 3 = 2
>> (Signed right shift)

>>> (Unsigned right shift)

JUnit throws AssertionError.
Java would still execute finally even if the block throws Error.

Using Java 8
Post a Comment


Java (161) Lucene-Solr (112) Interview (64) All (58) J2SE (53) Algorithm (45) Soft Skills (39) Eclipse (33) Code Example (31) JavaScript (23) Linux (22) Spring (22) Tools (22) Windows (22) Web Development (20) Nutch2 (18) Bugs (17) Debug (16) Defects (14) Text Mining (14) Troubleshooting (14) J2EE (13) Network (13) Tips (12) PowerShell (11) Chrome (10) Problem Solving (10) Design (9) How to (9) Learning code (9) Performance (9) Security (9) UIMA (9) html (9) Http Client (8) Maven (8) bat (8) blogger (8) Big Data (7) Database (7) Google (7) Guava (7) JSON (7) Shell (7) System Design (7) ANT (6) Coding Skills (6) Lesson Learned (6) Programmer Skills (6) Scala (6) css (6) Algorithm Series (5) Cache (5) Continuous Integration (5) IDE (5) adsense (5) xml (5) AIX (4) Become a Better You (4) Code Quality (4) Concurrency (4) GAE (4) Git (4) Good Programming Practices (4) Jackson (4) Life (4) Memory Usage (4) Miscs (4) OpenNLP (4) Project Managment (4) Review (4) Spark (4) Testing (4) ads (4) regular-expression (4) Android (3) Apache Spark (3) Distributed (3) Dynamic Languages (3) Eclipse RCP (3) English (3) Happy Hacking (3) IBM (3) J2SE Knowledge Series (3) JAX-RS (3) Jetty (3) Mac (3) Python (3) Restful Web Service (3) Script (3) regex (3) seo (3) .Net (2) Android Studio (2) Apache (2) Apache Procrun (2) Architecture (2) Batch (2) Bit Operation (2) Build (2) Building Scalable Web Sites (2) C# (2) C/C++ (2) CSV (2) Career (2) Cassandra (2) Fiddler (2) Google Drive (2) Gson (2) How to Interview (2) Html Parser (2) Http (2) Image Tools (2) JQuery (2) Jersey (2) LDAP (2) Logging (2) Software Issues (2) Storage (2) Text Search (2) xml parser (2) AOP (1) Application Design (1) AspectJ (1) Chrome DevTools (1) Cloud (1) Codility (1) Data Mining (1) Data Structure (1) ExceptionUtils (1) Exif (1) Feature Request (1) FindBugs (1) Firefox (1) Greasemonkey (1) HTML5 (1) Httpd (1) I18N (1) IBM Java Thread Dump Analyzer (1) Invest (1) JDK Source Code (1) JDK8 (1) JMX (1) Lazy Developer (1) Machine Learning (1) Mobile (1) My Plan for 2010 (1) Netbeans (1) Notes (1) Operating System (1) Perl (1) Problems (1) Product Architecture (1) Programming Life (1) Quality (1) Redhat (1) Redis (1) RxJava (1) Solutions logs (1) Team Management (1) Thread Dump Analyzer (1) Visualization (1) boilerpipe (1) htm (1) ongoing (1) procrun (1) rss (1)

Popular Posts