Java Programming Tips
Convert char to int
1 | char c = '9'; |
1 | char c = '9'; |
Add zeros at the beginning of a number
1 | int i = 640; |
1 | 00640 |
Print an array
1 | int[] a = {1,2,3,4,5,6}; |
Fill an array
Use Arrays.fill(array, val)
to assign values to an array.
1 | int[] a = new int[10]; |
1 | [7, 7, 7, 7, 7, 7, 7, 7, 7, 7] |
Convert between string and char array
1 | char[] arr = {'h', 'e', 'l', 'l', 'o', ' ', 'w', 'o', 'r', 'l', 'd'}; |
Convert integer to string
1 | String s1 = String.valueOf(i); |
Parse integer from string
Do not forget to catch the possible exception thrown by parseInt()
. parseInt()
ignores leading zeros.
1 | try { |
1 | int i = Integer.parseInt("000015640", 10); // 15640 |
Default initialization of an array in Java
Everything in a Java program not explicitly set to something by the programmer, is initialized to a zero value.
- For references (anything that holds an object) that is
null
. - For int/short/byte/long that is a
0
. - For float/double that is a
0.0
- For booleans that is a
false
. - For char that is the null character
'\u0000'
(whose decimal equivalent is 0).
Initialize the capacity of a List
1 | List<Integer> list = new ArrayList<>(10); |
In this line of code, we initialize an array list with initial capacity of 10. Note that 10 is its capacity, not its size. So we still need to add elements one by one to this list. Assessing directly without adding any elements, such as directly calling list.get(1)
, will cause out-of-bound exceptions.
Reverse a List
1 | Collections.reverse(list); |
Create a List from an array
Take the return of Array.asList()
as the parameter of ArrayList
constructor.
1 | int[] array = new int[10]; |
Sort
- Primitive array:
Arrays.sort(arr)
- Object array:
Arrays.sort(integerArr, comparator)
- List:
Collections.sort(list, comparator)
1 | int[] arr = new int[]{4, 1, 5, 4, 4, 0, 6, 1, 9}; |
Traverse a map
Use Map.Entry
or HashMap.Entry
.
1 | HashMap<Integer, Integer> hashMap = new HashMap<>(); |
isLetter() and isAlphabetic()
isLetter()
and isAlphabetic()
are two methods of Character
. The difference between them is:
isAlphabetic()
checksUPPERCASE_LETTER && LOWERCASE_LETTER && TITLECASE_LETTER && MODIFIER_LETTER && OTHER_LETTER && LETTER_NUMBER
.isLetter()
checksUPPERCASE_LETTER && LOWERCASE_LETTER && TITLECASE_LETTER && MODIFIER_LETTER && OTHER_LETTER
.
The point is that isLetter()
will return false
given a letter number. For example, roman numeral five (the letter looks like “V”). Certainly, for the English language, the distinction makes no difference.
Use Deque over Stack for LIFO stacks
We should use Deque
rather than Stack
for LIFO stacks.
1 | Deque<Integer> dstack = new ArrayDeque<>(); |
There are many reasons to prefer Deque
:
Deque
is an interface butStack
is a class. So usingDeque
brings us more flexibility for future extension.Stack
is synchronized butDeque
is not thread-safe. In the case of no need to ensure thread safety,Deque
is more efficient.Deque
iterates elements from top to bottom.Stack
iterates elements from bottom to top.- Most important: with
Stack
, we can access/insert/remove arbitrary elements in the LIFO stack by indexes,stack.get(index); stack.add(index, e); stack.remove(index)
, which breaks the LIFO rule. AlthoughDeque
does not absolutely obey the LIFO rule, it can only access/insert/remove the first/last element in the LIFO stack.
Print multi-dimensional arrays
1 | System.out.println(Arrays.toString(arr)); // print a 1D array |
Get ceiling/floor value of a number
1 | double ceilingValue = Math.ceil(3.1); // 4.0 |
Note that these twoMath
functions return double
. Or if we need to get the ceiling value of a fraction X/Y
, we can also do as the following:
1 | int res = (X + Y - 1) / Y; |
Sort an array/list
- Primitive array
int[]
:Arrays.sort
- Objective array
Integer[]
:Arrays.sort
and optional comparator - Objective list
List<Integer>
:Collections.sort
and optional comparator
1 | int[] arr = new int[]{4, 1, 5, 4, 4, 0, 6, 1, 9}; |
Common time complexity calculation
$$
\sum_{1}^{n}{k^2}=\frac{1}{n}{n(n+1)(2n+1)}=O(n^3)\
\sum_{1}^{n}{k^3}=(\frac{1}{2}{n(n+1)})^2=O(n^4)
$$
String manipulation
1 | StringBuilder builder1 = new StringBuilder("abcdefg"); |
toCharArray()
and getBytes()
toCharArray()
is better if we are not dealing with characters outside of the Unicode BMP, which are encoded as two surrogate characters. getBytes()
needs to specify encoding, which is prone to mistakes. Also, toCharArray()
is faster because for Java 7 and newer, a String
object contains a char
array internally. toCharArray()
just need to complete a copy operation.
Integer object comparison
For two Integer
objects, ==
compares their references while <
and >
compare their values. To examinate whether they have the same value, we should use equals()
or unbox them by intValue()
.
And, it is safe to use comparison operators (==
, <
, >
) for comparing values between an int
and an Integer
object.
1 | Integer i1 = new Integer(15640); |
1 | i1 == i2 : false |
substring()
substring(beginIndex, endIndex)
returns the substring in [beginIndex, endIndex)
. And it is safe for beginIndex == endIndex == 0 or length
.
1 | String s = "hello"; |
indexOf()
s.indexOf(pattern, fromIndex)
returns the first index of given pattern from fromIndex
(inclusive). If such pattern does not exist, it returns -1
.
abstract
keyword
If a class is declared abstract, it means that this class may be partially implementd. Thus, Java does not allow us to instantiate an abstract class. An abstract class can implement its constructor, functions (abstract or non-abstract) and have its variables.
An abstract function cannot have body. Any classes that declare any abstract functions must also be declared abstract. Any non-abstract classes that inherit abstract functions must implement all of them.
1 | static abstract class Node { |
Immutable objects
String
and all primitive wrapper classes (Integer
, Double
, Long
, Character
, etc.) are immutable.
Inner class and nested class
An instance of inner class can exist only within an instance of its outerClass. The instance of the inner class has direct access to the methods and fields of its outer instance. A nested class can access all static resources of its outer class.
The difference between inner class and nested class is straightforward. Inner class has non-static features. Nested class has static features.
1 | public class TestInnerNested { |
Round a float number to n decimal places
Use DecimalFormat
.
1 | DecimalFormat df = new DecimalFormat("#.####"); |
Traverse key-value pairs in a map
Use nested class Map.Entry<>
.
1 | Map<Integer, String> map = new HashMap<>(); |
assert
keyword
Do Not use assert
in test. They can be activated at run-time by way of the -ea
option on the java
command, but are not turned on by default.
Split a string into at most 2 pieces
1 | String[] arr = str.split(" ", 2); |
Difference between Exception
and RuntimeException
Any exception that derives from Exception
is a checked exception. If a function throws an Exception
in its body, it should also declare this behavior in this function declaration. Whereas a class that derives from RuntimeException is un-checked. RuntimeException
s do not need to be explicitly handled by the calling code.
Generally RuntimeException
s are exceptions that can be prevented programmatically.
floorEntry()
and lowerEntry()
of TreeMap
floorEntry(key)
gets the entry corresponding to the specified key; if no such entry exists, returns the entry for the greatest key less than the specified key; if no such entry exists, returns null.
lowerEntry(key)
returns the entry for the greatest key less than the specified key; if no such entry exists (i.e., the least key in the Tree is greater than the specified key), returns null.
Using a custom class as a key
To use a custom class as a key in Java Map, the custom class must define its equals
and hashCode
methods. Though Java provides an implicit implementation of these two methods for every class, the default implementation may lead to unexpected behaviors of Map (such as failing to find an existing key when inquiring with a new object with the same fields).
1 |
|
Shift
Signed shift: <<
, >>
Unsigned shift: <<<
, >>>