Skip to content

Latest commit

 

History

History
448 lines (358 loc) · 10.5 KB

java-snippets.md

File metadata and controls

448 lines (358 loc) · 10.5 KB

Java class file disassembler:

javap -c Foo.class will show the disassembly of Foo.class.


java.io

  • IO Stream is a conceptually endless flow of data.
  • Streams in java.io are either byte based (reading and writing bytes) or character based (reading and writing characters).
  • Summary of main java.io classes:
  Byte Based
Input
Byte Based
Output
Character Based
Input
Character Based
Output
Abstract InputStream OutputStream Reader Writer
Byte/Character bridge InputStreamReader OutputStreamWriter
Arrays ByteArrayInputStream ByteArrayOutputStream CharArrayReader CharArrayWriter
Files FileInputStream
RandomAccessFile
FileOutputStream
RandomAccessFile
FileReader FileWriter
Pipes PipedInputStream PipedOutputStream PipedReader PipedWriter
Buffering BufferedInputStream BufferedOutputStream BufferedReader BufferedWriter
Filtering FilterInputStream FilterOutputStream FilterReader FilterWriter
Parsing PushbackInputStream
StreamTokenizer
PushbackReader
LineNumberReader
Strings StringReader StringWriter
Data DataInputStream DataOutputStream
Formatted Data PrintStream PrintWriter
Objects ObjectInputStream ObjectOutputStream
Utilities SequenceInputStream

Bitwise and Bit Shift operators

Operator Bitwise Operation
~ Unary bitwise complement
<< Signed left shift
>> Signed right shift
>>> Unsigned right shift
& Bitwise AND
| Bitwise inclusive OR
^ Bitwise exclusive OR
AND OR XOR
0 & 0 = 0 0 | 0 = 0 0 ^ 0 = 0
1 & 0 = 0 1 | 0 = 1 1 ^ 0 = 1
0 & 1 = 0 0 | 1 = 1 0 ^ 1 = 1
1 & 1 = 1 1 | 1 = 1 1 ^ 1 = 0
AND OR XOR
x & 0 = 0 x | 0 = x x ^ 0 = x
x & (-1) = x x | (-1) = -1 x ^ (-1) = ~x
x & x = x x | x = x x ^ x = 0
x & (~x) = 0 x | (~x) = 1 x ^ (~x) = 1
  • Left shift:
    (n << s) == n * Math.pow(2, s)

  • Right shifts:

    • the unsigned (or logical) right shift operator >>> inserts a 0 into the leftmost bit (most significant bit):
      -1 >>> 31 == 1
    • the leftmost bit inserted by the signed right shift operator >> depends on sign extension (0 for positive n and 1 for negative n):
      -1 >> 1 == -1
    • the signed right shift operator >> for negative integers is NOT equal to division by 2:
      -3 / 2 = -1, whereas -3 >> 1 = -2
    • if n >= 0:
      (n >> s) == (int)(n / Math.pow(2, s))
      (n >>> s) == (n >> s)
    • if n < 0:
      (n >> s) == Math.floor(n / Math.pow(2, s))
      (n >>> s) == (n >> s) + (2 << ~s)

The 2's Complement

The 2's complement of an N-bit number is the complement with respect to 2N, i.e. the result of subtracting the number from 2N. The 2's complement of a number behaves like the arithmetic negative of the original number.

