Java Assignment- 4
Inner classes, Lambdas & functional interfaces
Basic Questions
- Write a class with a member inner class that prints a greeting using a field from the outer class. Create an object of the inner class and call its method.
- Write a class with a static nested class that has a static utility method sum(int a, int b). Call this method from main and print the result.
- Write a method that defines a local inner class Helper inside it. The local class should print a message and a local variable value. Call the local class from inside the method.
- Create an anonymous inner class of Runnable that prints “Task running” in its run() method, and start it using a Thread.
- Create an interface ClickListener with method onClick(). Use an anonymous inner class to implement it once and call onClick().
- Define a functional interface MathOp with one abstract method apply(int a, int b). Use a lambda to add two numbers and print the result.
- Use java.util.function.Consumer<Integer> with a lambda to print the square of each number in an int[].
- Use java.util.function.Predicate<String> with a lambda to test if a string starts with “A”. Read a word from the user and print the test result.
- Use java.util.function.Function<String, Integer> with a lambda to return the length of a string. Print the length for “Java” and “Programming”.
- Create a class Book and override toString() to return a clear, human-readable description. Create an object and print it.
- Create a class Pair with fields x and y. Override toString() so printing the object shows (x, y) format. Demonstrate it in main.
- Create a class User with fields id and name. Override equals() so two users are equal if their id matches. Test equality for two objects with the same id.
- In the User class from the previous question, also override hashCode() to be consistent with equals(). Print the hash codes of two equal users to show they match.
- Create a class User with fields id and name. Override equals() so users are equal if id matches, and override hashCode() consistently. Create two different objects with the same id, print equals() result and both hashCode() values, and explain in a comment why equal objects should have the same hash code (no sets or maps).
- Create a simple class Point with x and y (primitives). Make it cloneable using Cloneable and override clone(). Create a clone and print both objects.
- Change the clone’s x in the previous question. Print both Point objects to show they are different objects and changing one does not change the other.
- Create a class Item with a String name. Create two different Item objects with the same name. Print the result of == and equals() (after overriding equals() to compare by name) to show the difference between reference equality and value equality.
- Write code that creates many short-lived objects in a loop and then sets references to null. Call System.gc() after the loop and print a message before and after the call.
- Create a class that overrides finalize() to print a message when the object is about to be collected. Create and drop a reference, then call System.gc(). (Note: finalize() is deprecated and may not run.)
- Create a class with a static counter and an instance field label. Increase the counter in the constructor. Create three objects and print each object’s label and the final static counter.
Intermediate Questions
- Create an outer class with a private field secret. Add a member inner class that can read and print secret. Show that the inner class can access the private field.
- Create a class with both a member inner class and a static nested class. Show with simple code that the static nested class cannot access the outer class’s non-static fields directly.
- Write a method validateEmail(String s) that declares a local inner class Validator with a method isValid(). Use a very simple rule (e.g., presence of ‘@’) and print valid/invalid.
- Define an abstract class Handler with method handle(String msg). Create an anonymous inner class of Handler in main that prints the message with a prefix, and call handle().
- Sort a String[] names = {“Rajat”,”Shreya”,”Priya”,”Dev”} in reverse alphabetical order without Comparator or collections. Implement a simple nested-loop (e.g., selection/bubble sort) and print the result.
- Write a method int[] filterEven(int[] a) that returns a new array containing only even numbers from a. First count how many evens, then allocate exactly that size, copy them, and return. Do not use generics or collections.
- Sort a String[] words by length (shortest first) using a manual nested-loop sort (swap by comparing words[i].length()). Print the sorted array. Do not use Comparator.
- Use Function<Integer, Integer> with andThen to first double a number and then add 3. Apply it to 5 and print the result.
- Use two Predicate<String> lambdas and combine them with and and or to test strings that both start with “A” and end with “Z” (and then either condition). Print test results.
- Given int[] nums = {2,4,6,8}, print each element using an enhanced for loop. Do not use forEach, method references, or collections.
- Create a base class Person and subclass Student. Override toString() in both. In Student.toString(), call super.toString() and add extra info. Print a Student to see the full text.
- Create a class Product with fields code and price. Override equals()/hashCode() so products with the same code are equal. Put several products (including duplicates by code) into a Product[], then write a method int countUniqueByCode(Product[] arr) that counts unique products by scanning the array and comparing with equals() (no sets or maps).
- Write code that checks equals() against null and against an object of a different class. Ensure your equals() returns false in both cases and does not throw an exception.
- Create a class Address and a class Person that has an Address field. Implement shallow clone using super.clone() and show that after cloning, changing the Address inside the clone also changes it in the original.
- Extend the previous question to implement a deep clone for Person by also cloning Address. Show that changing the clone’s Address does not affect the original.
- Write code that calls clone() on a class that does not implement Cloneable, catches CloneNotSupportedException, and prints a friendly message.
- Print memory stats using Runtime.getRuntime() (totalMemory(), freeMemory()) before and after creating many objects and after System.gc(). Print the numbers.
- Create a class that overrides finalize() to log a message. In comments, note that finalize() is deprecated and should not be used in new code. Show a minimal example anyway.
- Create a class Key with field code (case-insensitive identity) and class Entry with fields Key key and String value. Override equals()/hashCode() in Key using code.toLowerCase(). Store Entry objects in an Entry[], implement String get(Entry[] arr, Key k) that linearly searches with equals() and returns the matching value. Retrieve a value using a new but equal Key.
- Create a simple factory that returns either an anonymous inner class or a lambda implementing a functional interface Greeter. Ask the user for a choice and call greet() accordingly.
Advanced Questions
- Create a tiny calculator using only arrays. Define a functional interface MathOp { int apply(int a,int b); }. Keep String[] names = {“add”,”sub”,”mul”,”div”} and MathOp[] ops = { (a,b)->a+b, (a,b)->a-b, (a,b)->a*b, (a,b)->a/b }. Read a name and two numbers, find the index with a loop, and run ops[index]. No collections or generics.
- Create an event system with an interface Listener { void onEvent(String e); }. Allow registering listeners using both anonymous inner classes and lambdas. Fire an event and show all listeners are called.
- Create an outer class Cache with a static nested class Entry and a member inner class Cleaner. Use the cleaner to remove entries older than a given time. Show both nested types working together.
- Create a class Report with fields String title and String[] notes. Implement a deep clone: copy the notes array elements into a new array. After cloning, change the clone’s notes and show the original is unaffected.
- Create CaseInsensitiveKey (field code). Override equals()/hashCode() using lowercase code. Implement a tiny key-value store using Entry[] (like in the Intermediate replacement): put(Entry[] arr, CaseInsensitiveKey k, String v) replaces value if an equal key exists; otherwise appends into the first null slot. Show that putting “ABC” then “abc” overwrites the previous value. No maps.
- Create a class Version with field name. First implement correct equals() and hashCode(). Write boolean contains(Version[] arr, Version v) that scans with equals(). Show it finds duplicates. Then (in commented code) show an incorrect equals() (e.g., compares hashCode() only) and explain in comments how a wrong equality breaks logic—even without collections.
- Generate an int[] of 50,000 random numbers. Measure and print the time for Arrays.sort(numsCopy1) and for your own insertion sort on numsCopy2. Print both durations. No comparators, no collections.
- Write code that shows lambda capture rules: create a local variable, use it inside a lambda, and try (commented line) to modify it after the lambda is created. Add comments explaining why the modification is not allowed.
- Create Shape → Rectangle/Circle. Override equals()/hashCode() based on dimensions and override toString(). Write Shape[] arr with duplicates and a method Shape[] unique(Shape[] arr) that returns a new array without duplicates using linear scans and equals(). Print before and after.
- Create many short-lived objects into an Object[] (e.g., temporary wrappers), then set the array elements to null, call System.gc(), and print timestamps before/after. Also create a class TempResource that implements AutoCloseable and use it in a try-with-resources block to show modern cleanup. (Note: finalize() is deprecated; mention this in a comment if you include it.)