JAVA-进阶(函数式编程)
JAVA-进阶(函数式编程)
1.首先理解什么是Lambda表达式?
简单来说,我们定义一个函数,往往要去想怎么调用,怎么创建对象,但是Lambda表达式的思想是,我不用去管你怎么去做这件事情,我只关心你在做什么(有点绕口,多读两边)。我们只是为了达到目的,过程和形式并不重要。
2.代码体现?
以Runnable接口为例:
普通的写法(实现内部类接口)
1 public class Demo01Runnable { 2 public static void main(String[] args) { 3 // 匿名内部类 4 Runnable task = new Runnable() { 5 @Override 6 public void run() { // 覆盖重写抽象方法 7 System.out.println("多线程任务执行!"); 8 } 9 }; 10 new Thread(task).start(); // 启动线程 11 } 12 }
Lambda表达式写法
public class Demo02LambdaRunnable { public static void main(String[] args) { new Thread(() -> System.out.println("多线程任务执行!")).start(); // 启动线程 } }
3.Lambda优越性?
代码简洁,不用去写一大堆对象内部类,另一方面比较重要就是延时(会在下边举例)。
4.Lambda的写法格式?
博主自己总结了一下,简单就是一个接口,只有一个抽象方法。
()->System.out.println(“多线程任务执行!”)看作是一个向上转型的对象就可以了,()代表无参,当然是可以加参数的,参数以逗号隔开,
System.out.println(“多线程任务执行!”)是你实现的抽象方法,在这里也就是run方法。
至于返回值,要看你对抽象方法的定义,该返回什么就返回什么,和普通方法没有区别。
省略格式建议不要用,少两个括号感觉用处不大。
5.函数式接口?
函数式接口,即适用于函数式编程场景的接口。而Java中的函数式编程体现就是Lambda。
首先介绍一个注解@FunctionalInterface,他是放在接口类上的,作用是检查这个接口是不是只有一个抽象方法,当然也可以不写。
1 @FunctionalInterface 2 public interface MyFunctionalInterface { 3 void myMethod(); 4 }
下边再说延时执行
public class Demo01Logger { private static void log(int level, String msg) { if (level == 1) { System.out.println(msg); } } public static void main(String[] args) { String msgA = "Hello"; String msgB = "World"; String msgC = "Java"; log(1, msgA + msgB + msgC); } }
View Code
我们会发现无论我的level等级是多少,字符串msgA + msgB + msgC都会拼接,但是我们想想这样会不会造成一种资源的浪费当level=2时,我完全没必要去拼接字符串,因为字符串是不执行的。所以Lambda的延时执行就体现出来了
@FunctionalInterface public interface MessageBuilder { String buildMessage(); }
View Code
public class Demo02LoggerLambda { private static void log(int level, MessageBuilder builder) { if (level == 1) { System.out.println(builder.buildMessage()); } } public static void main(String[] args) { String msgA = "Hello"; String msgB = "World"; String msgC = "Java"; log(1, () ‐> msgA + msgB + msgC ); } }
View Code
所谓的延时,就是说在我传入接口对象参数时,我没有执行方法体,只有什么时候调用buildMessage()这个方法的时候我才会执行。这就解决了资源浪费问题。
6.常用的函数式接口?
他们都是已经定义好抽象方法的接口
Supplier接口:又称为供应商,不传入参数,但是会返回
java.util.function.Supplier 接口仅包含一个无参的方法: T get() 。用来获取一个泛型参数指定类型的对 象数据。由于这是一个函数式接口,这也就意味着对应的Lambda表达式需要“对外提供”一个符合泛型类型的对象 数据。
import java.util.function.Supplier; public class Demo08Supplier { private static String getString(Supplier<String> function) { return function.get(); } public static void main(String[] args) { String msgA = "Hello"; String msgB = "World"; System.out.println(getString(() ‐> msgA + msgB)); } }
View Code
Consumer接口:又称消费者,传入参数,但无返回
java.util.function.Consumer 接口则正好与Supplier接口相反,它不是生产一个数据,而是消费一个数据, 其数据类型由泛型决定。
import java.util.function.Consumer; public class Demo09Consumer { private static void consumeString(Consumer<String> function) { function.accept("Hello"); } public static void main(String[] args) { consumeString(s ‐> System.out.println(s)); } }
View Code
import java.util.function.Consumer; public class Demo10ConsumerAndThen { private static void consumeString(Consumer<String> one, Consumer<String> two) { one.andThen(two).accept("Hello"); } public static void main(String[] args) { consumeString( s ‐> System.out.println(s.toUpperCase()), s ‐> System.out.println(s.toLowerCase())); } }
View Code
Predicate接口:有时候我们需要对某种类型的数据进行判断,从而得到一个boolean值结果,这时可以使用 java.util.function.Predicate 接口。
import java.util.function.Predicate; public class Demo15PredicateTest { private static void method(Predicate<String> predicate) { boolean veryLong = predicate.test("HelloWorld"); System.out.println("字符串很长吗:" + veryLong); } public static void main(String[] args) { method(s ‐> s.length() > 5); } }
View Code
import java.util.function.Predicate; public class Demo16PredicateAnd { private static void method(Predicate<String> one, Predicate<String> two) { boolean isValid = one.and(two).test("Helloworld"); System.out.println("字符串符合要求吗:" + isValid); } public static void main(String[] args) { method(s ‐> s.contains("H"), s ‐> s.contains("W")); } }
View Code
Function接口:接口用来根据一个类型的数据得到另一个类型的数据,前者称为前置条件, 后者称为后置条件。
import java.util.function.Function; public class Demo11FunctionApply { private static void method(Function<String, Integer> function) { int num = function.apply("10"); System.out.println(num + 20); } public static void main(String[] args) { method(s ‐> Integer.parseInt(s)); } }
View Code
相关文章