1 四大函数式接口
函数式接口:只有一个抽象方法的接口,只要是函数式接口,就可以用lambda表达式简化
例如Runnable:
@FunctionalInterface
public interface Runnable {
public abstract void run();
}
框架底层大量应用函数式接口,用来简化编程模型。
1.1 Function
Function函数式接口:该接口用到两个参数,一个是输入参数,一个是输出参数
@FunctionalInterface
public interface Function<T, R> {
R apply(T t);
...
}
📌 demo
public class demo1 {
public static void main(String[] args) {
//匿名内部类
Function function = new Function<String,String>(){
@Override
public String apply(String s) {
return s;
}
};
// //lambda表达式
Function<String,String> function = (str) ->{return str;};
System.out.println(function.apply("AAA"));
}
}
1.2 Predicate
Predicate断定型接口:有一个输入参数,返回值只能是布尔值
@FunctionalInterface
public interface Predicate<T> {
boolean test(T t);
...
}
📌 demo
public class demo2 {
public static void main(String[] args) {
//判断字符串是否为空
Predicate<String> predicate = new Predicate<String>() {
@Override
public boolean test(String str) {
return str.isEmpty();
}
};
Predicate<String> predicate =(str)->{return str.isEmpty();};
System.out.println(predicate.test(""));
}
}
1.3 Predicate
Predicate消费型接口:只有输入,没有返回值
@FunctionalInterface
public interface Consumer<T> {
void accept(T t);
...
}
📌 demo
public class demo3 {
public static void main(String[] args) {
//匿名内部类
Consumer<String> consumer = new Consumer<String>(){
@Override
public void accept(String str) {
System.out.println(str);
}
};
//lambda表达式
Consumer<String> consumer = (str)->{
System.out.println(str);
};
consumer.accept("AAA");
}
}
1.4 Predicate
Predicate供给型接口:没有参数,但有返回值
@FunctionalInterface
public interface Supplier<T> {
T get();
}
📌 demo
public class demo4 {
public static void main(String[] args) {
Supplier<String> supplier = new Supplier<String>() {
@Override
public String get() {
return "1024";
}
};
Supplier<String> supplier = ()->{return "1024";};
supplier.get();
}
}
2 ForkJoin
📌 要点
ForkJoin是JDK1.7之后推出,用来并行执行任务!用于提高效率,适用大数据量的场景。
ForkJoin将复杂的计算当做一个任务,将其分解为多个计算并当做一个个子任务来并行执行
工作窃取:ForkJoin将某个大任务分解为若干互不依赖的子任务,这些子任务分别放到不同的队列里,每个队列创建一个单独的线程来执行队列里的任务,线程和队列一一对应;那么会出现这么一种情况:某些线程执行较快,其他线程则还在干活,因此工作窃取机制就来了--干完活的线程会从其他线程的队列里窃取一个任务来执行,同时双端队列允许两个线程同时访问一个线程。
📌 使用forkjoin
forkjoinPool通过它来执行
计算任务forkjoinPool.execute(ForkJoinTask task)
计算类继承RecursiveTask(RecursiveTask继承至ForkJoinTask)
//计算类
public class ForkJoinDemo extends RecursiveTask<Long> {
private long start;
private long end;
//临界值
private long temp = 10000L;
public ForkJoinDemo(long start,long end){
this.start = start;
this.end = end;
}
@Override
protected Long compute() {
if ((end-start)<temp){
long sum = 0L;
for (long i = start;i <= end;i++){
sum += i;
}
return sum;
}else {//forkjoin
long middle = (start+end)/2;//中间值
ForkJoinDemo task1 = new ForkJoinDemo(start,middle);
task1.fork();//拆分任务,把任务压入线程队列
ForkJoinDemo task2 = new ForkJoinDemo(middle+1,end);
task2.fork();//拆分任务,把任务压入线程队列
return task1.join()+task2.join();
}
}
}
📌 求和三种方式
因为前两种方式我用的long数据类型,所以计算会快一些。
public class ForkJoinTest {
public static void main(String[] args) throws ExecutionException, InterruptedException {
common(); //263
forkJoin(); //140
stream();//232
}
//1、普通程序员
public static void common(){
long sum = 0;
long start = System.currentTimeMillis();
for (long i = 1L; i <= 10_0000_0000; i++) {
sum += i;
}
long end = System.currentTimeMillis();
System.out.println("sum = "+sum+" 时间:"+(end - start));
}
//2、使用ForkJoin
public static void forkJoin() throws ExecutionException, InterruptedException {
long start = System.currentTimeMillis();
ForkJoinPool forkJoinPool = new ForkJoinPool();
ForkJoinTask<Long> task = new ForkJoinDemo(1L,10_0000_0000L);
ForkJoinTask<Long> submit =forkJoinPool.submit(task);
long sum = submit.get();
long end = System.currentTimeMillis();
System.out.println("sum = "+sum+" 时间:"+(end - start));
}
//3、stream并行流
public static void stream() throws ExecutionException, InterruptedException {
long start = System.currentTimeMillis();
//reduce:将流中元素反复结合起来,得到一个值,下边也可简化为.reduce(Long::sum)--调用Long类中的sum方法
OptionalLong sum1 = LongStream.rangeClosed(1L,10_0000_0000L).parallel().reduce((a, b)->a+b);
long end = System.currentTimeMillis();
System.out.println("sum = "+sum1.getAsLong()+" 时间:"+(end - start));
}
}