Scott の 博客 Scott の 博客
首页
  • Data Structure and Algorithm
  • Java
  • 面试
  • Drafts
  • C++
  • 前端文章

    • JavaScript
  • 学习笔记

    • 《JavaScript教程》
    • 《JavaScript高级程序设计》
    • 《Vue》
    • 《React》
    • 《TypeScript 从零实现 axios》
    • 《Git》
    • TypeScript
    • JS设计模式总结
  • HTML
  • CSS
  • 技术文档
  • GitHub技巧
  • Nodejs
  • 博客搭建
  • 学习
  • 面试
  • 心情杂货
  • 实用技巧
  • 友情链接
关于
收藏
  • 分类
  • 标签
  • 归档
GitHub (opens new window)

Scott

恋爱中
首页
  • Data Structure and Algorithm
  • Java
  • 面试
  • Drafts
  • C++
  • 前端文章

    • JavaScript
  • 学习笔记

    • 《JavaScript教程》
    • 《JavaScript高级程序设计》
    • 《Vue》
    • 《React》
    • 《TypeScript 从零实现 axios》
    • 《Git》
    • TypeScript
    • JS设计模式总结
  • HTML
  • CSS
  • 技术文档
  • GitHub技巧
  • Nodejs
  • 博客搭建
  • 学习
  • 面试
  • 心情杂货
  • 实用技巧
  • 友情链接
关于
收藏
  • 分类
  • 标签
  • 归档
GitHub (opens new window)
  • Data Structure and Algorithm

  • Java

    • Java基础知识&面试题总结
    • Java
    • Control Flow
    • Clean Coding
    • Debugging and Deployment
    • Untitled
    • Refactor towards OOSD
    • Inheritance
    • Untitled
    • Exceptions
    • Generics
    • Collections
    • Lambda-Expression
      • Functional Interfaces
      • Anonymous Inner Classes
      • Lambda Expressions
      • Variable Capture
      • Method References
      • Built-in Functional Interfaces
      • The Consumer Interfaces
      • Chaining Consumer
      • The Supplier Interface
      • The Function Interface
      • Composing Functions
      • The Predicate Interface
      • Combining Predicates
      • The BinaryOperator Interface
      • The UnaryOperator Interface
    • Streams
    • Concurrency and Multi-threading
    • The Executive Framework
    • 4
    • 1
  • c++

  • 面试

  • Bilibili_Java

  • Python

  • All kinds of Drafts

  • High Integrity Information System

  • 左神算法课

  • 个人笔记
  • Java
Scott
2022-06-14
目录

Lambda-Expression

  1. Functional Interfaces
  2. Anonymous Inner Classes
  3. Lambda Expressions
  4. Variable Capture
  5. Method References
  6. Built-in Functional Interfaces
  7. The Consumer Interfaces
  8. Chaining Consumer
  9. The Supplier Interface
  10. The Function Interface
  11. Composing Functions
  12. The Predicate Interface
  13. Combining Predicates
  14. The BinaryOperator Interface
  15. The UnaryOperator Interface

# Functional Interfaces

  • A functional interface is an interface with a single abstract method
  • A functional interface represent a function
  • It doesn't matter if we have many default or even static methods in our interface, as long as we have a single abstract method, we refer to it as a functional interface
  • e.g. Comparable Interface
    • Only abstract method:compareTo(T o)
public interface Printer {
    void print(String message);
}

// this is unnecessary
public class ConsolePrinter implements Printer {
    @Override
    public void print(String message) {
        System.out.println(message);
    }
}

public class LambdasDemo {
    public static void show() {
        greet(new ConsolePrinter());
    }
    
