java8新特性
1.接口方法默認(rèn)實(shí)現(xiàn):java8中接口方法可以有默認(rèn)實(shí)現(xiàn)秃殉,需要加入default
關(guān)鍵字。
public interface Formula {
double calculate(int a);
default double inc10(int a) {//接口方法默認(rèn)實(shí)現(xiàn)
return a+10;
}
}
2.Lambda表達(dá)式:lambda表達(dá)式本質(zhì)是匿名函數(shù),形如()->{};參數(shù)列表->方法體,對(duì)于功能接口(有且僅有一個(gè)未實(shí)現(xiàn)方法的接口)的實(shí)現(xiàn)停忿,使用lambda會(huì)更簡(jiǎn)潔、優(yōu)雅蚊伞,但是方法體中不能調(diào)用接口的默認(rèn)實(shí)現(xiàn)方法席赂,而其他接口實(shí)現(xiàn)方式的方法體中可以調(diào)用接口的默認(rèn)實(shí)現(xiàn)方法。
例1:
Formula formula = new Formula() {//接口的匿名實(shí)現(xiàn)類
@Override
public double calculate(int a) {
return inc10(a * 5);//可以調(diào)用接口的默認(rèn)實(shí)現(xiàn)方法inc10()
}
};
Formula formula = a -> {return a*5;};//不能調(diào)用接口的默認(rèn)實(shí)現(xiàn)方法inc10()
formula.inc10(10);//實(shí)例可以調(diào)用接口的默認(rèn)實(shí)現(xiàn)
例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實(shí)現(xiàn)
sort方法:jdk1.6前使用歸并排序算法厚柳,1.7后使用Timsort排序算法(Timsort算法見:)
lambda表達(dá)式中的局部變量必須是final氧枣,如果變量未定義未final,lambda會(huì)隱式的將其轉(zhuǎn)換為final别垮,接口匿名實(shí)現(xiàn)相同,如:
int num=10;
Converter<Integer,String> converter=from -> String.valueOf(from+num);//隱式的把num轉(zhuǎn)為final
3.方法調(diào)用運(yùn)算符::
public interface Converter<F,T> {
T converte(F from);
}
Converter str2int=from->{return Integer.valueOf(from);};
//類方法調(diào)用
Converter str2int=Integer::valueOf;//jdk根據(jù)實(shí)參選擇合適的靜態(tài)方法
//實(shí)例方法調(diào)用
StringTool stringTool = new StringTool();
Converter str2int=stringTool::convert;
//構(gòu)造方法調(diào)用
PersonFactory<Person> personFactory=Person::new;//jdk會(huì)選擇合適的構(gòu)造方法實(shí)例化對(duì)象
4.FunctionalInterface(函數(shù)接口/功能性接口):java8中提供了一些函數(shù)接口扎谎,用來(lái)完成特定的操作碳想,常用的有下面幾個(gè)烧董,這些接口上都標(biāo)注了@FunctionalInsterface
,表明這是一個(gè)函數(shù)接口,但是不標(biāo)注也可以胧奔,兩外這些函數(shù)接口中都有很多默認(rèn)方法實(shí)現(xiàn)逊移,用于輔助操作。
- 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>,接受一個(gè)值T龙填,產(chǎn)生一個(gè)結(jié)果R胳泉,接口方法
R apply(T t)
:
Function<String,Integer> s2i=Integer::valueOf;
Function<Integer,Integer> andThenInc10 = from->from+10;//andThen Function在目標(biāo)Function后執(zhí)行,用目標(biāo)Function的輸出作為輸入
Function<Boolean,String> compose2Str = from->{//compose Function在目標(biāo)Function前執(zhí)行岩遗,輸出作為目標(biāo)Function的輸入
if(from){
return "1";
}
return "0";
};
System.out.println(s2i.compose(compose2Str).andThen(andThenInc10).apply(true));
- Supplier<T> 獲取一個(gè)結(jié)果T扇商,像工廠方一樣,接口方法
T get()
:
Supplier<Person> personSupplier =()->new Person();//Person::new
System.out.println(personSupplier.get().toString());
- Consumer<T> 對(duì)輸入的東西進(jìn)行處理宿礁,返回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在目標(biāo)Consumer執(zhí)行完成后執(zhí)行
greeter.andThen(andThenOk).accept(new Person("liu", "jh"));
- Comparator<T> 同源兩個(gè)對(duì)象的處理(比較),接口方法
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在目標(biāo)Comparator后執(zhí)行(但是只有目標(biāo)Comparator沒有比較結(jié)果時(shí)才執(zhí)行梆靖,其實(shí)也就是第二比較維度)
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反轉(zhuǎn)
5.Optional類控汉,對(duì)象可以用該類包裝,避免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時(shí)有效
//鏈?zhǔn)秸{(diào)用不用判斷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對(duì)象,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));//參數(shù)是consumer
map.computeIfPresent(3, (key, val) -> val + key+"aa"); //如果存在key净嘀,則可以對(duì)該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對(duì)應(yīng)值纲辽,key不存在颜武,value為null
7.CompletableFuture、Future:Future描述線程的未來(lái)情況(包括線程未來(lái)產(chǎn)生的數(shù)據(jù)拖吼,線程是否執(zhí)行完成鳞上、取消線程執(zhí)行等信息):
CompletableFuture<Integer> future = CompletableFuture.supplyAsync(() -> {
try {
Thread.sleep(5000L);
}catch (Exception e){
}
return 100;
});
future.join();//需要的時(shí)候阻塞執(zhí)行線程邏輯,如果邏輯有異常吊档,則直接拋出異常篙议,runtimeException
System.out.println(future.get());//需要的時(shí)候阻塞執(zhí)行線程邏輯,拋出check exception
System.out.println(future.getNow(1));//發(fā)起執(zhí)行線程邏輯,但是不阻塞鬼贱,如果線程未執(zhí)行完成移怯,則返回指定的值,否則返回線程產(chǎn)生的值
System.out.println(future.get(3, TimeUnit.SECONDS));//發(fā)起請(qǐng)求这难,并阻塞舟误,希望在給定的時(shí)間內(nèi)的到結(jié)果,如果得不到結(jié)果姻乓,則拋出超時(shí)異常
//創(chuàng)建
1.構(gòu)造方法創(chuàng)建completableFuture,一定要通過complete()設(shè)置返回值嵌溢,或者通過completeExceptionally拋出異常
2.CompletableFuture.completedFuture(T value)創(chuàng)建一個(gè)已有值的completableFuture
public static CompletableFuture<Void> runAsync(Runnable runnable) 沒有executor的,使用ForkJoinPool.commonPool()作為默認(rèn)線程池
public static CompletableFuture<Void> runAsync(Runnable runnable, Executor executor)
public static <U> CompletableFuture<U> supplyAsync(Supplier<U> supplier) Supplier函數(shù)接口產(chǎn)生一個(gè)對(duì)象
public static <U> CompletableFuture<U> supplyAsync(Supplier<U> supplier, Executor executor)
//異步任務(wù)執(zhí)行完成后執(zhí)行 BiConsumer蹋岩、Consumer
public CompletableFuture<T> whenComplete(BiConsumer<? =super T,? super Throwable> action) 和上一個(gè)future用同一個(gè)線程執(zhí)行赖草,結(jié)果是上一個(gè)future的結(jié)果
public CompletableFuture<T> whenCompleteAsync(BiConsumer<? super T,? super Throwable> action) 不和和上一個(gè)future用同一個(gè)線程,但是如果線程池一樣的話星澳,可能會(huì)用到同一個(gè)線程
public CompletableFuture<T> whenCompleteAsync(BiConsumer<? super T,? super Throwable> action, Executor executor)
public CompletableFuture<T> exceptionally(Function<Throwable,? extends T> fn)
//異步任務(wù)執(zhí)行完成后轉(zhuǎn)換
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)
//消費(fèi)
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)
兩個(gè)都消費(fèi)后才算完成
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是純消費(fèi),它的函數(shù)參數(shù)沒有返回值禁偎,而thenCombine的函數(shù)參數(shù)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)
任意一個(gè)執(zhí)行完成就執(zhí)行
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) 所有的都執(zhí)行完成
public static CompletableFuture<Object> anyOf(CompletableFuture<?>... cfs) 任意一個(gè)執(zhí)行完成,object是執(zhí)行完成的返回值
考慮一個(gè)情景:當(dāng)所有的future都執(zhí)行完成后如暖,將所有future的結(jié)果放到一個(gè)集合中笆檀?
public static <T> CompletableFuture<List<T>> sequence(List<CompletableFuture<T>> futures) {
CompletableFuture<Void> allDoneFuture = CompletableFuture.allOf(futures.toArray(new CompletableFuture[futures.size()]));//所有的都執(zhí)行完成
return allDoneFuture.thenApply(v -> {return futures.stream().map(CompletableFuture::join).collect(Collectors.toList());});//牛逼
}
8.時(shí)間的一些操作,參考joda