STUDYECRAT Java :  Functional Interface 
    
    
      
      60s
    
  
          Java  Functional Interface 
        
        Prove your skills in this interactive quiz
Live Code
Run snippets directly
Timed
60s per question
Scored
Earn 3D badges
★ Java 8 Functional Interfaces: Key Interview Points
1. The Big Four Functional Interfaces
      Function<String, Integer> strToInt = Integer::parseInt;
Predicate<String> isLong = s -> s.length() > 10;
Consumer<String> printer = System.out::println;
Supplier<Double> random = Math::random;
// Each serves distinct purpose: transform, test, consume, supply
    Predicate<String> isLong = s -> s.length() > 10;
Consumer<String> printer = System.out::println;
Supplier<Double> random = Math::random;
// Each serves distinct purpose: transform, test, consume, supply
- Tip: Prefer primitive variants (IntPredicate) when working with primitives for better performance
 - Real Use: Stream.filter() uses Predicate, Stream.map() uses Function
 
2. Method Reference Nuances
      List<String> names = Arrays.asList("A", "B", "C");
names.forEach(System.out::println); // Instance method
Function<String, String> upper = String::toUpperCase; // Bound instance
BiFunction<String, String, String> concat = String::concat; // Unbound instance
// :: syntax adapts to functional interface context
    names.forEach(System.out::println); // Instance method
Function<String, String> upper = String::toUpperCase; // Bound instance
BiFunction<String, String, String> concat = String::concat; // Unbound instance
// :: syntax adapts to functional interface context
- Tip: Class::method can mean either static method or instance method depending on context
 - Real Use: Optional.ifPresent() often uses System.out::println
 
3. Function Composition
      Function<Integer, Integer> square = x -> x * x;
Function<Integer, String> toString = Object::toString;
// Execution order differences:
Function<Integer, String> a = square.andThen(toString); // square → toString
Function<Integer, String> b = toString.compose(square); // square → toString
// andThen vs compose direction matters!
    Function<Integer, String> toString = Object::toString;
// Execution order differences:
Function<Integer, String> a = square.andThen(toString); // square → toString
Function<Integer, String> b = toString.compose(square); // square → toString
// andThen vs compose direction matters!
- Tip: Debug composition chains with peek(): x -> { System.out.println(x); return x; }
 - Real Use: Spring's functional WebFlux uses composition heavily
 
4. Avoiding Auto-boxing
      // Standard vs primitive versions:
Function<Integer, Integer> f1 = x -> x * 2; // Boxed
IntUnaryOperator f2 = x -> x * 2; // Primitive
LongPredicate isEven = l -> l % 2 == 0; // Better than Predicate<Long>
// Primitive variants prevent costly boxing
    Function<Integer, Integer> f1 = x -> x * 2; // Boxed
IntUnaryOperator f2 = x -> x * 2; // Primitive
LongPredicate isEven = l -> l % 2 == 0; // Better than Predicate<Long>
// Primitive variants prevent costly boxing
- Tip: Look for ToIntFunction, DoubleConsumer, etc. in performance-critical code
 - Real Use: Stream.sum() uses primitive streams (IntStream) internally
 
5. Creating Your Own
      @FunctionalInterface
interface TriFunction<A,B,C,R> {
R apply(A a, B b, C c);
}
TriFunction<String, Integer, Boolean, String> tri =
(s,i,b) -> s + i + b;
// @FunctionalInterface enforces single abstract method
    interface TriFunction<A,B,C,R> {
R apply(A a, B b, C c);
}
TriFunction<String, Integer, Boolean, String> tri =
(s,i,b) -> s + i + b;
// @FunctionalInterface enforces single abstract method
- Tip: Always annotate with @FunctionalInterface to prevent accidental method additions
 - Real Use: Java's BiFunction is insufficient for 3+ parameters
 
💡 Pro Interview Tip
      When asked about functional interfaces, always mention the four key variants (Function, Predicate, Consumer, Supplier) and demonstrate composition. Interviewers love seeing candidates who can chain operations like filter.map.reduce fluently.
    

