TIPS String.format(“%.2f”, float) -> Format float to 2 dp (Round) - 0 IS NOT THE SAME AS false - Implicit casting happens for expression evaluation as well. Eg: 5 + 5.5 + 8L [will implicitly cast to float] - Java has 4 logical operators (NOT, AND, OR, XOR) = (!, &&, ||, ^) - Float values can store HUGE numbers, or store decimals up to 6 decimal places. - Double values can store HUGE numbers, or store decimals up to 15 decimal places. - false && true (short circuit false), true || false (short circuit true) - Chars are implicitly casted to integers. If you want to retrieve the char value instead of an integer value, you need to explicitly cast to char. Eg: ‘a’ + 5 = 102 (char)(‘a’ + 5) = ‘f’ - Java has signed numbers by default (the most significant bit determines the sign) therefore the cap of a numeric primitive type is calculated as follows: 2^(bits - 1) - 1 Primitive (Value) Types By assigning a primitive type to a primitive type, you are copying a value to it By assigning a reference type to a reference type, you are copying the ADDRESS of the reference to it. Primitive values are stored on the stack Reference addresses are stored on the stack Reference data is stored on the heap Byte Short Char Int Long Float Double (1 byte) (2 bytes) (2 bytes) (4 bytes) (8 bytes) (4 bytes) (8 bytes) Any reference variable can be assigned NULL. However, try to avoid this as much as possible. Implicit Casting When storing a value in a byte, and then storing the same value in a short, the type of the value is cast to (short) implicitly! As the diagram shows implicit type casting only works when you go from a smaller type range to a larger type range AND NOT BACKWARDS. Since float values are stored in powers of 10, they can store way larger values than long or int BUT at the cost of precision. Information Loss Sometimes when casting int to float or long to float or to double some less significant bits of the value may be lost (due to floating point values being stored differently) Explicit Casting When the source data type can store larger values than the target data type, explicit casting is required. Char c = (char) 97L Which follows the pattern (targetType) value Explicit casting may cause type overflow where you try to cast from a larger value to a smaller one and huge loss of data occurs. Strings - Are IMMUTABLE REFERENCE TYPES in Java. ALWAYS COMPARE REF TYPES USING a.equals(b). If you were to use `==` you would compare their addresses instead of their values. - Can be indexed with .charAt() - Adding values of different types to a string will automatically convert them to string format - .split in Java uses regex. Therefore some characters that have meaning in regex need to be escaped like so: \\[charValue] Array If you want utility functions like array to string or sorting an array, import Arrays - Arrays.copyOf (Deep copy of array) - Arrays.equals (Check if both arrays contain the same elements in the same order) - Arrays are fixed size containers, storing elements of the same type sequentially. IntStream.range(start, end).ToArray() can be used to create integer arrays from ranges. - By passing an array as an argument, a copy of the reference is sent. Therefore, any changes made in the function will change the actual data on the heap the reference points to - When initializing an empty array, the elements are initialized to the default value of the type the array holds. Eg: Int[] array = new Int[5]; (stores {0, 0, 0, 0, 0}, since the default value for int is 0) Functions - The varargs syntax can be used to specify an arbitrary number of function parameters. Eg: sum(int …numbers) The values are stored in an array with its name set to the parameter type given. - You can pass 0 or more varargs - Varargs can also be passed as an array instead of individual values Packages A package is a java file within a folder. The file must contain package [nameOfFolder] for the package to be imported in other files. To import a package, use import packageName.fileName - If classes are in the same package you can use them without imports - If they are not, you need to import them or use their long names (not recommended) Access Modifiers Top-level modifiers: [Default] Package-private (Visible only to classes in the same package) Public (Visible to all classes) Low-level modifiers: Private (Visible only to current class) Protected (Visible only to classes in same package and classes which inherit from it [including ones in other packages]) Inheritance You can store a subclass object into a superclass type: Mammal cat = new Cat(); But you will only have access to the fields defined in Mammal This is mainly useful when you want to build a method for the object and its subclasses. Eg: Public void printName(Employee e) {} // Can be passed Clerk, Manager, etc (As long as they inherit from Employee)… Object ALL classes inherit from the Object class. ALL reference types inherit the following methods from Object: Clone is super useful, creates a deep copy of any ref. - Object.getClass() is useful for retrieving classes Interfaces Variable created in an interface can only be constants. Interfaces can reference objects of classes which implement them. The behaviour is the same as superclass referencing subclass objects. StringBuilder - StringBuilder is used to create mutable strings. - Default value is an empty string - All operations are done in place (directly modifying the string) Methods: String toString() -> Returns string stored in StringBuilder. int length() -> Returns string length Char charAt(int i) -> Returns character at specified index Void setCharAt(int i) -> Sets character at the specified index StringBuilder deleteCharAt(int I) -> Deletes the character at the specified index StringBuilder append(String s) -> Concatenates given string to the end of the invoking object. Several overloadings to take primitive types and even arrays of characters. StringBuilder insert(int offset, String str) -> Inserts string at given index StringBuilder replace(int start, int end, String str) -> Replace substring from start index to end index (exclusive) with given string. StringBuilder delete(int start, int end) -> Removes substring from start index to end index (exclusive) StringBuilder reverse() -> Reverses string in SB object. (Un)Boxing | Primitive Wrappers You need to use .equals() to check if a Primitive wrapper’s value is equal to another’s. Since they are Reference Types. OR To get the value a wrapper is storing use: .[nameOfWrapper]Value() Generic Classes Only Reference Types can be passed to generic classes. Classes can be created to store generic types Like: Object references can also be used to store Ref types just like generics. BUT Object references can create run-time errors. While generics only throw errors at compile-time. Which means Generics are superior because the errors are spotted by programmers and NOT users. - When it reaches its capacity, it creates a new array of size capacity * 1.5 and copies current elements to the new array. [O(n) operation] - It is good practice to use superclass notation when working with ArrayList and LinkedList: List<String> names = ArrayList<>(); To create an immutable list: List<ref> list = List.of(val1, val2 …); To initialize a mutable ArrayList: List<ref> list = new ArrayList<>(List.of(val1, val2 …)); OR List<Integer> li = new ArrayList<>(Arrays.asList(new Integer[] { 1, 2, 3 })); LinkedList works as a Doubly Linked List, therefore, accessing any elements is an O(N) operation. (except for first and last elements) By using superclass notation, you can compare objects which implement the List<> interface using .equals() for example. This is without compiler warnings. (NO ERRORS THROWN IF OTHERWISE, JUST WARNINGS) Comparable - Collections.sort(List<T>) to sort a COLLECTION of pre-defined types Comparable is an interface which can be used to implement sorting for custom classes like so: Let A be the current object (this) Let B be the object to compare to (otherObject) Where the return values should be: A < B, returns -1 A == B, returns 0 A > B, returns 1