四大函数式接口
函数式接口: 只有一个方法的接口
@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();
}
forEach(消费者类的函数式接口)
Function函数式接口
import java.util.ArrayList;
import java.util.List;
import java.util.function.Function;
public class MyInterface {
public static void main(String[] args) {
List list = new ArrayList<String>();
/* Function<String,String> function = new Function<String,String>(){
@Override
public String apply(String o) {
return o;
}
};*/
Function<String,String> function=( str)->{
return str;
};
// lambd simple
System.out.println(function.apply("9"));
}
}
简化开发
断定型接口 Predicate
@Test
public void test1(){
// 判断字符串是否为"Mon"
/* Predicate<String> predicate = new Predicate<String>() {
@Override
public boolean test(String s) {
return "Mon".equals(s);
}
};
*/
Predicate<String> predicate = str->{return "Mon".equals(str);};
System.out.println(predicate.test("Mon"));
}
供给型接口 Supplier
@Test
public void test2(){
/* Supplier supplier= new Supplier<String>() {
@Override
public String get() {
return "优越";
}
};*/
Supplier supplier = ()->{
return "优越";
};
System.out.println(supplier.get());
}
消费型接口 Consumer
@Test
public void test2(){
/* Consumer consumer = new Consumer<String>() {
@Override
public void accept(String o) {
System.out.println("收到的参数是"+ o);
}
};*/
Consumer<String> consumer = (o)->{
System.out.println("收到的参数是"+ o);
};
consumer.accept("hahh");
}
- 注解补充
@Target({ElementType.METHOD}) 指定注解针对的地方,它是一个元注解(官方自带的注解,无需自己定义)
ElementType:
ElementType.METHOD 针对方法
public enum ElementType {
/** Class, interface (including annotation type), or enum declaration */
TYPE,
/** Field declaration (includes enum constants) */
FIELD,//针对成员变量
/** Method declaration */
METHOD,//针对成员方法
/** Formal parameter declaration */
PARAMETER,//方法参数
/** Constructor declaration */
CONSTRUCTOR,//构造器
/** Local variable declaration */
LOCAL_VARIABLE,
/** Annotation type declaration */
ANNOTATION_TYPE,//注解
/** Package declaration */
PACKAGE,
/**
* Type parameter declaration
*
* @since 1.8
*/
TYPE_PARAMETER,
/**
* Use of a type
*
* @since 1.8
*/
TYPE_USE
}
@Retention 指定注解的保留域
Stream流式计算
存储+计算
集合、mysql本质是存储,计算交给流来做
现在有5个用户,需要用一行代码完成下面的筛选
- id必须是偶数
- 年龄大于等于21岁
- 用户名转为大写字母
- 用户名按照倒数字典序排序
- 只输出一个用户
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.lang.reflect.Array;
import java.util.Arrays;
import java.util.Comparator;
import java.util.List;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.stream.Stream;
@Data
@AllArgsConstructor
@NoArgsConstructor
public class User {
private int id;
private String name;
private int age;
}
class Problem{
public static void main(String[] args) {
/*
现在有5个用户,需要用一行代码完成下面的筛选
* */
User u1 = new User(1,"a",20);
User u2 = new User(2,"b",21);
User u3 = new User(3,"c",22);
User u4 = new User(4,"d",23);
User u5 = new User(5,"e",24);
List<User> users = Arrays.asList(u1, u2, u3, u4, u5);
// 把集合变为流
Stream<User> stream = users.stream();
stream
.filter((user)->{return user.getId()%2==0;})
.filter((user)->{return user.getAge()>=21;})
.map((user)->{ user.setName(user.getName().toUpperCase());return user;})
.sorted((o1,o2)->{
return o2.getName().compareTo(o1.getName());
}).limit(1)
.forEach(System.out::println);
/* users.forEach((o)->{
System.out.println(o);
});*/
/*
users.forEach(new Consumer<User>() {
@Override
public void accept(User user) {
System.out.println(user);
}
});
*/
}
}
使用到了上面的4大函数式接口
ForkJoin详解
在数据量比较大的情况下,并行执行任务,效率高
类比于大数据中的map reduce (把大任务拆分成小任务再合并)
ForkJoin特点: 工作窃取
B线程先执行完之后可以将A线程的任务偷一点过来执行
里面维护的都是双端队列
import org.junit.Test;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ForkJoinPool;
import java.util.concurrent.ForkJoinTask;
import java.util.concurrent.RecursiveTask;
import java.util.stream.LongStream;
public class ForkJoinDemo extends RecursiveTask<Long> {
private Long sta;
private Long end;
private Long temp =1_0000L;
public ForkJoinDemo(Long sta, Long end) {
this.sta = sta;
this.end = end;
}
// 计算方法
@Override
protected Long compute() {
if ((end-sta)<temp){
Long ans=0l;
for(Long i =sta;i<=end;++i)
ans+=i;
return ans;
}else{
// fork join
long mid = (sta+end)/2;
ForkJoinDemo task1 = new ForkJoinDemo(sta,mid);
//拆分任务,把任务压入线程队列
task1.fork();
ForkJoinDemo task2 = new ForkJoinDemo(mid+1,end);
task2.fork();
return (Long) task1.join()+ (Long) task2.join();
}
}
}
class Demo{
public static void main(String[] args) {
test1();
// 301 时间 500000000500000000
// test2();3900 时间 500000000500000000
// test3();180 时间 500000000500000000
}
public static void test1(){
long start = System.currentTimeMillis();
long ans =0l;
for (long i =1l;i<=10_0000_0000;++i)
ans+=i;
long end = System.currentTimeMillis();
System.out.println(end-start+" 时间 "+ans);
}
public static void test2(){
Long start = System.currentTimeMillis();
ForkJoinPool forkJoinPool = new ForkJoinPool();
ForkJoinDemo forkJoinDemo = new ForkJoinDemo(0l,10_0000_0000l);
ForkJoinTask submit = forkJoinPool.submit(forkJoinDemo);
// 提交
Object o=0l;
try {
o = submit.get();
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
Long end = System.currentTimeMillis();
System.out.println(end-start+" 时间 "+o);
}
public static void test3(){
Long start = System.currentTimeMillis();
// 返回一个并行的等效流
long sum = LongStream.rangeClosed(0l, 10_0000_0000l).parallel().reduce(0, Long::sum);
Long end = System.currentTimeMillis();
System.out.println(end-start+" 时间 "+sum);
}
}
异步回调
类似于ajax,异步调用
- 异步执行
- 成功回调
- 失败回调
public static void main(String[] args) throws ExecutionException, InterruptedException {
// 发起一个请求
// 1. 返回值为空 用void伪类型
/* CompletableFuture<Void> voidCompletableFuture = CompletableFuture.runAsync(()->{
// try {
// TimeUnit.SECONDS.sleep(2);
// } catch (InterruptedException e) {
// e.printStackTrace();
// }
System.out.println(Thread.currentThread().getName()+"runAsync");
});
TimeUnit.SECONDS.sleep(3);
System.out.println("111");
//获取阻塞结果
System.out.println(voidCompletableFuture.get());*/
// 2.有返回值的异步回调
// 返回的是错误信息
CompletableFuture<Integer> completableFuture = CompletableFuture.supplyAsync(()->{
System.out.println(Thread.currentThread().getName()+"supplyAsync");
int i = 1/0;
return 0;
});
/* completableFuture.whenComplete(new BiConsumer<Integer, Throwable>() {
@Override
public void accept(Integer t, Throwable u) {
System.out.println("t-->"+t);
System.out.println("u-->"+u);
//正常执行t有自定的返回值 错误执行u返回错误信息
}
}).exceptionally(new Function<Throwable, Integer>() {
@Override
public Integer apply(Throwable throwable) {
System.out.println(throwable.getMessage());
return 345;
}
}).get();*/
// 可以用函数式接口简化为
System.out.println(completableFuture.whenComplete((t, u) -> {
System.out.println("t-->" + t);
System.out.println("u-->" + u);
}).exceptionally((e) -> {
System.out.println(e.getMessage());
return 345;
}).get());
}
就像网页一样
没有找到页面返回404
服务器内部错误返回500