Inner Classes
Member Inner Classes
public class OuterClass {
public static void main(String[] args) {
// Accessing member inner class from member method
OuterClass outer = new OuterClass();
outer.processData();
// Direct access to member inner class
OuterClass.InnerClass inner = new OuterClass().new InnerClass();
inner.displayInfo();
}
private String identifier = "Global Identifier";
public void processData() {
InnerClass innerRef = new InnerClass();
System.out.println(innerRef.localIdentifier);
}
public class InnerClass {
private String localIdentifier = "Local Identifier";
public void displayInfo() {
String tempVar = "Temporary Value";
// Accessing local variable
System.out.println(tempVar);
// Accessing inner class member
System.out.println(this.localIdentifier);
// Accessing outer class member
System.out.println(OuterClass.this.identifier);
}
}
}
Local Inner Classes
public class ContainerClass {
public static void main(String[] args) {
ContainerClass container = new ContainerClass();
container.executeOperation();
}
public void executeOperation() {
int counter = 0;
class LocalInnerClass {
public void performTask() {
System.out.println(counter); // Local variable must be effectively final
}
}
new LocalInnerClass().performTask();
}
}
Lambda Expressions
public class LambdaDemo {
public static void main(String[] args) {
Integer[] values = {10, 20, 5, 15, 25, 8, 12, 18};
List<integer> numberList = new ArrayList<>();
Collections.addAll(numberList, values);
// Lambda expression requirements: interface must have exactly one abstract method
// Parentheses can be omitted when there's only one parameter
// Braces, return, and semicolon can be omitted for single-line expressions
// Parameter types can be omitted when type can be inferred from context
Collections.sort(numberList, (x, y) -> y.compareTo(x));
System.out.println("Sorted in descending order: " + numberList);
}
}
</integer>
Fnuctional Intefraces
@FunctionalInterface // Ensures the interface has exactly one abstract method
public interface CustomFunction {
void execute();
}
public class FunctionalInterfaceDemo {
public static void main(String[] args) {
FunctionalInterfaceDemo demo = new FunctionalInterfaceDemo();
// Functional interfaces often used as method parameters or return values
// Functional interface reference == lambda expression
// Functional interface reference.method(params) == lambda expression body
// Double colon (::) syntax:
// param->(object, class, super, this).method(param) == (object, class, super, this)::method
// param->new Class(param) == Class::new
// System.out.println(demo.getStringSupplier(() -> "Hello"));
// demo.processString("Test",
// input -> System.out.println("Processing: " + input),
// input -> System.out.println("Final result: " + input));
// System.out.println(demo.validateString("Test",
// input -> input.length() > 3,
// input -> input.startsWith("T")));
System.out.println(demo.transformString("Java Programming",
input -> input.replace(" ", "_")));
}
public String getStringSupplier(Supplier<string> supplier) {
return supplier.get();
}
public void processString(String text, Consumer<string> processor1, Consumer<string> processor2) {
processor1.andThen(processor2).accept(text);
}
public boolean validateString(String text, Predicate<string> validator1, Predicate<string> validator2) {
return validator1.or(validator2).test(text);
}
public String transformString(String input, Function<string string=""> transformer) {
return transformer.apply(input);
}
}
</string></string></string></string></string></string>
Stream API
public class StreamProcessing {
public static void main(String[] args) {
// Intermediate operations (return Stream): filter, map, limit, skip
// Terminal operations: forEach, count
List<string> names = new ArrayList<>();
names.add("Alice");
names.add("Bob");
names.add("Charlie");
names.add("David");
names.add("Eve");
names.add("Frank");
names.stream()
.map(name -> name + " Smith") // Transform elements
.limit(4) // Limit to first 4 elements
.skip(1) // Skip first element
.filter(name -> name.startsWith("B")) // Filter elements
.forEach(name -> System.out.println(name)); // Process elements
System.out.println("Total elements: " + names.stream().count());
List<integer> numbers = new ArrayList<>();
numbers.add(100);
numbers.add(200);
numbers.add(300);
Stream extends Serializable> combinedStream = Stream.concat(names.stream(), numbers.stream());
combinedStream.forEach(item -> System.out.println("Combined: " + item));
}
}
</integer></string>