    public static void greet(Printer printer) {
        printer.print("Hello world");
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21

# Anonymous Inner Classes

  • Write less code, but not enough, that's why we have lambda expression
public class LambdasDemo {
    public static void show() {
        // this is the anonymous inner class
        // it doesn't have a name 
        greet(new Printer() {
            @Override
            public void print(String message) {
                System.out.println(message);
            }
        });
    }
}
1
2
3
4
5
6
7
8
9
10
11
12

# Lambda Expressions

  • By using lambda expression, it can be implemented in a standalone function
    • A function exists on its on without belonging to a class
  • It is like an anonymous function that we can pass around
public class LambdasDemo {
    public static void show() {
        // it know the type of message
        // if only one parametor, don't need use parenthesis
        greet(message -> { System.out.println(message)});
            
        // or 
        // lambda expressions are essentially objects 
        //  and can be used to represent anonymous in ner classes 
        Printer printer = message -> System.out.println(message);
    }
}
1
2
3
4
5
6
7
8
9
10
11
12

# Variable Capture

  • One of the differences between Lambda Expression and Anonymous Inner Classes:
    • Lambda Expression:
      • this references the enclosing object
      • We cannot have fields because it just represent an anonymous function
        • So we cannot have instance fields here and cannot store state here
      • We can only access the local variables declared in the closing object as well the static or instance fields in the class
    • Anonymous Inner Classes:
      • this references the current instance of the anonymous inner class
      • It can have state, they can have field to store some data
public class LambdasDemo {
    public String prefix = "-";
    
    public void show() {    
        greet(message -> { System.out.println(this.prefix + message)});
    }
}
1
2
3
4
5
6
7

# Method References

  • Makes code more compact and easier to read
  • Sometimes all we do in a lambda expression is just passing the parameter to an existing method
  • Therefore, it's easier to reference the method directly: (three parts)
    • ClassName/the object that contains this method
    • ::
    • name of the method without parenthesis
  • With this method references, we can reference static or instance methods, as well as constructors
public class LambdasDemo {
    public static void output(String message) {}
    
    public void out(String message){}
    
    public LambdasDemo(String message) {}
    
    public static void show() {
        greet(message -> { System.out.println(message)});
        // simpler way: 
    	greet(System.out::print);
        
        // it is a static method 
        greet(message -> output(message));
        // becomes:
        greet(LambdasDemo::output)
            
        // it is an instance method 
        var demo = new LambdasDemo();
        greet(message -> demo.out(message));
        // becomes 
        greet(demo::out);
        
        // for constructor 
        greet(message -> new LambdasDemo(message));
        // becomes
        greet(LambdasDemo::new);
    }
    
    
    
    public static void greet(Printer printer) {
        printer.print("Hello world");
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35

# Built-in Functional Interfaces

  • Java provides many predefined functional interfaces that we can use to perform common tasks
  • These interfaces are declared injava.util.function
  • There are four types of functional interfaces
    • Consumer
    • Supplier
    • Function
    • Predicate

# The Consumer Interfaces

  • It represents an operation that takes a single argument and returns no results
  • It is called Consumer, because it consumes a value
  • BiConsumer takes two values
  • IntConsumer takes int values (more efficient when dealing with a large number of numbers)
  • e.g. void consume(obj)
// it just consumes 
public interface Printer {
    void print(String message);
}
1
2
3
4
public class LambdasDemo {
    public void show() {    
        List<Integer> list = List.of(1, 2, 3);
        // first way: imperative programming: implementing logic using instructions
        // 	(for, if/else, switch/case)
        for (var item : list)
            System.out.println(item);
        
        // second way: declarative programming 
        //  instead of specifying how things should be done 
        // 	we specify what is to be done
        // it expects a consumer object  
        list.forEach(item - > System.out.println(item));
         
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16

# Chaining Consumer

public class LambdasDemo {
    public void show() {    
        List<String> list = List.of("a", "b", "c");
        Consumer<String> print = item -> System.out.println(item);
        
        Consumer<String> printUpperCase = item -> System.out.println(item.toUpperCase());
        
        // print three times
        list.forEach(print.andThen(printUpperCase).andThen(print));
        
    }
}
1
2
3
4
5
6
7
8
9
10
11
12

# The Supplier Interface

  • It is the opposite of the Consumer Interface
  • It represents an operation that takes no input and returns a value so it supplies a value
  • e.g.obj supply()
public class LambdasDemo {
    public void show() {    
        List<String> list = List.of("a", "b", "c");
        Supplier<Double> geRandom = () -> {return Math.Random()};
        Supplier<Double> geRandom = () -> Math.Random();
        var random = getRandom.get();
    }
}
1
2
3
4
5
6
7
8
  • Lazy Evaluation: function is not executed until we explicitly call it

# The Function Interface

  • The function interface represents a function that can map a value to a different value
  • e.g. obj map(obj)
public class LambdasDemo {
    public void show() {    
        Function<String, Integer> map = str -> str.length();
        var length = map.apply("Sky");
    }
}
1
2
3
4
5
6

# Composing Functions

public class LambdasDemo {
    public void show() {    
        // "key:value"
        // first: "key=value"
        // second: "{key=value}"
        Function<String, String> replaceColon = str -> str.replace(":", "=");
        Function<String, String> addBraces = str -> "{" + str + "}";
        
        // Decarative Programming 
        var result = replaceColon
            		 .andThen(addBraces)
            	     .apply("key:value"); 
        
        // second way in reverse order
        result = addBraces.compose(replaceColon).apply("key:value");
        
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18

# The Predicate Interface

  • The Predicate Interface represents an operation that takes an object and checks to see if the object satisfies some criteria
  • e.g. boolean test(condition)
  • kind
    • BiPredicate
    • IntPredicate
public class LambdasDemo {
    public void show() {    
        Predicate<String> isLongerThan5 = str -> str.length() > 5;
        var result = IslongerThan5.test("sky");
    }
}
1
2
3
4
5
6

# Combining Predicates

public class LambdasDemo {
    public void show() {    
        Predicate<String> hasLeftBrace = str -> str.startsWith("{");
        Predicate<String> hasRightBrace = str -> str.endssWith("}");
        // && || !
        Predicate<String> hasLeftAndRightBraces = hasLeftBrace.and(hasRightBrace);
        Predicate<String> hasLeftOrRightBraces = hasLeftBrace.or(hasRightBrace);
        Predicate<String> hasEitherLeftOrRightBraces = hasLeftBrace.negate(hasRightBrace);
        
        var result = hasLeftAndRightBraces.test("{}"); // true
    }
}
1
2
3
4
5
6
7
8
9
10
11
12

# The BinaryOperator Interface

  • It extends from the BiFunction<T,T,T> interface
    • It takes two types of type T and returns a result of type T
public class LambdasDemo {
    public void show() { 
        // more efficient to use the BinaryOperator, since parameters are primitive integers and need to be boxed 
        BinaryOperator<Integer> add = (a, b) -> a + b;
        
        var result = add.apply(1, 2);
        
        Function<Integer, Integer> square = a -> a * a;
        
        var result2 = add.andThen(square).apply(1, 2);
    }
}
1
2
3
4
5
6
7
8
9
10
11
12

# The UnaryOperator Interface

  • It takes a value of type T and returns a result of type T
public class LambdasDemo {
    public void show() { 
        UnaryOperator<Integer> square = n -> n * n;
        UnaryOperator<Integer> increment = n -> n + 1; 
        
        var result = increment.andThen(square).apply(1);
    }
}
1
2
3
4
5
6
7
8
上次更新: 2022/12/04, 16:55:22
Collections
Streams

← Collections Streams→

最近更新
01
day01-Java基础语法
08-31
02
1
08-29
03
路线
08-01
更多文章>
Theme by Vdoing | Copyright © 2019-2022 Evan Xu | MIT License
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式
×