1. 四大函数式接口(必须掌握)
新时代程序员:lambda表达式、函数式接口、链式编程、Stream流式计算
1.1 函数式接口
@FunctionalInterface
public interface Runnable {
/**
* When an object implementing interface <code>Runnable</code> is used
* to create a thread, starting the thread causes the object's
* <code>run</code> method to be called in that separately executing
* thread.
* <p>
* The general contract of the method <code>run</code> is that it may
* take any action whatsoever.
*
* @see java.lang.Thread#run()
*/
public abstract void run();
}
// 超级多@FunctionalInterface
// 简化编程模型,在新版本的框架底层大量应用!
// foreach(消费者类的函数式接口)
(1)Function函数式接口
Function函数式接口,有一个输入参数,有一个输出。只要是函数式接口,可以用Lambda表达式简化。
public class Demo01 {
public static void main(String[] args) {
Function function = new Function<String,String>() {
@Override
public String apply(String o) {
return o;
}
};
System.out.println(function.apply("adsad"));
}
}
Lambda:
public class Demo01 {
public static void main(String[] args) {
Function<String,String> function = (str)->{return str;};
System.out.println(function.apply("adsad"));
}
}
(2)Predicate 断定型接口
Predicate 断定型接口,有一个参数,返回值只能是布尔值
public class Demo02 {
public static void main(String[] args) {
Predicate<String> predicate = new Predicate<String>() {
@Override
public boolean test(String str) {
return str.isEmpty();
}
};
System.out.println(predicate.test("123"));
}
}
Lambda:
public class Demo02 {
public static void main(String[] args) {
Predicate<String> predicate = (str)->{
return str.isEmpty();
};
System.out.println(predicate.test("123"));
}
}
(3)Consumer 消费型接口
Consumer 消费型接口:只有输入,没有返回值
public class Demo03 {
public static void main(String[] args) {
Consumer<String> consumer = new Consumer<String>() {
@Override
public void accept(String o) {
System.out.println(o);
}
};
consumer.accept("123");
}
}
Lambda:
public class Demo03 {
public static void main(String[] args) {
Consumer<String> consumer = (str)->{
System.out.println(str);
};
consumer.accept("123");
}
}
(4)Supplier 供给型接口
Consumer 消费型接口:没有参数,只有返回值
public class Demo04 {
public static void main(String[] args) {
Supplier<String> supplier = new Supplier<String>() {
@Override
public String get() {
return "ad";
}
};
System.out.println(supplier.get());
}
}
Lambda:
public class Demo03 {
public static void main(String[] args) {
Consumer<String> consumer = (str)->{
System.out.println(str);
};
consumer.accept("123");
}
}
2. Stream流式计算
大数据:存储+计算。
存储:集合、MySQL。
计算:都应该交给流来操作。
public class User {
public static void main(String[] args) {
UserData a = new UserData(1, "a", 21);
UserData b = new UserData(2, "b", 22);
UserData c = new UserData(3, "c", 23);
UserData d = new UserData(4, "d", 24);
UserData e = new UserData(6, "e", 25);
// 集合就是存储
List<UserData> lis = Arrays.asList(a, b, c, d, e);
// 计算交给流 链式编程
lis.stream().filter((u)->{return u.getId()%2 == 0;}).filter(u->{return u.getAge() > 23;}).map(u->{return u.getName().toUpperCase();}).sorted((uu1,uu2)->{
return uu2.compareTo(uu1);
}).limit(1).forEach(System.out::println);
}
}
class UserData{
private int id;
private String name;
private int age;
public UserData(int id, String name, int age) {
this.id = id;
this.name = name;
this.age = age;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
@Override
public String toString() {
return "UserData{" +
"id=" + id +
", name='" + name + '\'' +
", age=" + age +
'}';
}
}
3. ForkJoin 分支合并
ForkJoin 在1.7之后出现的,并行执行任务!提高效率。大数据量!
大数据:Map Reduce(大任务拆分为小任务)
ForkJoin特点:工作窃取
这里面维护的都是双端队列。
public class Demo01 extends RecursiveTask<Long> {
private long start;
private long end;
// 临界值
private long temp = 1000L;
public Demo01(long start, long end) {
this.start = start;
this.end = end;
}
public static void main(String[] args) {
}
@Override
protected Long compute() {
if((end - start) < temp){
Long sum = 0L;
for (Long i = start; i < end; i++) {
sum+=i;
}
return sum;
}else{
long middle = (start + end) /2;
Demo01 demo01 = new Demo01(start, middle);
demo01.fork(); // 拆分任务,把任务压入线程队列
Demo01 demo02 = new Demo01(middle+1, end);
demo02.fork(); // 拆分任务,把任务压入线程队列
long l = demo01.join() + demo02.join();
return l;
}
}
}
测试类:
public class Test1 {
public static void main(String[] args) throws ExecutionException, InterruptedException {
test3();
}
// 普通程序员
public static void test1(){
long start = System.currentTimeMillis();
Long sum = 0L;
for (Long i = 0L; i < 10_1001_1010; i++) {
sum+=i;
}
long end = System.currentTimeMillis();
System.out.println("时间"+(end-start)+",sum="+sum);
}
// 使用ForkJoin
public static void test2() throws ExecutionException, InterruptedException {
long start = System.currentTimeMillis();
Long sum = 0L;
ForkJoinPool forkJoinPool = new ForkJoinPool();
Demo01 demo01 = new Demo01(0L,10_1001_1010);
ForkJoinTask<Long> submit = forkJoinPool.submit(demo01);// 提交任务
Long aLong = submit.get();
long end = System.currentTimeMillis();
System.out.println("时间"+(end-start)+",sum="+aLong);
}
// Stream 并行流
public static void test3(){
long start = System.currentTimeMillis();
long sum = LongStream.rangeClosed(0L, 10_0000_0000).parallel().reduce(0, Long::sum);
long end = System.currentTimeMillis();
System.out.println("时间"+(end-start)+",sum="+sum);
}
}
4. Future异步回调
Future 设计的初衷:对将来的某个事件的结果进行建模
Future 实现类
(1)没有返回值的异步回调
public class Demo01 {
public static void main(String[] args) throws ExecutionException, InterruptedException {
CompletableFuture<Void> completableFuture = CompletableFuture.runAsync(()->{
try {
TimeUnit.SECONDS.sleep(2);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName()+"");
});
System.out.println("1111111");
Void unused = completableFuture.get(); // 阻塞获取执行结果
System.out.println(unused);
}
}
(2)有返回值的异步回调
public class Demo01 {
public static void main(String[] args) throws ExecutionException, InterruptedException {
CompletableFuture<Object> uCompletableFuture = CompletableFuture.supplyAsync(() -> {
System.out.println(Thread.currentThread().getName()+"");
return 1/0;
});
Object s = uCompletableFuture.whenComplete((t, u) -> {
System.out.println("t=>"+t);
System.out.println("u=>"+u);
}).exceptionally((f) -> {
f.printStackTrace();
return "233";
}).get();
System.out.println(s);
}
}