函数式编程(Lambda+函数编程接口+Stream)
JDK8 Lambda
简易说明
()-> System.out.println(“Lambda 创建了一个线程”)
() 指的是参数的括号
System.out.println(“Lambda 创建了一个线程”) 指的是方法体
// 正常创建线程的方式
new Thread(new Runnable() {
@Override
public void run() {
System.out.println("Normal 创建了一个线程!");
}
}).start();
// Lambda表达式创建一个线程
new Thread(()-> System.out.println("Lambda 创建了一个线程")).start();
定义
特性
应用
函数编程接口
我们看一下Runnable接口
@FunctionalInterface
public interface Runnable {
public abstract void run();
}
@FunctionalInterface
指的是这个接口是一个函数编程接口接口
定义
- 类型是接口
- 有且只有一个抽象方法
手写示例
示例1
@FunctionalInterface
interface InterDemoA{
void doSth();
}
public class FunctionDemo {
void doSth(InterDemoA interDemoA){
System.out.print("Function A");
interDemoA.doSth();
}
public static void main(String[] args) {
FunctionDemo functionDemo = new FunctionDemo();
functionDemo.doSth(()-> System.out.println(" do Sth"));
}
}
// 执行结果:Function A do Sth
示例2
说明:
当出现方法重载情况
需要指定参数类型,否者报错
@FunctionalInterface
interface InterDemoA{
void doSth();
}
@FunctionalInterface
interface InterDemoB{
void doSth();
}
public class FunctionDemo {
void doSth(InterDemoA interDemoA){
System.out.print("Function A");
interDemoA.doSth();
}
void doSth(InterDemoB interDemoB){
System.out.print("Function B");
interDemoB.doSth();
}
public static void main(String[] args) {
FunctionDemo functionDemo = new FunctionDemo();
functionDemo.doSth((InterDemoB)()-> System.out.println(" do Sth"));
functionDemo.doSth((InterDemoA)()-> System.out.println(" do Sth"));
}
}
重要的函数接口(JDK8常用的函数接口)
java.util.function包下有jdk的函数接口
常用接口
- Supplier
- Consumer
- Function
- UnaryOperator
- BiFunction
使用示例
public class JdkFunctionDemo {
public static void main(String[] args) {
// Supplier T get(); 没有输入 只有一个输输出
Supplier<String> supplier = ()->"this is Supplier demo";
System.out.println(supplier.get());
//Consumer void accept(T t); 只有一个输入 没有输出
Consumer<String> consumer = i -> System.out.println("this is demo for "+i);
consumer.accept("Consumer");
// Function<T,R> R apply(T t); 输入T 输出R
Function<Integer, Integer> function = i -> i*i;
System.out.println("Function demo:"+function.apply(9));
//UnaryOperator<T> 输入输出都是T
UnaryOperator<Integer> unaryOperator = i -> i*i;
System.out.println("UnaryOperator demo:"+unaryOperator.apply(8));
//BiFunction<T,U,R> R apply(T t, U u); 输入U,T 输出R
BiFunction<Integer,Integer,String> biFunction = (i,j) -> i+"*"+j+"="+i*j;
System.out.println(biFunction.apply(7, 8));
}
}
JDK8 Stream编程
定义
JAVA8 中流表示的是元素的序列
流的创建
public class StreamOperateDemo {
public static void main(String[] args) {
String[] arr = {"张三","","李四","","王五","赵柳","嘿嘿","白给","噶你捏","沙雕","百川","羲和","日暮"};
// 1.数组创建
Arrays.stream(arr).forEach(System.out::println);
// 2.list
Arrays.asList(arr).stream().forEach(System.out::println);
// 3. Stream.of()
Stream.of(arr).forEach(System.out::println);
// 4.迭代器 打印1-10元素
Stream.iterate(1,i->i+1).limit(10).forEach(System.out::println);
// 5.generate打印10个随机数
Stream.generate(()->new Random().nextInt(10)).limit(10).forEach(System.out::println);
}
}
流编程实例
public class StreamOperateDemo2 {
public static void main(String[] args) {
/*
* JDK8 流编程完整示例
* 元素的中间操作与终止操作
*
* 结果依次b,e,l,o
* bo_le -> bole ->字符转成新的流(b o l e) -> sorted -> (b e l o)
*
*/
String[] arr = {"张三","","李四","","王五","赵柳","嘿嘿","bo_le","噶你捏","沙雕","百川","羲和","bo_le"};
Stream.of(arr)
// 过滤空元素
.filter(i -> !i.isEmpty())
// 过滤重复元素
.distinct()
// 排序
.sorted()
.limit(1)
.map(i->i.replace("_",""))
.flatMap(i->Stream.of(i.split("")))
.sorted()
// 流编程中,终止操作只能有一个,中间操作可以是0-N个
// .findFirst()
//流编程中 必须有一个终止操作
//.peek(i -> System.out.println(i));
.forEach(System.out::println);
}
}
非短路终止操作需要遍历完所有元素
短路终止操作不需要遍历完所有元素