============================================================ IT6003 - Advanced Java Programming Lab Session 2: Generics & Lambda Expressions State University of Zanzibar (SUZA) ============================================================ OBJECTIVES: - Create and use generic classes and methods - Understand bounded type parameters and wildcards - Write lambda expressions for functional interfaces - Use built-in functional interfaces (Predicate, Function, Consumer, Supplier) - Apply method references ============================================================ PART A: Generics [30 minutes] ============================================================ Exercise 1: Generic Box Class ------------------------------- a) Create a generic class Box with: - private T item; - void set(T item), T get(), boolean isEmpty() b) Create Box, Box, Box. c) Try to put a String in Box - observe compile error. Exercise 2: Generic Pair -------------------------- a) Create a generic class Pair with: - K getKey(), V getValue() - toString() returning "(key, value)" - swap() returning new Pair b) Create Pair for name-age pairs. c) Create Pair> for name-courses mapping. Exercise 3: Generic Methods ----------------------------- a) Write: static void printArray(T[] array) b) Write: static > T findMax(T[] array) c) Write: static int countOccurrences(T[] array, T target) d) Write: static List arrayToList(T[] array) e) Test each with Integer[], String[], and Double[] arrays. Exercise 4: Bounded Types and Wildcards ----------------------------------------- a) Write: static double sum(List list) - Should work with List, List, List b) Write: static void printList(List list) // unbounded c) Write: static double total(List list) // upper bound d) Write: static void addNumbers(List list) // lower bound e) Test each method and observe which calls compile and which don't. ============================================================ PART B: Lambda Expressions [30 minutes] ============================================================ Exercise 5: Basic Lambda Syntax ---------------------------------- a) Define a functional interface: MathOperation with double operate(double a, double b) b) Create lambda implementations for: add, subtract, multiply, divide, power c) Store them in variables and call each. d) Create a method: double calculate(double a, double b, MathOperation op) e) Call calculate() with inline lambda expressions. Exercise 6: Built-in Functional Interfaces --------------------------------------------- Given: List names = Arrays.asList("Ali", "Fatma", "Hassan", "Amina", "Omar", "Zainab"); a) Predicate: filter names longer than 4 characters b) Predicate: filter names starting with "A" c) Chain predicates: names starting with "A" AND longer than 3 chars d) Function: convert each name to its length e) Function: convert to uppercase f) Consumer: print each name with "Hello, " prefix g) Supplier: generate random names from the list Exercise 7: Method References ------------------------------- a) Use String::toUpperCase as a method reference with map() b) Use System.out::println as a method reference with forEach() c) Use Integer::parseInt to convert List to List d) Use String::new (constructor reference) with a stream e) Create a static method and use ClassName::methodName reference Exercise 8: Comparator with Lambda ------------------------------------- Given a list of Student objects (name, gpa, regNo): a) Sort by name: (a, b) -> a.getName().compareTo(b.getName()) b) Sort by GPA descending: Comparator.comparingDouble(Student::getGpa).reversed() c) Sort by name length, then alphabetically: use thenComparing() d) Use Comparator.comparing() with method reference e) Use Comparator.nullsFirst() and Comparator.nullsLast() ============================================================ PART C: Combining Generics and Lambdas [30 minutes] ============================================================ Exercise 9: Generic Filter Method ------------------------------------ a) Write: static List filter(List list, Predicate predicate) b) Use it to filter List (keep even numbers) c) Use it to filter List (keep strings with length > 5) d) Use it to filter List (keep GPA > 3.0) Exercise 10: Generic Transform Method ---------------------------------------- a) Write: static List transform(List list, Function mapper) b) Transform List to List (string lengths) c) Transform List to List (student names) d) Transform List to List (number to words) Exercise 11: Generic forEach ------------------------------ a) Write: static void forEach(List list, Consumer action) b) Print all elements c) Print elements with index: "0: Ali, 1: Fatma, ..." d) Write elements to a file (Consumer that writes to BufferedWriter) Exercise 12: Functional Pipeline ----------------------------------- Build a data processing pipeline: a) Given List of mixed text: names, numbers, and empty strings b) Step 1: Filter out empty/null strings (Predicate) c) Step 2: Trim whitespace (Function) d) Step 3: Convert to uppercase (Function) e) Step 4: Sort by length (Comparator) f) Step 5: Print each with index (Consumer) g) Chain all steps using compose() and andThen() ============================================================ PART D: Challenge [30 minutes] ============================================================ Exercise 13: Generic Repository ---------------------------------- a) Define interface: Repository with save, findById, findAll, delete b) Define interface: Identifiable with ID getId() c) Implement GenericRepository, ID> using HashMap internally d) Create Employee implements Identifiable e) Create repository and perform CRUD operations f) Add a findBy(Predicate) method that uses lambdas for flexible queries ============================================================ SUBMISSION: Submit all .java files in a folder named Lab02_RegNo/ ============================================================