To calculate the 2's complement of a binary number:

  1. invert the bits by flipping 1s to 0s and 0s to 1s (the unary bitwise complement operation (~), also called 1's complement)
  2. then add 1 (ignoring the overflow)

For example, using 1 byte (8 bits), the 2's complement of 510 = 0000 01012 is 1111 10112 = -510:

  1. ~(0000 0101) = 1111 1010
  2. 1111 1010 + 1 = 1111 1011

The 2's complement of 0 is 0: inverting gives all 1s, and adding 1 changes the 1s back to 0s (since the overflow is ignored).


💾 Memory Usage in Java (on a 64-bit machine).

  • Primitive types:
type bytes
boolean 1
byte 1
char 2
int 4
long 8
float 4
double 8
  • References:
    8 bytes for a memory address (on a 64-bit machine)

  • Objects:
    16 bytes overhead + memory used by each instance variable, padded to a multiple of 8 bytes

    For example, Integer wrapper object:
    24 bytes = 16 bytes overheard + 4 bytes int + padding to a multiple of 8

  • Arrays:
    24 bytes header (16 bytes object overhead + 4 bytes for the length + 4 bytes padding) + memory needed to store the values

type bytes
boolean[] ~N
int[] ~4N
double[] ~8N
  • Strings:
    56 + 2N bytes = 32 bytes (for the String object) + (24 + 2N) bytes (for the char[] array in a string of length N)

  • Linked List node object (inner class):
    48 bytes = 16 bytes object overhead + 8 bytes extra overhead for a reference to the enclosing instance + 2 * 8 bytes for references to next/previous node + 8 bytes reference to a node data


Precedence and associativity of Java operators

Java operators, from highest to lowest precedence, along with their associativity:

Operator Description Level Associativity
[]
.
()
++
--
access array element
access object member
invoke a method
post-increment
post-decrement
1 left to right
++
--
+
-
!
~
pre-increment
pre-decrement
unary plus
unary minus
logical NOT
bitwise NOT
2 right to left
()
new
cast
object creation
3 right to left
*
/
%
multiplicative 4 left to right
+ -
+
additive
string concatenation
5 left to right
<< >>
>>>
shift 6 left to right
< <=
> >=
instanceof
relational
type comparison
7 left to right
==
!=
equality 8 left to right
& bitwise AND 9 left to right
^ bitwise XOR 10 left to right
| bitwise OR 11 left to right
&& conditional AND 12 left to right
|| conditional OR 13 left to right
?: conditional 14 right to left
= += -=
*= /= %=
&= ^= |=
<<= >>= >>>=
assignment 15 right to left

Associativity:

  • x = y = z = 17 is treated as x = (y = (z = 17)), since the = operator has right-to-left associativity.
  • 72 / 2 / 3 is treated as (72 / 2) / 3, since the / operator has left-to-right associativity.

Method Overloading vs. Overriding

  • Method Overloading:

    • Method with same name co-exists in same class, but they must have different method signatures.
    • Resolved using static binding at compile time.
  • Method Overriding:

    • Method with same name and same signature is declared in derived class or sub-class.
    • Resolved using dynamic binding at runtime.
    • Examples: equals(), hashCode(), compareTo().
    • Cannot override static methods (main(), for example) because they are associated with Class rather than Object, and resolved and bonded during compile time. Also, private and final methods cannot be overridden.
    • Good practice is to use @Override annotation.

Implementing equals() and hashCode() override:

public class Person implements Comparable<Person> {

	private String name;
	private int age;

	public Person(String name, int age) {
		this.name = name;
		this.age = age;
	}

	@Override
	public boolean equals(Object y) {
		if (y == this) return true;
		if (y == null) return false;
		if (y.getClass() != this.getClass()) return false;
		Person that = (Person) y;
		return this.name.equals(that.name) && this.age == that.age;
	}

	// satisfies the hashCode contract
	@Override
	public int hashCode() {
		return (31 * name.hashCode() + age);
	}

	@Override
	public String toString() {
		return name + " " + age;
	}

	// impose total ordering, i.e. ordering that is compatible with equals:
	// (a.compareTo(b) == 0) => a.equals(b)
	@Override
	public int compareTo(Person other) {

		// lexicographic ordering:
		int nameComp = name.compareTo(other.name);

		// if names are the same, return in seniority order:
		return (nameComp != 0 ? nameComp
				: (age < other.age ? -1 : (age == other.age ? 0 : 1)));
	}
}

IntegerCache, ShortCache, ByteCache, CharacterCache

The Integer class has a static cache, that stores 256 Integer objects.

Two autoboxing conversions of a primitive value p will yield an identical reference (that is, the == comparison will return true) if p is:

  • Short and Integer from -128 to 127
  • Byte
  • Boolean
  • Character from \u0000 to \u007f (7f is 127 in decimal)

String concatenation:

	a += b

is the equivalent of

	a = new StringBuilder().append(a).append(b).toString();

String's natural ordering:

The successor of a string s in String's natural ordering is s + "\0", which is s with a null character appended.

	String[] wordArray = {"included", "j", "aaa"};
	SortedSet<String> dictionary = new TreeSet<String>(Arrays.asList(wordArray));
	System.out.println(dictionary.subSet("a", "included\0"));

The code above will output: [aaa, included]


Parity test

  • Warning: for negative odd integers (x % 2) == 1 will return false,
    since the remainder will be -1, not 1: (-3 % 2) == -1.
  • Test for "not equal to zero" instead:
	public static boolean isOdd(int x) {
		return (x % 2) != 0;
	}