java8新特性
1.接口方法默认实现:java8中接口方法可以有默认实现,需要加入default
关键字。
public interface Formula {
double calculate(int a);
default double inc10(int a) {//接口方法默认实现
return a+10;
}
}
2.Lambda表达式:lambda表达式本质是匿名函数,形如()->{};参数列表->方法体,对于功能接口(有且仅有一个未实现方法的接口)的实现,使用lambda会更简洁、优雅,但是方法体中不能调用接口的默认实现方法,而其他接口实现方式的方法体中可以调用接口的默认实现方法。
例1:
Formula formula = new Formula() {//接口的匿名实现类
@Override
public double calculate(int a) {
return inc10(a * 5);//可以调用接口的默认实现方法inc10()
}
};
Formula formula = a -> {return a*5;};//不能调用接口的默认实现方法inc10()
formula.inc10(10);//实例可以调用接口的默认实现
例2:
List<Integer> names = Arrays.asList(3,1,2,5);
Collections.sort(names, new Comparator<Integer>() {
@Override
public int compare(Integer a, Integer b) {
return a.compareTo(b);
}
});
Collections.sort(names,(a,b)->a.compareTo(b));//lambda实现
sort方法:jdk1.6前使用归并排序算法,1.7后使用Timsort排序算法(Timsort算法见:)
lambda表达式中的局部变量必须是final,如果变量未定义未final,lambda会隐式的将其转换为final,接口匿名实现相同,如:
int num=10;
Converter<Integer,String> converter=from -> String.valueOf(from+num);//隐式的把num转为final
3.方法调用运算符::
public interface Converter<F,T> {
T converte(F from);
}
Converter str2int=from->{return Integer.valueOf(from);};
//类方法调用
Converter str2int=Integer::valueOf;//jdk根据实参选择合适的静态方法
//实例方法调用
StringTool stringTool = new StringTool();
Converter str2int=stringTool::convert;
//构造方法调用
PersonFactory<Person> personFactory=Person::new;//jdk会选择合适的构造方法实例化对象
4.FunctionalInterface(函数接口/功能性接口):java8中提供了一些函数接口,用来完成特定的操作,常用的有下面几个,这些接口上都标注了@FunctionalInsterface
,表明这是一个函数接口,但是不标注也可以,两外这些函数接口中都有很多默认方法实现,用于辅助操作。
- Predicate<T>(谓词)用于判断 ,接口方法
boolean test(T t)
:
Predicate<String> notBlank=s -> s!=null&&s.length()>0;
System.out.println(notBlank.test("abc"));
Predicate<String> and = s -> s.charAt(0)=='d';
System.out.println(notBlank.and(and).test("abc"));//满足and和notBlank predicate
Predicate<String> nonNull = Objects::nonNull;
Predicate<String> isNull = nonNull.negate();//Object::isNull; nonNull的反面
System.out.println(nonNull.test(""));
- Function<T,R>,接受一个值T,产生一个结果R,接口方法
R apply(T t)
:
Function<String,Integer> s2i=Integer::valueOf;
Function<Integer,Integer> andThenInc10 = from->from+10;//andThen Function在目标Function后执行,用目标Function的输出作为输入
Function<Boolean,String> compose2Str = from->{//compose Function在目标Function前执行,输出作为目标Function的输入
if(from){
return "1";
}
return "0";
};
System.out.println(s2i.compose(compose2Str).andThen(andThenInc10).apply(true));
- Supplier<T> 获取一个结果T,像工厂方一样,接口方法
T get()
:
Supplier<Person> personSupplier =()->new Person();//Person::new
System.out.println(personSupplier.get().toString());
- Consumer<T> 对输入的东西进行处理,返回void,接口方法
void accept(T t)
:
Consumer<Person> greeter = p->System.out.println("Hello, " + p.getFirstName());
Consumer<Person> andThenOk = p->System.out.println("Are you ok?");//andThen Consumer在目标Consumer执行完成后执行
greeter.andThen(andThenOk).accept(new Person("liu", "jh"));
- Comparator<T> 同源两个对象的处理(比较),接口方法
int compare(T o1, T o2)
:
Comparator<Person> comparator = (p1, p2) -> p1.getFirstName().compareTo(p2.getFirstName());
Comparator<Person> thenComparator = (p1, p2) -> p1.getLastName().compareTo(p2.getLastName());//thenComparing Comparator在目标Comparator后执行(但是只有目标Comparator没有比较结果时才执行,其实也就是第二比较维度)
Person p1 = new Person("a", "d");
Person p2 = new Person("b", "d");
System.out.println(comparator.thenComparing(thenComparator).compare(p1, p2));// <0
System.out.println(comparator.reversed().compare(p1, p2)); // > 0 ,reversed反转
5.Optional类,对象可以用该类包装,避免NullPointerException
,参照guava中option:
Optional<String> optional = Optional.ofNullable(null);//of(),empty(),允许为null值,of不允许null值,否则optional定义失败,empty就是null,null不能做get()操作
System.out.println(optional.isPresent());//null false
System.out.println(optional.get());//null NullPointerException
System.out.println(optional.orElse("fallback"));//null时有效
//链式调用不用判断null
optional.map(s -> s).filter(s -> s.contains("b")).ifPresent((s) -> System.out.println(s.indexOf("d")));
6.Stream:filter,sort,map,collection(Collectors.toList/toSet/toMap)/reduce,count,match(anyMatch,allMatch,noneMatch),集合.stteam()可以获得集合的stream对象,map没有stream,但定义了一些操作,如下:
Map<Integer, String> map = new HashMap<>();
for (int i = 0; i < 10; i++) {
map.putIfAbsent(i, "val" + i);//如果没有放入
}
map.forEach((key, val) -> System.out.println(key+"=="+val));//参数是consumer
map.computeIfPresent(3, (key, val) -> val + key+"aa"); //如果存在key,则可以对该MapEntity处理
System.out.println(map.get(3));
map.computeIfAbsent(23, key -> "val" + key);
System.out.println(map.get(23));
map.remove(3, "val3"); //key,value都匹配才删除
map.merge(11, "val9", (value, newValue) ->value.concat(newValue));//如果key不存在,新建,存在更改,value是key对应值,key不存在,value为null
7.CompletableFuture、Future:Future描述线程的未来情况(包括线程未来产生的数据,线程是否执行完成、取消线程执行等信息):
CompletableFuture<Integer> future = CompletableFuture.supplyAsync(() -> {
try {
Thread.sleep(5000L);
}catch (Exception e){
}
return 100;
});
future.join();//需要的时候阻塞执行线程逻辑,如果逻辑有异常,则直接抛出异常,runtimeException
System.out.println(future.get());//需要的时候阻塞执行线程逻辑,抛出check exception
System.out.println(future.getNow(1));//发起执行线程逻辑,但是不阻塞,如果线程未执行完成,则返回指定的值,否则返回线程产生的值
System.out.println(future.get(3, TimeUnit.SECONDS));//发起请求,并阻塞,希望在给定的时间内的到结果,如果得不到结果,则抛出超时异常
//创建
1.构造方法创建completableFuture,一定要通过complete()设置返回值,或者通过completeExceptionally抛出异常
2.CompletableFuture.completedFuture(T value)创建一个已有值的completableFuture
public static CompletableFuture<Void> runAsync(Runnable runnable) 没有executor的,使用ForkJoinPool.commonPool()作为默认线程池
public static CompletableFuture<Void> runAsync(Runnable runnable, Executor executor)
public static <U> CompletableFuture<U> supplyAsync(Supplier<U> supplier) Supplier函数接口产生一个对象
public static <U> CompletableFuture<U> supplyAsync(Supplier<U> supplier, Executor executor)
//异步任务执行完成后执行 BiConsumer、Consumer
public CompletableFuture<T> whenComplete(BiConsumer<? =super T,? super Throwable> action) 和上一个future用同一个线程执行,结果是上一个future的结果
public CompletableFuture<T> whenCompleteAsync(BiConsumer<? super T,? super Throwable> action) 不和和上一个future用同一个线程,但是如果线程池一样的话,可能会用到同一个线程
public CompletableFuture<T> whenCompleteAsync(BiConsumer<? super T,? super Throwable> action, Executor executor)
public CompletableFuture<T> exceptionally(Function<Throwable,? extends T> fn)
//异步任务执行完成后转换
public <U> CompletableFuture<U> thenApply(Function<? super T,? extends U> fn)
public <U> CompletableFuture<U> thenApply(Function<? super T,? extends U> fn,Executor executor)
public <U> CompletableFuture<U> thenApplyAsync(Function<? super T,? extends U> fn)
public <U> CompletableFuture<U> thenApplyAsync(Function<? super T,? extends U> fn, Executor executor)
public <U> CompletableFuture<U> handle(BiFunction<? super T,Throwable,? extends U> fn) 具有whenComplete和thenApply的特性
public <U> CompletableFuture<U> handle(BiFunction<? super T,Throwable,? extends U> fn, Executor executor)
public <U> CompletableFuture<U> handleAsync(BiFunction<? super T,Throwable,? extends U> fn)
public <U> CompletableFuture<U> handleAsync(BiFunction<? super T,Throwable,? extends U> fn, Executor executor)
//消费
public CompletableFuture<Void> thenAccept(Consumer<? super T> action)
public CompletableFuture<Void> thenAcceptAsync(Consumer<? super T> action)
public CompletableFuture<Void> thenAcceptAsync(Consumer<? super T> action, Executor executor)
两个都消费后才算完成
public CompletableFuture<Void> thenAcceptBoth(Consumer<? super T> action)
public CompletableFuture<Void> thenAcceptBothAsync(Consumer<? super T> action)
public CompletableFuture<Void> thenAcceptBothAsync(Consumer<? super T> action, Executor executor)
同thenAcceptBoth,只不过thenAcceptBoth是纯消费,它的函数参数没有返回值,而thenCombine的函数参数fn有返回值。
public <U,V> CompletableFuture<V> thenCombine(CompletionStage<? extends U> other, BiFunction<? super T,? super U,? extends V> fn)
public <U,V> CompletableFuture<V> thenCombineAsync(CompletionStage<? extends U> other, BiFunction<? super T,? super U,? extends V> fn)
public <U,V> CompletableFuture<V> thenCombineAsync(CompletionStage<? extends U> other, BiFunction<? super T,? super U,? extends V> fn, Executor executor)
任意一个执行完成就执行
public CompletableFuture<Void> acceptEither(CompletionStage<? extends T> other, Consumer<? super T> action)
public CompletableFuture<Void> acceptEitherAsync(CompletionStage<? extends T> other, Consumer<? super T> action)
public CompletableFuture<Void> acceptEitherAsync(CompletionStage<? extends T> other, Consumer<? super T> action, Executor executor)
public <U> CompletableFuture<U> applyToEither(CompletionStage<? extends T> other, Function<? super T,U> fn)
public <U> CompletableFuture<U> applyToEitherAsync(CompletionStage<? extends T> other, Function<? super T,U> fn)
public <U> CompletableFuture<U> applyToEitherAsync(CompletionStage<? extends T> other, Function<? super T,U> fn, Executor executor)
public static CompletableFuture<Void> allOf(CompletableFuture<?>... cfs) 所有的都执行完成
public static CompletableFuture<Object> anyOf(CompletableFuture<?>... cfs) 任意一个执行完成,object是执行完成的返回值
考虑一个情景:当所有的future都执行完成后,将所有future的结果放到一个集合中?
public static <T> CompletableFuture<List<T>> sequence(List<CompletableFuture<T>> futures) {
CompletableFuture<Void> allDoneFuture = CompletableFuture.allOf(futures.toArray(new CompletableFuture[futures.size()]));//所有的都执行完成
return allDoneFuture.thenApply(v -> {return futures.stream().map(CompletableFuture::join).collect(Collectors.toList());});//牛逼
}
8.时间的一些操作,参考joda