Skip to content
IT-306 · Java Programming Lab/Quick Revision Short Notes

Java Programming Lab (IT-306) - Unit 3 Short Notes

UNIT 3: JAVA PROGRAMMING LAB - SHORT NOTES


1.0 Exception Handling in Java

1.1 Fundamentals of Exceptions

  • Definition: An exception is an event that disrupts the normal flow of a program. Handling it allows graceful recovery.

  • Hierarchy:

    | Class | Description | | :--- | :--- | | Throwable | Root class. | | Error | Severe system issues (e.g., OutOfMemoryError). Unchecked, usually not handled. | | Exception | Program-level issues. Can be handled. | | RuntimeException | Subclass of Exception (e.g., NullPointerException). Unchecked. | | Checked Exceptions | Subclasses of Exception excluding RuntimeException. Must be handled (try-catch) or declared (throws). |

  • Key Point: Checked exceptions enforce compile-time checking; unchecked do not.

1.2 Try-Catch-Finally Mechanism

  • Syntax:

    
    try {
    
        // Code that may throw exception
    
    } catch (SpecificException e) {
    
        // Handler
    
    } catch (AnotherException e) {
    
        // Handler (Order: specific to general)
    
    } finally {
    
        // Always executes (even if return/catch). Used for cleanup.
    
    }
    
    
  • Flow: try → (if exception) matching catch → finally. If no exception, catch skipped, then finally.

  • > [!TIP] Common Pitfall: finally block executes even if try/catch has a return. The return value is determined before finally runs, but finally can modify mutable return objects.

1.3 Throwing Exceptions

  • throw: Manually throws an exception object.

    
    if (age < 0) throw new IllegalArgumentException("Age cannot be negative");
    
    
  • throws: Declares exceptions a method might throw. Propagates responsibility to caller.

    
    public void readFile() throws IOException { ... }
    
    
  • Propagation: If a method doesn't handle a checked exception, it must declare it with throws. The exception climbs the call stack until caught.

1.4 Custom Exceptions

  • Create by extending Exception (for checked) or RuntimeException (for unchecked).

    
    public class InsufficientFundsException extends Exception {
    
        public InsufficientFundsException(String msg) { super(msg); }
    
        // Add custom fields/methods if needed
    
    }
    
    
  • Usage: throw new InsufficientFundsException("Balance too low");

1.5 Try-with-Resources (Java 7+)

  • Syntax: Automatically closes resources implementing AutoCloseable.

    
    try (BufferedReader br = new BufferedReader(new FileReader("file.txt"))) {
    
        // Use br
    
    } // br.close() called automatically, even on exception.
    
    
  • Advantage: Cleaner, safer than finally block with explicit close(). Can declare multiple resources separated by ;.

  • > [!TIP] Remember: Resources are closed in reverse order of declaration.


2.0 Java I/O (Input/Output) Streams

2.1 Stream Fundamentals

Byte Streams Character Streams
Handle raw binary data (8-bit bytes). Handle text data (16-bit Unicode characters).
Classes: InputStream, OutputStream. Classes: Reader, Writer.
E.g., FileInputStream, DataOutputStream. E.g., FileReader, BufferedWriter.
Use for: Images, audio, serialized objects. Use for: Text files, console I/O.

2.2 File I/O Operations

  • File Class: Represents file/directory path. Not for file content.

    
    File f = new File("data.txt");
    
    f.exists(); f.isFile(); f.length(); f.delete();
    
    
  • Reading Text (Efficient): BufferedReader + FileReader.

    
    try (BufferedReader br = new BufferedReader(new FileReader("file.txt"))) {
    
        String line;
    
        while ((line = br.readLine()) != null) {
    
            // Process line
    
        }
    
    }
    
    
  • Writing Text (Efficient): BufferedWriter + FileWriter.

    
    try (BufferedWriter bw = new BufferedWriter(new FileWriter("output.txt"))) {
    
        bw.write("Hello");
    
        bw.newLine(); // Platform-independent newline
    
    }
    
    
  • Binary I/O: FileInputStream / FileOutputStream for raw bytes.

2.3 Standard Streams

  • System.in → InputStream (usually BufferedInputStream).

  • System.out → PrintStream (auto-flushed on \n).

  • System.err → PrintStream for error messages.

  • Console Input:

    • Scanner (Simpler): new Scanner(System.in). nextInt(), nextLine().

    • BufferedReader (Faster): new BufferedReader(new InputStreamReader(System.in)). readLine() returns String.

2.4 Serialization and Deserialization

  • Concept: Converting object state to byte stream (serialization) and reconstructing from it (deserialization).

  • Requirements:

    1. Class must implement java.io.Serializable (marker interface).

    2. Fields marked transient are not serialized.

    3. Optional: private static final long serialVersionUID = 1L; for version control.

  • Process:

    
    // Serialize
    
    try (ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("obj.ser"))) {
    
        oos.writeObject(myObject);
    
    }
    
    // Deserialize
    
    try (ObjectInputStream ois = new ObjectInputStream(new FileInputStream("obj.ser"))) {
    
        MyClass obj = (MyClass) ois.readObject(); // ClassCastException if types mismatch
    
    }
    
    
  • > [!TIP] Common Pitfall: InvalidClassException if serialVersionUID of sender/receiver classes differ. ClassNotFoundException if class definition not available during deserialization.


3.0 Collections Framework

3.1 Core Interfaces & Hierarchy


Collection (Interface)

├── List (Interface)      [Ordered, allows duplicates]

├── Set (Interface)       [Unordered, no duplicates]

└── Queue (Interface)     [Ordered for processing, may allow duplicates]

