Java Cheatsheet
This cheatsheet will focus on Java 17.
Resources
References:
- Java 17 Documentation
(docs.oracle.com)
- Learn X in Y minutes - Java
(learnxinyminutes.com)
General Basics and Gotchas
import java.security.*; // Imports everything from the `java.security` package
assert foo > 0; // Must enable assertions to work, e.g. `$ java -ea MyFile.java`
try {
throw new RuntimeException("lmao");
} catch (Exception e) {
System.out.println(e);
} finally {
System.out.println("finally");
}
// IMMUTABLE Record
record Foo(int a, String b){};
final var tmp = new Foo(123, "kekekek");
tmp.a; // Both fields are readable
tmp.hashCode(); // Hashable!
public class HelloWorld {
public static void main(String[] args) {
System.out.println("Hello, World!");
}
}
public class Foo {
public int a;
public String b;
public Foo(int a, String b) {
this.a = a;
this.b = b;
}
}
public class ClosureExample {
interface Closure {
public String run(String a);
}
public static void main(String[] args) {
final var s = "xd";
final var closure = new Closure() {
public String run(String a) {
return a + " lmao " + s;
}
};
System.out.println(closure.run("ayy")); // Prints "ayy lmao xd"
}
}
Java has no operator overloading. The ==
operator will compare references, leading to weird bugs like:
final var lst = new ArrayList<Integer>(Arrays.asList(1, 1, 10000, 10000));
// WRONG. DON'T DO THIS.
System.out.println(lst.get(0) == lst.get(1)); // Prints "true"
System.out.println(lst.get(2) == lst.get(3)); // Prints "false"
// (Due to underlying implementation details, `==` may *seem* to work under certain edge cases.)
// Correct way
System.out.println(lst.get(0).equals(lst.get(1))); // Prints "true"
System.out.println(lst.get(2).equals(lst.get(3))); // Prints "true"
System.out.println(lst.get(1).equals(lst.get(2))); // Prints "false"
Also, notice how we had to use ArrayList<Integer>
. Java doesn’t support using primitive types as generic arguments, so you can’t do ArrayList<int>
.
Common Types
Boxed Types
In many cases, the compiler implicitly converts between primitive and boxed types.
// TODO: Do you need to know anything specific?
StringBuilder
(TODO: Talk a little bit about the motivation?)
Java 17 Documentation - Class StringBuilder
import java.lang.StringBuilder;
final var buf = new StringBuilder("ayy lmao");
buf.append('a');
buf.append((char) 0x61); // Appends lower-case 'a'
buf.append("foobar");
buf.toString(); // Returns the contents as a String
// TODO: Add more notes on other methods?
// (I'm kinda rushing rn, so I'm not going unnecessarily in-depth.)
Array
(Fixed-Size Array)
Java 17 Documentation - Class Array
Java 17 Documentation - Class Arrays
import java.util.Comparator;
import java.util.Arrays;
int[] arr = new int[10];
int[][] arr = new int[10][5]; // Can be nested
int[] arr = {123, 321, 456, 654};
Integer[] arr4 = {22, 33, 44, 55};
// TODO: how to do literal 2D arrays?
System.out.println(arr[0]); // First element
arr.length; // --> int (I think?)
for (int v : arr) System.out.println(v);
// There isn't anything like Python's enumerate(), so you may need to:
for (int i = 0; i < arr.length; ++i) {
System.out.println(i);
System.out.println(arr[i]);
}
// Sort by natural ordering in ascending order
Arrays.sort(arr);
// Sort with comparator using lambda syntax
String[] arr = {"ada", "bbc", "ccd", "aaa", "aea"};
Arrays.sort(arr,
(var a, var b) -> ((Character) a.charAt(1)).compareTo(b.charAt(1))
);
// Becomes ["aaa", "bbc", "ccd", "ada", "aea"]
// Usually, it's better to use compareTo() if it's available,
// but you can also implement the comparison yourself:
Arrays.sort(arr,
(var a, var b) -> a.charAt(1) - b.charAt(1)
);
// Another alternative version using an anonymous class:
Arrays.sort(arr, new Comparator<String>() {
@Override
public int compare(String a, String b) {
if (a.charAt(1) > b.charAt(1)) return 1;
if (a.charAt(1) < b.charAt(1)) return -1;
return 0;
}
});
Binary search:
final int[] arr = {10, 20, 30, 40, 50, 60};
Arrays.binarySearch(arr, 30); // Returns 2
Arrays.binarySearch(arr, 31); // Returns -4. Insertion point is (-(-4) - 1) = 3
Arrays.binarySearch(arr, 29); // Returns -3. Insertion point is (-(-3) - 1) = 2
// Negative values indicate that the value doesn't exist.
// Value represents the insertion point:
// insertion_point = -returned_value - 1
arr.add(2, 29); // Array becomes [10, 20, 29, 30, 40, 50, 60]
// You can also use a comparator: Arrays.binarySearch(arr, key, comparator)
List
/ ArrayList
(Dynamic Array)
Java 17 Documentation - Class ArrayList
Java 17 Documentation - Interface List
Java 17 Documentation - Class Collectors
Java 17 Documentation - Class Collections
import java.util.List;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.stream.Collectors;
import java.util.Collections;
// Constructor accepts any Collection
final var lst = new ArrayList<Integer>(collection);
// Hardcoding
final var lst = new ArrayList<Integer>(Arrays.asList(123, 321, 456, 654));
// Convert `int[]` to `List<Integer>`
final List<Integer> lst = Arrays.stream(arr).boxed().toList(); // IMMUTABLE
final ArrayList<Integer> lst = Arrays.stream(arr).boxed()
.collect(Collectors.toCollection(ArrayList::new)); // MUTABLE
// Convert `Integer[]` to `List<Integer>`
final var lst = new ArrayList<Integer>(Arrays.asList(arr));
lst.size(); // --> int
for (int v : lst) System.out.println(v);
// There isn't anything like Python's enumerate(), so you may need to:
for (int i = 0; i < lst.size(); ++i) {
System.out.println(i);
System.out.println(lst.get(i));
}
// Push/pop/peek at the back
lst.add(x);
lst.remove(lst.size() - 1); // --> popped element
lst.get(lst.size() - 1); // --> peeked element
// Push/pop/peek at the front
lst.add(0, x);
lst.remove(0); // --> popped element
lst.get(0); // --> peeked element
lst.sort(null); // Pass in null to sort by natural ordering.
lst.sort((var a, var b) -> b.compareTo(a)); // Pass in a comparator. (This one reverses the order.)
// See Array notes for more ways to pass a comparator.
Binary search:
final var lst = new ArrayList<Integer>(Arrays.asList(10, 20, 30, 40, 50, 60));
Collections.binarySearch(lst, 30); // Returns 2
Collections.binarySearch(lst, 31); // Returns -4. Insertion point is (-(-4) - 1) = 3
Collections.binarySearch(lst, 29); // Returns -3. Insertion point is (-(-3) - 1) = 2
// Negative values indicate that the value doesn't exist.
// Value represents the insertion point:
// insertion_point = -returned_value - 1
lst.add(2, 29); // List becomes [10, 20, 29, 30, 40, 50, 60]
// You can also use a comparator: Collections.binarySearch(lst, key, comparator)
Map
/ HashMap
Java 17 Documentation - Class HashMap
Java 17 Documentation - Interface Map
import java.util.Map;
import java.util.HashMap;
// Hardcoded IMMUTABLE map
final Map<Integer, String> map = Map.ofEntries(
Map.entry(234, "alice"),
Map.entry(432, "bob"),
Map.entry(567, "mallory"),
);
// Hardcoded IMMUTABLE map, less-verbose, but only works up to 10 entries.
final Map<Integer, String> map = Map.of(
234, "alice",
432, "bob",
567, "mallory",
);
// MUTABLE map, usually better to call `.put()` repeatedly.
final HashMap<Integer, String> map = new HashMap();
map.put(234, "alice");
map.put(432, "bob");
map.put(567, "mallory");
map.size(); // --> int
for (var x : map.entrySet()) System.out.println(x.getKey() + " : " + x.getValue());
for (var k : map.keySet()) System.out.println(k); // Keys only
for (var v : map.values()) System.out.println(v); // Values only
map.put(k, v); // Replaces old values if they exist
map.remove(k); // Returns the associated value, or null if it doesn't exist
map.clear();
map.containsKey(k); // --> true if key exists
map.containsValue(v); // --> true if v appears at least once as a value.
map.get(k); // Returns null if key doesn't exist
map.getOrDefault(k, defaultval); // Returns defaultval if key doesn't exist
Extracting keys:
// To a fixed-size array
K[] arr = new K[map.size()];
arr = map.keySet().toArray(arr);
// To List/Set (MUTABLE)
// (Both constructors take Collection. keySet() returns Set, which extends Collection.)
final List<K> lst = new ArrayList(map.keySet());
final Set<K> set = new HashSet(map.keySet());
Extracting values:
// To a fixed-size array
V[] arr = new V[map.size()];
arr = map.values().toArray(arr);
// To List/Set (MUTABLE)
// (Both constructors take Collection. values() returns Collection.)
final List<V> lst = new ArrayList(map.values());
final Set<V> set = new HashSet(map.values());
Set
/ HashSet
Java 17 Documentation - Class HashSet
Java 17 Documentation - Interface Set
import java.util.Set;
import java.util.HashSet;
import java.util.Arrays;
import java.util.stream.Collectors;
// Constructor accepts any Collection
final var set = new HashSet<Integer>(collection);
// Hardcoding
final var set = new HashSet<Integer>(Arrays.asList(123, 321, 456, 654));
// Convert `int[]` to `Set<Integer>`
final HashSet<Integer> set = Arrays.stream(arr).boxed()
.collect(Collectors.toCollection(HashSet::new)); // MUTABLE
// Convert `Integer[]` to `Set<Integer>`
final var set = new HashSet<Integer>(Arrays.asList(arr));
set.size(); // --> int
for (int v : set) System.out.println(v);
set.add(v); // Returns true if a new item was added.
set.remove(v); // Returns true an item was removed. (Silently "fails".)
set.clear();
set.contains(v); // --> bool
Deque
/ ArrayDeque
Java 17 Documentation - Class ArrayDeque
Java 17 Documentation - Interface Deque
import java.util.Deque;
import java.util.ArrayDeque;
// Constructor accepts any Collection
final var dq = new ArrayDeque<Integer>(collection);
// Hardcoding
final var dq = new ArrayDeque<Integer>(Arrays.asList(123, 321, 456, 654));
// TODO: Do I need to also add conversions with fixed-size arrays?
// The other sections already have plenty of examples.
// The constructor already accepts a Collection.
dq.size(); // Returns int
dq.isEmpty(); // Returns boolean
for (int v : dq) System.out.println(v);
dq.addLast(v); // Meant to throw an exception if capacity exceeded, but ArrayDeque grows automatically.
dq.addFirst(v); // ^
dq.removeLast(); // Pop. Throws exception if deque is empty.
dq.removeFirst(); // ^
dq.getLast(); // Peek. Throws exception if deque is empty.
dq.getFirst(); // ^
dq.offerLast(v); // Returns true if the element was added successfully.
dq.offerFirst(v); // ^
dq.pollLast(); // Pop. Returns null if deque is empty.
dq.pollFirst(); // ^
dq.peekLast(); // Peek. Returns null if deque is empty.
dq.peekFirst(); // ^
Queue
Java 17 Documentation - Interface Queue
import java.util.Queue;
import java.util.ArrayDeque;
// See ArrayDeque notes for more on the constructor.
final Queue<Integer> q = new ArrayDeque<Integer>();
q.size(); // Returns int
q.isEmpty(); // Returns boolean
for (int v : q) System.out.println(v);
q.add(v); // Equivalent to Deque addLast()
q.remove(); // Equivalent to Deque removeFirst()
q.element(); // Equivalent to Deque getFirst()
q.offer(v); // Equivalent to Deque offerLast()
q.poll(); // Equivalent to Deque pollFirst()
q.peek(); // Equivalent to Deque peekFirst()
PriorityQueue
By default (when you don’t supply a Comparator
), PriorityQueue
is a min-priority-queue, following natural ordering.
Java 17 Documentation - Class PriorityQueue
import java.util.PriorityQueue;
// Constructor accepts any Collection
final var q = new PriorityQueue<Integer>(collection);
// Hardcoding
final var q1 = new PriorityQueue<Integer>(Arrays.asList(7, 3, 6, 4, 1, 5));
// (Reading out the result:)
while (!q1.isEmpty()) System.out.println(q1.remove()); // Prints in order: 1, 3, 4, 5, 6, 7
// Constructing with a custom Comparator.
// Constructor can't take both a Comparator and Collection, so call add() repeatedly as needed.
// See Array sort() notes for more ways to pass a comparator.
final var q2 = new PriorityQueue<Integer>(
(var a, var b) -> b.compareTo(a)
);
q2.add(7);
q2.add(2);
q2.add(5);
q2.add(6);
// (Reading out the result:)
while (!q2.isEmpty()) System.out.println(q2.remove()); // Prints in order: 7, 6, 5, 2
// PriorityQueue implements the Queue interface.
// Refer to the Queue notes for the API.