# Java for Interviews (Core Java - III)

# Core Java - III:

## Marker Interface:

* This is an empty interface (no fields or methods).
    
* Serializable, Cloneable, and Remote interfaces are examples of marker interfaces.
    

---

## Serialization and Deserialization:

### Serialization:

* Process of converting the state of an object into a byte stream after the program exists.
    
* This byte stream can be saved as a file (.ser) which is platform-independent.
    
* Through this process, the information of the object is saved into the file.
    
* Steps to serialize:
    
    1. Object class should implement a ‘Serializable’ interface.
        
    2. Use the code below.
        
        ```java
        import java.io.serializable;
        
        FileoutputStream fileOut = new FileOutputStream("file path");
        ObjectOutputStream out = new ObjectOutputStream(fileOut);
        out.writeObject(objectName); 
        out.close(); 
        fileOut.close();
        ```
        

### Deserialization:

* The reverse process of converting a byte stream into an object.
    
* Steps to deserialize:
    
    1. Create a class same as the one that’s serialized and declare the object (don’t instantiate).
        
    2. Object class should implement a ‘Serializable’ interface.
        
    3. Use the code below.
        
        ```java
        import java.io.Serializable;
        
        FileInputStream fileIn = new FileInputStream("file path");
        ObjectInputStream in = new ObjectInputStream(fileIn);
        objectName = (<datatype of the object>) in.readObject();
        in.close();
        fileIn.close();
        ```
        

### Important Notes:

* Children classes of a parent class that implements ‘Serializable’ will do so as well.
    
* Static fields are not serialized. Because they belong to the class itself, and not to an individual object.
    
* The class definition itself is not recorded. So while deserializing, cast the input stream as the object type.
    
* Fields declared as “transient” aren’t serialized, they’re ignored.
    
* **SerialVersionUID:**
    
    * Unique ID that functions like a version number.
        
    * Verifies that the sender and receiver of a serialized object, have loaded classes for that object that match.
        
    * Ensures objects will be compatible with machines.
        
    * The number must match, otherwise, this will cause ‘InvalidClassException’.
        
    * SerialVersionUID will be calculated based on class properties, members, etc...
        
    * A serializable class can declare its own ‘serialVersionUID’ explicitly (recommended).
        

---

## Timer and TimerTask:

* Timer:
    
    * A facility for threads to schedule tasks for future execution in a background thread.
        
* TimerTask:
    
    * A task that can be scheduled for one-time or repeated execution by a Timer.
        

---

## Threads:

* A thread is a lightweight sub-process, the smallest unit of processing.
    
* Threads are independent. So, if there occurs an exception in one thread, it doesn’t affect other threads. It uses a shared memory area.
    
* Java provides a **Thread** class to achieve thread programming.
    
* JVM allows an application to have multiple threads running concurrently.
    
* Each thread can execute parts of the code in parallel with the main thread.
    
* Each thread has a priority.
    
* Threads with higher priority are executed in preference compared to threads with lower priority.
    
* JVM continues to execute threads until either of the following occurs,
    
    * The exit method of class Runtime has been called.
        
    * All user threads have died.
        
* When a JVM starts up, there is a thread that calls the main method. This thread is called as **main**.
    
* There are two kinds of threads:
    
    * Daemon thread
        
    * User thread
        
* A **Daemon** thread is a low-priority thread that runs in the background to perform tasks such as garbage collection.
    
* JVM terminates itself when all user threads (non-daemon threads) finish their execution.
    
* There are two ways to create threads.
    
    * Extending the **Thread** class.
        
    * Creating an instance of a class that implements the **Runnable** interface, and passes the instance within the constructor of a **Thread** class.
        
    * **Example:**
        
        ```java
        Thread t = new Thread(new Runnable(){
            @Override
            public void run() {
            }
        });
        ```
        

## Multithreading:

* Process of executing multiple threads simultaneously.
    
* Helps maximize utilization of CPU.
    
* Threads are independent. So, if there occurs an exception in one thread, it doesn’t affect other threads.
    
* Useful for multiple clients, multiplayer games, etc...
    

---

## Collections Framework:

