

3分钟入门lambda表达式
source link: http://www.cnblogs.com/nedulee/p/12520362.html
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

本节是lambda表达式的一个入门课,讲解的同时配有练习demo
前言
lambda表达式是java8推出的一个新特性。标志着从jdk1.8开始,java正式支持函数式编程。使用lambda表达式可以用简洁流畅的代码完成一个功能,这也在一定程度上,可以减轻了java一直为人诟病的代码简洁性问题。
什么是lambda表达式?
lambda表达式可以简单理解为一段可以传递的代码,核心思想是将面向对象中传递数据变为传递行为。下面举一个编写线程的例子。
1Runnable runnable = new Runnable() { 2 @Override 3 public void run() { 4 System.out.println("hello lambda"); 5 } 6};
这里使用的是匿名内部类的方式。匿名内部类实现的也是将代码作为数据传递,不过使用匿名内部类还是不够简洁,那么使用lambda表达式的代码是什么样的呢?
1Runnable runnable = () -> System.out.println("hello lambda");
我们可以看到使用lambda表达式实现起来非常的简单,只需要一行代码即可,接下来我们就试着分析一下这段代码。
基础语法

我们可以将lambda表达式整体看作是一个函数,()存放的是函数的操作数 ->指向的是函数的逻辑,可以用{}包裹起来。
函数式接口
我们可以看到上述的示例代码,lambda表达式的引用变量是一个runnable类型,事实上,java为我们提供了多种变量类型供我们选择,这些类型我们称之为函数式接口。
函数式接口是只有一个方法的接口,用作lambda表达式的类型。比如我们之前提到的Runnable接口
1@FunctionalInterface 2public interface Runnable { 3 /** 4 * When an object implementing interface <code>Runnable</code> is used 5 * to create a thread, starting the thread causes the object's 6 * <code>run</code> method to be called in that separately executing 7 * thread. 8 * <p> 9 * The general contract of the method <code>run</code> is that it may 10 * take any action whatsoever. 11 * 12 * @see java.lang.Thread#run() 13 */ 14 public abstract void run(); 15}
我们可以看到interface上一个注解@FunctionInterface,它的作用是告诉编译器这个接口是一个函数式接口。
自己实现一个函数式接口
我们可以自己实现一个函数式接口,判断数据的数据是否合法
1/** 2 * 自定义函式数接口 3 * 4 * @author jialin.li 5 * @date 2020-03-18 14:22 6 */ 7@FunctionalInterface 8public interface CustomFunctionInterface<T> { 9 boolean legal(T t); 10}
测试方法:
1/** 2 * 测试. 3 * 4 * @author jialin.li 5 * @date 2020-03-18 14:23 6 */ 7public class Test { 8 9 public boolean legal(int value, CustomFunctionInterface<Integer> functionInterface){ 10 return functionInterface.legal(value); 11 } 12 13 public static void main(String[] args) { 14 System.out.println(new Test().legal(-8, (x) -> x >= 0)); 15 } 16}
测试结果:
1false
jdk提供的函数式接口
jdk在java.util.function中为我们提供了非常丰富的函数式接口,大致可以分为4类:

接下来我们会针对这四种不同的接口,给出相应的demo,你也可以先看题目,自己尝试写一下
Consumer
将输入的10进制数,转换为2进制数输出
1public void toBinaryString(int value, Consumer<Integer> consumer){ 2 consumer.accept(value); 3} 4 5public static void main(String[] args) { 6 new Test().toBinaryString(15, (x) -> System.out.println(Integer.toBinaryString(x))); 7}
supplier
生成n个随机数100以内的随机数,以数组的形式返回
1public int[] getRandomArr(int n, Supplier<Integer> supplier) { 2 int[] arr = new int[n]; 3 for (int i = 0; i < n; i++) { 4 arr[i] = supplier.get(); 5 } 6 return arr; 7} 8 9public static void main(String[] args) { 10 int[] arr = new Test().getRandomArr(10, () -> new Random().nextInt(100)); 11 System.out.println(Arrays.toString(arr)); 12}
function
生成一个[1,n]组成的阶乘数组,例如输入3,返回[1,4,9]
1public int[] getFactorialArr(int n, Function<Integer,Integer> function) { 2 int[] arr = new int[n]; 3 for (int i = 1; i <= n; i++) { 4 arr[i - 1] = function.apply(i); 5 } 6 return arr; 7} 8 9public static void main(String[] args) { 10 int[] arr = new Test().getFactorialArr(10, (x) -> x*x); 11 System.out.println(Arrays.toString(arr)); 12}
Predicate
判断一个数是否是偶数
1public boolean isEven(int n, Predicate<Integer> predicate) { 2 return predicate.test(n); 3} 4 5public static void main(String[] args) { 6 boolean isEven = new Test().isEven(1102, (x) -> (x % 2 == 0)); 7 System.out.println(isEven); 8}
其他场景
除了上述的4个接口,java.util.function中还有许多其他的接口,可以实现各种功能。比如实现2个数的加法运算:
1public static void main(String[] args) { 2 BinaryOperator<Integer> binaryOperator = Integer::sum; 3 System.out.println(binaryOperator.apply(1, 3)); 4}
实现List遍历:
1public static void main(String[] args) { 2 List<String> list = new ArrayList<>(Arrays.asList("java", "python", "go", "sql")); 3 list.forEach(System.out::println); 4}
更多场景还请您去探索,感受函数式编程的魅力吧
最后,期待您的订阅和点赞,专栏每周都会更新,希望可以和您一起进步,同时也期待您的批评与指正!

Recommend
About Joyk
Aggregate valuable and interesting links.
Joyk means Joy of geeK