2301. Java Core - Basic
String, Integer, Array, and List
Basic knowledge of java.
1. Basics
1.1 Java Access Modifiers
Class Access Levels are as follows:
Access Modifiers | private | default | protected | public |
Inside Class | Y | Y | Y | Y |
Same Package Class | N | Y | Y | Y |
Same Package Sub-Class | N | Y | Y | Y |
Other Package Class | N | N | N | Y |
Other Package Sub-Class | N | N | Y | Y |
1.2 Java Primitive Data Types
A primitive data type
specifies the size and type of variable values, and it has no additional methods. There are eight primitive data types in Java:
Data Type | Size | Description |
---|---|---|
byte | 1 byte | Stores whole numbers from -128 to 127 |
short | 2 bytes | Stores whole numbers from -32,768 to 32,767 |
int | 4 bytes | Stores whole numbers from -2,147,483,648 to 2,147,483,647 |
long | 8 bytes | Stores whole numbers from -9,223,372,036,854,775,808 to 9,223,372,036,854,775,808 |
float | 4 bytes | Stores fractional numbers from 3.4e−038 to 3.4e+038. Sufficient for storing 6 to 7 decimal digits |
double | 8 bytes | Stores fractional numbers from 1.7e−308 to 1.7e+038. Sufficient for storing 15 decimal digits |
boolean | 1 byte | Stores true or false values |
char | 2 bytes | Stores a single character/letter |
1.3 Java Non-primitive data types
Non-primitive data types are called reference types
because they refer to objects. The main difference between primitive
and non-primitive
data types are:
- Primitive types are predefined (already defined) in Java. Non-primitive types are created by the programmer and is not defined by Java (except for
String
). - Non-primitive types can be used to call methods to perform certain operations, while primitive types cannot.
- A primitive type has always a value, while non-primitve types can be
null
. - A primitive type starts with a lowercase letter, while non-primitive types starts with an uppercase letter.
- The size of a primitive type depends on the data type, while non-primitive types have all the same size.
Examples of non-primitive types are Strings
, Arrays
, Classes
, Interface
, etc.
1.4 Autoboxing in Java
Autoboxing in java was introduced in Java 1.5. Autoboxing and unboxing is a convenient way to auto transform primitive data type to it’s corresponding java wrapper classes and vice versa.
Autoboxing in Java
Converting a primitive data type into an object of the corresponding wrapper class is called autoboxing. For example, converting int to Integer or converting long to Long object.
Java compiler applies autoboxing when a primitive value is:
- Passed as a parameter to a method that expects an object of the corresponding wrapper class. For example a method with Integer argument can be called by passing int, java compiler will do the conversion of int to Integer.
- Assigned to a variable of the corresponding wrapper class. For example, assigning a Long object to long variable.
Unboxing in Java
Converting an object of a wrapper type to its corresponding primitive data type is called unboxing.
Java compiler applies unboxing when an object of a wrapper class is:
- Passed as a parameter to a method that expects a value of the corresponding primitive type.
- Assigned to a variable of the corresponding primitive type.
Java Autoboxing Example:
public static void main(String[] args) { int i = 6; long j = 105L; // passed the int, will get converted to Integer object at Runtime using // autoboxing in java doSomething(i); List<Long> list = new ArrayList<>(); // java autoboxing to add primitive type in collection classes list.add(j); } private static void doSomething(Integer in) { // unboxing in java, at runtime Integer.intValue() is called implicitly to return int int j = in; // java unboxing, Integer is passed where int is expected doPrimitive(in); } private static void doPrimitive(int i) { }
1.5 Wrapper Class in Java
Wrapper class in java are the Object representation of eight primitive types in java. All the wrapper classes in java are immutable
and final
. Java 5 autoboxing and unboxing allows easy conversion between primitive types and their corresponding wrapper classes in java programs.
Below table shows the primitive types and their wrapper class in java.
Primitive type | Wrapper class | Constructor Arguments |
---|---|---|
byte | Byte | byte or String |
short | Short | short or String |
int | Integer | int or String |
long | Long | long or String |
float | Float | float, double or String |
double | Double | double or String |
char | Character | char |
boolean | Boolean | boolean or String |
Example.
public static void main(String args[]){ int i = 10; char c = 'a'; // primitives are simple to use int j = i + 3; // polymorphism achieved by Wrapper classes, we can't pass primitive here doSomething(new Character(c)); List<Integer> list = new ArrayList<>(); // wrapper classes can be used in Collections Integer in = new Integer(i); list.add(in); // autoboxing takes care of primitive to wrapper class conversion list.add(j); // wrapper classes can be null in = null; Integer ix = new Integer(12); System.out.println(ix); // ix = 12 modify(ix); System.out.println(ix); // ix is still 12 } private static void doSomething(Object obj){ } private static void modify(Integer ix) { ix = ix + 1; System.out.println(ix); // ix = 13 }
Notice, variable ix
in main() function is not changed after the call by modify() function.
1.6 for loop
There are three types of for loop in java.
- General for loop
- for-each or enhanced for loop
- Java for loop with label(continue or break)
Example for ‘general for loop’.
// print integers 6 to 10 for (int i = 6; i <= 10; i++) { System.out.println("Java for loop example - " + i); }
Example for ‘for-each or enhanced for loop’.
// print integers with 'for each' int[] intArray = { 1, 2, 3, 4, 5 }; for (int i : intArray) { System.out.println("Java for each example - " + i); } // print strings with 'for loop' List<String> fruits = new ArrayList<>(); fruits.add("Apple"); fruits.add("Banana"); fruits.add("Orange"); for (String f : fruits) { System.out.println("Java for each loop with collection - " + f); }
Example for ‘for loop with label’.
// for loop with label, continue int[][] intArr = { { 1, -2, 3 }, { 0, 3 }, { 9, 2, 5 }, { 1, 2, 5 }}; process: for (int i = 0; i < intArr.length; i++) { boolean allPositive = true; for (int j = 0; j < intArr[i].length; j++) { if (intArr[i][j] < 0) { allPositive = false; continue process; } } if (allPositive) { // process the array System.out.println("Array has no negative elements: " + Arrays.toString(intArr[i])); } } // for loop with label, break search: for (int i = 0; i < intArr.length; i++) { for (int j = 0; j < intArr[i].length; j++) { if (intArr[i][j] > 7) { System.out.println("Find array which contains element larger than 7: " + Arrays.toString(intArr[i])); break search; } } }
Output.
Java for loop example - 6
Java for loop example - 7
Java for loop example - 8
Java for loop example - 9
Java for loop example - 10
Java for each example - 1
Java for each example - 2
Java for each example - 3
Java for each example - 4
Java for each example - 5
Java for each loop with collection - Apple
Java for each loop with collection - Banana
Java for each loop with collection - Orange
Array has no negative elements: [0, 3]
Array has no negative elements: [9, 2, 5]
Array has no negative elements: [1, 2, 5]
Find array which contains element larger than 7: [9, 2, 5]
1.7 while loop
// while loop int i = 6; while (i <= 10) { System.out.println(i); i++; } // while loop with Iterator List<String> veggies = new ArrayList<>(); veggies.add("Spinach"); veggies.add("Potato"); veggies.add("Tomato"); Iterator<String> it = veggies.iterator(); while(it.hasNext()) { System.out.println(it.next()); } // infinite loop while(true) { try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } SimpleDateFormat sdf = new SimpleDateFormat("MMM dd,yyyy HH:mm:ss"); Date current = new Date(System.currentTimeMillis()); System.out.println(sdf.format(current)); }
Output.
6
7
8
9
10
Spinach
Potato
Tomato
Apr 01,2019 13:52:25
Apr 01,2019 13:52:26
Apr 01,2019 13:52:27
Apr 01,2019 13:52:28
Apr 01,2019 13:52:29
Apr 01,2019 13:52:30
...
1.8 do while loop
// do while loop int i = 6; do { System.out.println(i); i++; } while (i <= 10); // infinite loop do { try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } SimpleDateFormat sdf = new SimpleDateFormat("MMM dd,yyyy HH:mm:ss"); Date current = new Date(System.currentTimeMillis()); System.out.println(sdf.format(current)); } while(true);
Output.
6
7
8
9
10
Apr 01,2019 14:01:06
Apr 01,2019 14:01:07
Apr 01,2019 14:01:08
Apr 01,2019 14:01:09
Apr 01,2019 14:01:10
1.9 do while vs while loop
The only time you should use do while
loop is when you want to execute the statements inside loop at least once
, even though condition expression returns false. Otherwise it’s always better to use while loop.
2. Static Keyword
static keyword usage.
- static variable
- static methods
- static block
- static inner class
- Interface static method
Example.
public class StaticKeywordExample { public static void main(String[] args) { StaticExample.setCount(5); //non-private static variables can be accessed with class name StaticExample.str = "abc"; StaticExample se = new StaticExample(); System.out.println(se.getCount()); //class and instance static variables are same System.out.println(StaticExample.str + " is same as " + se.str); System.out.println(StaticExample.str == se.str); //static nested classes are like normal top-level classes StaticExample.MyStaticClass myStaticClass1 = new StaticExample.MyStaticClass(); myStaticClass1.count = 10; StaticExample.MyStaticClass myStaticClass2 = new StaticExample.MyStaticClass(); myStaticClass2.count = 20; System.out.println(myStaticClass1.count); System.out.println(myStaticClass2.count); } } class StaticExample { //static block static { //can be used to initialize resources when class is loaded System.out.println("StaticExample static block"); //can access only static variables and methods str = "Test"; setCount(2); } //multiple static blocks in same class static{ System.out.println("StaticExample static block2"); } //static variable example private static int count; //kept private to control its value through setter public static String str; // instance method public int getCount() { return count; } //static method example public static void setCount(int count) { if (count > 0) StaticExample.count = count; } //static util method public static int addInts(int i, int...js){ int sum = i; for (int x : js) { sum += x; } return sum; } //static class example - used for packaging convenience only public static class MyStaticClass{ public int count; } }
3. String and Character
3.1 String
Common operations on String.
- Creation
- Concatenation
- Comparison
- Conversion
- Substring
- Replacement
// String creation String s1 = "java"; // s1 = "java" String s2 = new String("java"); // s2 = "java" String s3 = new String(new char[]{'j','a','v','a'}); // s3 = "java", created by char array String s4 = String.valueOf(5); // s4 = "5", created by int // concatenate strings String s10 = "hello"; String s11 = "123"; String s12 = s10 + s11; // s12 = "hello123"; // String comparison String str1 = "java"; // str1 is stored in String Pool String str2 = "java"; // str2 is stored in String Pool String str3 = new String("java"); // str3 is created locally, it is not in String Pool String str4 = new String(new char[]{'j','a','v','a'}); // str4 = "java" System.out.println(str1 == str2); // true, both are from String Pool, same object System.out.println(str1.equals(str2)); // true System.out.println(str1 == str3); // false, str3 is created with new keyword System.out.println(str1.equals(str3)); // true System.out.println(str1 == str4); // false, str4 is created with new keyword System.out.println(str1.equals(str4)); // true // Substring String s = "hello, world"; String substring = s.substring(0, 5); // substring = "hello" System.out.println(substring); CharSequence subSequence = s.subSequence(0, 5); // subSequence = "hello" System.out.println(subSequence); // Split string to string array String sentence = "I am a software engineer"; String[] array = sentence.split(" "); // array = {"I", "am", "a", "software", "engineer"} // Split string with regex String a = "1+2i"; String[] x = a.split("\\+|i"); // x = {"1", "2"}; System.out.println(Arrays.toString(x)); String b = "1+2i3"; String[] y = b.split("\\+|i"); // y = {"1", "2", "3"}; System.out.println(Arrays.toString(y)); // Replace string String strA = "hello, world"; strA = strA.replaceAll("o","tt"); // strA = "helltt, wttld"; System.out.println(strA); // Convert string to upper case String strB = "Hello, World!"; strB = strB.toUpperCase(); // strB = "HELLO, WORLD!" System.out.println(strB); // Convert string to lower case String strC = "Hello, World!"; strC = strC.toLowerCase(); // strC = "hello, world!" System.out.println(strC); // intern() String strAA = "intern"; String strBB = new String("intern"); System.out.println(strAA == strBB); // false, strBB is created with new keyword System.out.println(strAA.equals(strBB)); // true // get the string from String Poll String strCC = strBB.intern(); // strCC is fetched from String Pool System.out.println(strAA == strCC); // true, strCC is strAA System.out.println(strAA.equals(strCC)); // true
3.2 StringBuilder
StringBuilder is mainly used to concatenate strings, as it has better performance than String.
// StringBuilder creation StringBuilder sb1 = new StringBuilder(); StringBuilder sb2 = new StringBuilder(20); // Set capacity StringBuilder sb3 = new StringBuilder("Hello, world!"); // Creation with initial value StringBuilder sb = new StringBuilder("Have"); // append sb.append(" a"); sb.append(" nice"); sb.append(" day!"); System.out.println(sb); // sb.toString() = "Have a nice day!" sb.append(1); sb.append(2); sb.append(3); System.out.println(sb); // sb.toString() = "Have a nice day!123" // insert sb.insert(0, "Johnny, "); System.out.println(sb); // sb.toString() = "Johnny, Have a nice day!123" // replace sb.replace(8, 12, "have"); // change H to lower case System.out.println(sb); // sb.toString() = "Johnny, have a nice day!123" // delete sb.delete(sb.length() - 2, sb.length()); System.out.println(sb); // sb.toString() = "Johnny, have a nice day!1" // Delete last character sb.setLength(sb.length() - 1); System.out.println(sb); // sb.toString() = "Johnny, have a nice day!" // reverse sb.reverse(); System.out.println(sb); // sb.toString() = "!yad ecin a evah ,ynnhoJ" // convert to String String str = sb.toString(); System.out.println(str); // str = "!yad ecin a evah ,ynnhoJ";
3.3 StringBuffer
StringBuffer is mainly used to concatenate strings, as it has better performance than String.
// StringBuffer creation StringBuffer sb1 = new StringBuffer(); StringBuffer sb2 = new StringBuffer(20); // Set capacity StringBuffer sb3 = new StringBuffer("Hello, world!"); // Creation with initial value StringBuffer sb = new StringBuffer("Have"); // append sb.append(" a"); sb.append(" nice"); sb.append(" day!"); System.out.println(sb); // sb.toString() = "Have a nice day!" sb.append(1); sb.append(2); sb.append(3); System.out.println(sb); // sb.toString() = "Have a nice day!123" // insert sb.insert(0, "Johnny, "); System.out.println(sb); // sb.toString() = "Johnny, Have a nice day!123" // replace sb.replace(8, 12, "have"); // change H to lower case System.out.println(sb); // sb.toString() = "Johnny, have a nice day!123" // delete sb.delete(sb.length() - 2, sb.length()); System.out.println(sb); // sb.toString() = "Johnny, have a nice day!1" // Delete last character sb.setLength(sb.length() - 1); System.out.println(sb); // sb.toString() = "Johnny, have a nice day!" // reverse sb.reverse(); System.out.println(sb); // sb.toString() = "!yad ecin a evah ,ynnhoJ" // convert to String String str = sb.toString(); System.out.println(str); // str = "!yad ecin a evah ,ynnhoJ";
3.4 String vs StringBuilder vs StringBuffer
Feature | String | StringBuilder | StringBuffer |
---|---|---|---|
mutable | No | Yes | Yes |
thread-safe | Yes | No | Yes |
3.5 CharSequence
CharSequence is an interface
that represents a sequence of characters. String, StringBuilder and StringBuffer are all its implementations.
// CharSequence creation, instantiated by implementation class(String, StringBuffer or StringBuilder) CharSequence string = "hello, String!"; CharSequence stringbuffer = new StringBuffer("hello, StringBuffer!"); CharSequence stringbuilder = new StringBuilder("hello, StringBuilder!"); // Comparison CharSequence cs1 = "java"; // created by String, fetched from String Pool String str1 = "java"; // fetched from String Pool StringBuilder sb1 = new StringBuilder("java"); StringBuffer sb2 = new StringBuffer("java"); System.out.println(cs1 == str1); // true, since they are both from String Pool System.out.println(cs1.equals(str1)); // true, their values are same System.out.println(cs1.equals(sb1)); // false System.out.println(cs1.equals(sb1.toString())); // true System.out.println(cs1.equals(sb2)); // false System.out.println(cs1.equals(sb2.toString())); // true CharSequence cs2 = new String("java"); // new string object, not in String Pool System.out.println(cs2 == str1); // false System.out.println(cs2.equals(str1)); // true
Note, whether the object created by CharSequence is equal to other strings depends on how this object is created. If we know which class instantiated these objects, it is easy to apply the comparison rules.
3.6 Character
// get integer value from char String s = "ab5d"; int x = Character.getNumericValue(s.charAt(2)); // x = 5 // check if character is number(one single character) Character.isDigit(c); // same as if (c >= '0' && c <= '9') { } // check if character is number or letter Character.isLetterOrDigit(c); // same as if (c >= '0' && c <= '9' || c >= 'a' && c <= 'z' || c >= 'A' && c <= 'Z') { }
4. Bit Manipulation
// flip bit with XOR, change 1 to 0 and change 0 to 1. int bit = 0; bit = bit ^ 1; // bit = 1; bit = bit ^ 1; // bit = 0; // find the complement of the give number int num = 10; // 1010 int mask = 15; // 1111 int result = num ^ mask; // result = 5, 0101 // power int left = 3; int pow = 1 << left; // pow = 8, 1000 // shift int num = 5; // get the value of last bit int last = num & 1; // last = 1 // right shift num >> 1; // return 2, 101 -> 10 // left shift num << 1: // return 10, 101 -> 1010 // number of one-bits int n = 177 // in binary format: 10110001 int count = 0; while (n > 0) { if (n & 1) { count++; } n = n >> 1; } return count; // count = 4; // or use built-in method Integer.bitCount(177); // return 4
5. Array and Collections
5.1 Array and List
// create empty array int[] nums = new int[]{}; String[] strs = new String[]{}; // create array with length = 3 int[] nums = new int[3]; String[] strs = new String[3]; // create char array from string String s = "hello"; char[] chs = s.toCharArray(); // chs = {'h','e','l','l','o'}; // create list List<Integer> list1 = new ArrayList<>(); List<String> list2 = new ArrayList<>(); // create list with array int[] nums = new int[]{1,2,3}; List<Integer> list = Arrays.asList(nums); // list = {1,2,3} // loop for (int i = 0; i < nums.length; i++) { int num = nums[i]; } // or for (int num : nums) { } // Sort array int[] nums = {3, 7, 6, 5, 9, 2}; Arrays.sort(nums); // nums = {2,3,5,6,7,9}; // Sort collection List<String> list = new ArrayList<String>(); list.add("orange"); list.add("apple"); list.add("banana"); Collections.sort(list); // list = {"apple", "banana", "orange"} // Binary search on sorted array or collection int index1 = Arrays.binarySearch(new char[]{'c','d','e','f','g'}, 'f'); // index1 = 3; int index2 = Arrays.binarySearch(new int[]{10,15,20,22,35}, 20); // index2 = 2; int index3 = Collections.binarySearch(Arrays.asList(new Integer[] {10,15,20,22,35}), 15); // index3 = 1; // Binary search on array int[] array = {10,15,20,22,35}; int index1 = Arrays.binarySearch(array,20); // index1 = 2 int index2 = Arrays.binarySearch(array,8); // index2 = -1, (-insertion point) - 1 int index3 = Arrays.binarySearch(array,40); // index3 = -6, (-insertion point) - 1 // Binary search on collection List list = new ArrayList<>(Arrays.asList(new Integer[]{10,20,15,22,35})); int index1 = Collections.binarySearch(list,20); // index1 = 2 int index2 = Collections.binarySearch(list,8); // index2 = -1, (-insertion point) - 1 int index3 = Collections.binarySearch(list,40); // index3 = -6, (-insertion point) - 1 // print Array int[] nums = {1,3,5,7}; System.out.println(Arrays.toString(nums)); // print [1,3,5,7]
5.2 HashSet, HashMap, TreeMap
// create HashSet Set<String> set = new HashSet<>(); Set<Integer> set = new HashSet<>(); // initialize HashSet with List List<Integer> list = new ArrayList<>(); list.add(1); list.add(2); Set<Integer> set = new HashSet<>(list); // set = {1,2} // initialize HashSet with array int[] nums = new int[]{1,2,3}; Set<Integer> set = new HashSet<>(Arrays.asList(nums)); // set = {1,2,3} // create HashMap, key-value pair Map<Integer, Integer> map = new HashMap<>(); Map<Integer, String> map = new HashMap<>(); // remove duplicated elements in list List<Integer> list = new ArrayList<>(); list.add(1); list.add(2); list.add(1); // duplicate element Set<Integer> set = new HashSet<>(list); // set = {1,2} list.clear(); list.addAll(set); // list = {1,2} TreeMap<Integer, String> treeMap = new TreeMap<>(); treeMap.put(1, "Monday") treeMap.put(2, "Tuesday") treeMap.put(3, "Wednesday") treeMap.put(4, "Thursday") treeMap.put(5, "Friday") String day = treeMap.get(3); // day = "Wednesday" Integer lowKey = treeMap.lowerKey(3); // lowKey = 2 Integer highKey = treeMap.higherKey(3); // lowKey = 4 Map.Entry<Integer, String> lowEntry = treeMap.lowerEntry(3); // lowEntry = <3, Wednesday> Map.Entry<Integer, String> highEntry = treeMap.higherEntry(3); // lowEntry = <4, Thursday>
5.3 Stack and Queue
// create stack Stack<Integer> stack = new Stack<>(); // create queue Queue<Integer> queue = new LinkedList<>(); // create Deque Deque<Integer> deque = new LinkedList<>(); // Loop elements in queue Queue<Integer> queue = new LinkedList<>(); int sum = 0; for (int i: queue) { sum = sum + i; }
5.4 Heap
// create min heap PriorityQueue<Integer> minHeap = new PriorityQueue<>(); // create max heap PriorityQueue<Integer> maxHeap = new PriorityQueue<>((a,b)->b-a);