* The **Collection** interface (java.util.Collection) and **Map** interface ([java.util.Map](http://java.util.Map)) are the two main root interfaces of java collection classes.
    
* Advantages of Collections:
    
    * Consistent API → The API has a basic set of interfaces like Collection, Set, List, or Map and all the classes like ArrayList, LinkedList, Vector, etc... that implement these interfaces and have some common methods.
        
    * Reduces programming effort → A developer doesn’t have to worry about the design of the collections.
        
    * Increases program speed and quality → Increases performance by providing high-performance implementations of useful data structures and algorithms.
        
* Hierarchy of the Collection framework:
    
    ![](https://cdn.hashnode.com/res/hashnode/image/upload/v1674404718505/3cbc751e-d6b1-4055-8c36-0908267b6bed.png align="center")
    
    * Root interfaces:
        
        1. Iterable interface:
            
            * Root interface for the entire collection framework.
                
            * The **collection** interface extends the **iterable** interface.
                
            * Therefore all the interfaces, and classes implement this interface.
                
            * This interface provides an iterator to iterate through all the collections.
                
            * This interface contains only one abstract method which is the iterator.
                
        2. Collection interface:
            
            * This interface extends the **iterable** interface and is implemented by all the classes in the collections framework.
                
            * This interface contains all the basic methods which every collection has like addition, removing, clearing the data, etc...
                
            * Having these methods in this interface ensures that the names of the methods are universal for all the collections.
                
            * This interface builds the foundation on which all the collection classes are implemented.
                
        3. List interface:
            
            * This is a child interface of the **Collection** interface.
                
            * This interface is dedicated to the data of the list type in which we can store all the ordered collections of the objects.
                
            * This also allows duplicate data to be present in it.
                
            * This list interface is implemented by various classes like ArrayList, Vector, Stack, etc.
                
            * Since all the subclasses implement the list, we can instantiate a list object with any of these classes as shown below.
                
                ```java
                 List <T> al = new ArrayList<> (); 
                 List <T> ll = new LinkedList<> (); 
                 List <T> v = new Vector<> ();
                ```
                
        4. Queue interface:
            
            * As the name suggests, a queue interface maintains the FIFO(First In First Out) order similar to a real-world queue line.
                
            * This interface is dedicated to storing all the elements where the order of the elements matters.
                
            * There are various classes like PriorityQueue, ArrayDeque, etc.
                
            * Since all these subclasses implement the queue, we can instantiate a queue object with any of these classes.
                
                ```java
                Queue <T> pq = new PriorityQueue<> (); 
                Queue <T> ad = new ArrayDeque<> ();
                ```
                
        5. Dequeue interface:
            
            * This is a very slight variation of the Queue Data Structure.
                
            * It is also known as a double-ended queue, which is a data structure where we can add and remove the elements from both ends of the queue.
                
            * This interface extends the queue interface. The class which implements this interface is ArrayDeque.
                
                ```java
                Deque<T> ad = new ArrayDeque<> ();
                ```
                
        6. Set interface:
            
            * A set is an unordered collection of objects in which duplicate values cannot be stored.
                
            * This collection is used when we wish to avoid the duplication of the objects and wish to store only the unique objects.
                
            * This set interface is implemented by various classes like HashSet, TreeSet, LinkedHashSet, etc.
                
            * Since all the subclasses implement the set, we can instantiate a set object with any of these classes.
                
                ```java
                Set<T> hs = new HashSet<> (); 
                Set<T> lhs = new LinkedHashSet<> (); 
                Set<T> ts = new TreeSet<> ();
                ```
                
        7. Sorted Set interface:
            
            * This interface is very similar to the set interface.
                
            * The only difference is that this interface has extra methods that maintain the ordering of the elements.
                
            * The sorted set interface extends the set interface and is used to handle the data which needs to be sorted.
                
            * The class which implements this interface is TreeSet.
                
            * Since this class implements the SortedSet, we can instantiate a SortedSet object with this class.
                
                ```java
                SortedSet<T> ts = new TreeSet<> ();
                ```
                
        8. Map interface:
            
            * A map is a data structure that supports the key-value pair mapping for the data.
                
            * This interface doesn’t support duplicate keys because the same key cannot have multiple mappings.
                
            * A map is useful if there is data and we wish to perform operations based on the key.
                
            * This map interface is implemented by various classes like HashMap, TreeMap, etc.
                
            * Since all the subclasses implement the map, we can instantiate a map object with any of these classes.
                
                ```java
                Map<T> hm = new HashMap<> (); 
                Map<T> tm = new TreeMap<> ();
                ```
                
    * Classes that implement List interface:
        
        1. ArrayList:
            
            * ArrayList provides us with dynamic arrays in Java.
                
            * Though, it may be slower than standard arrays but can be helpful in programs where lots of manipulation in the array is needed.
                
            * The size of an ArrayList is increased automatically if the collection grows or shrinks when the objects are removed from the collection.
                
                ```java
                ArrayList<Integer> al = new ArrayList<Integer>();
                ```
                
        2. LinkedList:
            
            * LinkedList class is an implementation of the LinkedList Data Structure which is a linear data structure where the elements are not stored in contiguous locations and every element is a separate object with a data part and address part.
                
            * The elements are linked using pointers and addresses.
                
            * Each element is known as a node.
                
                ```java
                LinkedList<Integer> ll = new LinkedList<Integer>();
                ```
                
        3. Vector:
            
            * A vector provides us with dynamic arrays in Java.
                
            * Though, it may be slower than standard arrays but can be helpful in programs where lots of manipulation in the array is needed.
                
            * This is identical to ArrayList in terms of implementation.
                
            * However, the primary difference between a vector and an ArrayList is that a Vector is synchronized and an ArrayList is non-synchronized.
                
            * Synchronized means **only one thread at a time can access the code.**
                
                ```java
                Vector<Integer> v = new Vector<Integer>();
                ```
                
        4. Stack:
            
            * Stack class models and implements the Stack Data Structure.
                
            * The class is based on the basic principle of *last-in-first-out.*
                
            * In addition to the basic push and pop operations, the class provides three more functions empty, search and peek.
                
            * This class can also be referred to as the subclass of Vector.
                
            * Stack is a subclass of Vector and a legacy class. It is thread-safe which might be overhead in an environment where thread safety is not needed. An alternate to Stack is to use ArrayDequeue which is not thread-safe and has faster array implementation.
                
                ```java
                Stack<String> stack = new Stack<String>();
                ```
                
    * Classes that implement Queue interface:
        
        1. PriorityQueue:
            
            * A PriorityQueue is used when the objects are supposed to be processed based on priority.
                
            * It is known that a queue follows the First-In-First-Out algorithm, but sometimes the elements of the queue are needed to be processed according to the priority and this class is used in these cases.
                
            * The PriorityQueue is based on the priority heap. The elements of the priority queue are ordered according to the natural ordering, or by a Comparator provided at queue construction time, depending on which constructor is used.
                
                ```java
                PriorityQueue<Integer> pQueue = new PriorityQueue<Integer>();
                ```
                
    * Classes that implement Deque interface:
        
        * ArrayDeque class provides us with a way to apply a resizable array.
            
        * This is a special kind of array that grows and allows users to add or remove an element from both sides of the queue.
            
        * Array deques have no capacity restrictions and they grow as necessary to support usage.
            
            ```java
            ArrayDeque<Integer> de_que = new ArrayDeque<Integer>(10);
            ```
            
    * Classes that implement the Set interface:
        
        1. HashSet:
            
            * The HashSet class is an inherent implementation of the Hash Table Data Structure.
                
            * The objects that we insert into the HashSet do not guarantee to be inserted in the same order.
                
            * The objects are inserted based on their hashcode.
                
            * This class also allows the insertion of NULL elements.
                
                ```java
                HashSet<String> hs = new HashSet<String>();
                ```
                
        2. LinkedHashSet:
            
            * A LinkedHashSet is very similar to a HashSet.
                
            * The difference is that this uses a doubly linked list to store the data and retains the ordering of the elements.
                
                ```java
                LinkedHashSet<String> lhs = new LinkedHashSet<String>();
                ```
                
    * Classes that implement the Sorted Set interface:
        
        1. TreeSet:
            
            * The TreeSet class uses a Tree for storage.
                
            * The ordering of the elements is maintained by a set using their natural ordering whether or not an explicit comparator is provided.
                
            * This must be consistent with equals if it is to correctly implement the Set interface.
                
            * It can also be ordered by a Comparator provided at a set creation time, depending on which constructor is used.
                
                ```java
                TreeSet<String> ts = new TreeSet<String>();
                ```
                
    * Classes that implement Map interface:
        
        1. HashMap:
            
            * HashMap provides the basic implementation of the Map interface of Java.
                
            * It stores the data in (Key, Value) pairs.
                
            * To access a value in a HashMap, we must know its key.
                
            * HashMap uses a technique called Hashing.
                
            * Hashing is a technique of converting a large String to a small String that represents the same String so that the indexing and search operations are faster.
                
            * HashSet also uses HashMap internally.
                
                ```java
                HashMap<Integer, String> hm = new HashMap<Integer, String>();
                ```
                
        2. TreeMap:
            
            * The TreeMap in Java has been used to implement Map and NavigableMap interfaces along with the AbstractMap Class.
                
            * The map is sorted according to the natural ordering of its keys, or by a Comparator provided at map creation time, depending on which constructor is used.
                
            * This proves to be an efficient way of sorting and storing the key-value pairs.
                
            * The storing order maintained by the treemap must be consistent with equals just like any other sorted map, irrespective of the explicit comparators.
                
            * The treemap implementation is not synchronized in the sense that if a map is accessed by multiple threads, concurrently and at least one of the threads modifies the map structurally, it must be synchronized externally.
                

---

## Lambda:

* A lambda expression is a short block of code that takes in parameters and returns a value.
    
* Lambda expressions are similar to methods, but they do not need a name and they can be implemented right in the body of a method.
    
    ```java
    (n) -> { System.out.println(n); }
    ```
    

---