Map (Interface)           [Key-Value pairs, keys unique]

  • Map does not extend Collection.

3.2 List Interface

Feature ArrayList LinkedList
Underlying Structure Resizable array Doubly-linked list
Insertion/Removal (end) O(1) amortized O(1)
Insertion/Removal (middle) O(n) (shift elements) O(1) if iterator at position
Search (get(index)) O(1) O(n)
Memory Overhead Less (only array + size) More (node objects with prev/next refs)
Best For Frequent retrievals, less modification Frequent insertions/removals at ends/middle
  • Common Methods: add(E e), add(int index, E e), get(int index), set(int index, E e), remove(int index), size(), clear().

  • ListIterator: Bidirectional (hasPrevious(), previous()). Allows set() and add() during traversal.

3.3 Set Interface

Feature HashSet LinkedHashSet TreeSet
Ordering No order Insertion-order Sorted (natural or Comparator)
Underlying HashMap LinkedHashMap TreeMap (Red-Black tree)
Performance (add/contains/remove) O(1) average O(1) average O(log n)
Null Elements Allows one null Allows one null No null (throws NullPointerException)
Use When Uniqueness only, speed Uniqueness + predictable iteration order Sorted, unique elements

3.4 Map Interface

Feature HashMap LinkedHashMap TreeMap
Ordering No order Insertion-order or access-order (LRU) Sorted by keys
Underlying Array of Entry (buckets) HashMap + doubly-linked list Red-Black tree
Performance (get/put) O(1) average O(1) average O(log n)
Null Keys/Values One null key, multiple null values One null key, multiple null values No null keys/values
Key Methods put(K key, V val), get(Object key), keySet(), values(), entrySet() Same as HashMap Same + firstKey(), lastKey(), headMap(), tailMap()
  • entrySet() returns Set<Map.Entry<K,V>> for iterating key-value pairs efficiently.

3.5 Utility Classes

  • Collections Class (static methods):

    • sort(List<T> list) / sort(List<T> list, Comparator<? super T> c)

    • shuffle(List<?> list)

    • binarySearch(List<? extends Comparable<? super T>> list, T key)

    • synchronizedList(List<T> list) → thread-safe wrapper.

    • unmodifiableList(List<? extends T> list) → read-only view.

  • Arrays Class:

    • asList(T... a) → Fixed-size list backed by array.

    • sort(int[] a) / sort(T[] a, Comparator<? super T> c)

    • binarySearch(int[] a, int key)

    • deepEquals(Object[] a1, Object[] a2)

3.6 Iterators and Enhanced For-Loop

  • Iterator<E> Interface:

    • boolean hasNext()

    • E next()

    • void remove() (Optional, removes last element returned by next()).

  • Fail-Fast: Iterators throw ConcurrentModificationException if collection structurally modified after iterator creation (except via Iterator.remove()).

  • Enhanced For-Loop (for-each):

    
    for (String s : list) { ... } // Works with arrays & any Iterable
    
    for (Map.Entry<K,V> entry : map.entrySet()) { ... }
    
    
  • > [!TIP] Pitfall: Cannot use for-each to remove elements from collection. Use explicit Iterator and its remove().


4.0 Practical Lab Applications & Common Pitfalls

4.1 Integrated Lab Exercises

  • Pattern: Read file → Parse data → Store in List<CustomObject> → Process → Write output.

    • Use try-with-resources for all I/O.

    • Use BufferedReader for large text files.

    • Handle NumberFormatException during parsing.

  • Management System: Use HashMap<ID, Employee> for fast lookup by ID. Use ArrayList for ordered lists. Validate inputs, throw/ catch custom exceptions (e.g., DuplicateIDException).

  • Serialization: Serialize ArrayList<Employee> to file. Deserialize back. Mark sensitive fields (e.g., salary) as transient.

4.2 Common Errors & Debugging

Error Cause Solution
NullPointerException Calling method on null object (common with uninitialized collections or get() returning null). Initialize collections. Check for null before use.
ConcurrentModificationException Modifying collection (add/remove) while iterating via for-each/iterator (except via Iterator.remove()). Use Iterator.remove(). Use CopyOnWriteArrayList (thread-safe). Collect modifications and apply after loop.
ClassCastException Storing wrong type in raw collection (no generics) or incorrect cast from Object. Always use generics (List<String>).
IndexOutOfBoundsException Invalid index for List (negative or >= size). Check size() before get(index)/remove(index).
Resource Leaks Forgetting to close Stream/Reader/Writer. Always use try-with-resources.
InvalidClassException serialVersionUID mismatch during deserialization. Define explicit serialVersionUID in Serializable classes.

4.3 Best Practices

  1. Resource Management: Always use try-with-resources for Closeable/AutoCloseable objects (I/O streams, Scanner, Connection).

  2. Exception Handling:

    • Catch the most specific exception first.

    • Don't catch Exception or Throwable unless re-throwing or logging at top level.

    • Log meaningful messages (e.getMessage()).

  3. Collections:

    • Use Generics (List<Employee>) for type safety.

    • Choose based on operation:

      • Frequent random access? → ArrayList.

      • Frequent insert/remove at ends? → LinkedList or ArrayDeque.

      • Need uniqueness? → HashSet (fast) or TreeSet (sorted).

      • Key-value lookup? → HashMap (fast) or TreeMap (sorted keys).

      • Need predictable iteration order? → LinkedHashSet/LinkedHashMap.

  4. Iteration: Use for-each for read-only traversal. Use explicit Iterator when needing to remove() elements safely.

Go to where you left off?

Quick Add to Notes

Save questions, your own notes and screenshots into notes filed by unit. It takes a free account.

Create free account

Have an account? Log in