給蘋(píng)果按照重量排序
Collections.sort(lists, new Comparator<Apple>() {
@Override
public int compare(Apple o1, Apple o2) {
return o1.getWeight().compareTo(o2.getWeight());
}
Java8的寫(xiě)法
lists.sort(Comparator.comparing(Apple::getWeight));
Java8對(duì)硬件的影響
Java8之前程序都是單線程的,如果想使用多線程那么需要自行處理并發(fā)她按,雖然很Java提供了線程池和并發(fā)集合牛隅,但使用Java8會(huì)更容易實(shí)現(xiàn)多線程
并行與共享的可變數(shù)據(jù)
寫(xiě)代碼時(shí)不能訪問(wèn)共享的可變數(shù)據(jù),這些函數(shù)成為純函數(shù)或無(wú)狀態(tài)函數(shù)或無(wú)副作用函數(shù)
Stream API
Java8新的API提供了Stream尤溜,它支持許多處理數(shù)據(jù)的并行操作倔叼,從而可以避免使用synchronized
向方法傳遞代碼技巧(方法引用,lambda表達(dá)式)
Java8之前使用匿名內(nèi)部類實(shí)現(xiàn)行為參數(shù)化宫莱,Java8之后使用行為參數(shù)化(通過(guò)API傳遞代碼)不需要?jiǎng)?chuàng)建匿名內(nèi)部類
函數(shù)式編程
將代碼傳遞給方法的功能丈攒,還讓我們能夠使用一整套新技巧
函數(shù)式編程的基石
1,沒(méi)有共享的可變數(shù)據(jù)
2,將方法和函數(shù)傳遞給其他方法的能力
Java中的函數(shù)
程序執(zhí)行期間不能傳遞叫二等公民(方法巡验,類)际插,能傳遞叫一等公民,java8將函數(shù)在運(yùn)行時(shí)傳遞把他編程一等公民
//篩選一個(gè)目錄中隱藏的文件
File[] hiddenFiles1 = new File(".").listFiles(new FileFilter() {
@Override
public boolean accept(File pathname) {
return pathname.isHidden();
}
});
//java8 寫(xiě)法
File[] hiddenFiles2 = new File(".").listFiles(File::isHidden);
方法引用
java8使用 方法引用:: 語(yǔ)法(即吧這個(gè)方法最為值)
使用File::isHidden就創(chuàng)建了一個(gè)方法引用
lambda-匿名函數(shù)
比如(int a) -> x+1
篩選出綠色并且重量大于150克的蘋(píng)果
//篩選綠色蘋(píng)果
public static List<Apple> filterGreenApples(List<Apple> inventory){
List<Apple> result = new ArrayList<>();
for (Apple apple:inventory){
if ("green".equals(apple.getColor())){
result.add(apple);
}
}
return result;
}
//篩選重量超過(guò)150克蘋(píng)果
public static List<Apple> filterHeavyApples(List<Apple> inventory){
List<Apple> result = new ArrayList<>();
for (Apple apple:inventory){
if (apple.getWeight() > 150){
result.add(apple);
}
}
return result;
}
第一版寫(xiě)兩個(gè)方法
可以看出很多代碼都是重復(fù)的显设,變動(dòng)部分只有if判斷我們可以將這部分抽取出來(lái)
public static boolean isGreenApple(Apple apple){
return "green".equals(apple.getColor());
}
public static boolean isHeavyApple(Apple apple){
return apple.getWeight() > 150;
}
public interface Predicate<T t>{
boolean test(T t);
}
static List<Apple> filterApples(List<Apple> inventory,Predicate<Apple> p){
List<Apple> result = new ArrayList<>();
for (Apple apple:inventory){
if (p.test(apple)){
result.add(apple);
}
}
return result;
}
public static void main(String[] args){
filterApples(lists,StreamTest::isGreenApple);
filterApples(lists,StreamTest::isHeavyApple);
}
第二版
我們需要把變化的部分抽取出來(lái)框弛,然后使用函數(shù)引用將變化的部分傳遞到函數(shù)中,這樣就可以防止代碼重復(fù)
filterApples(lists,(Apple apple) -> "green".equals(apple.getColor()));
filterApples(lists,(Apple apple) -> apple.getWeight() > 150);
filterApples(lists,(Apple apple) -> apple.getWeight() < 150 || "brown".equals(apple.getColor()));
第三版
java8中我們可以直接使用lambda表達(dá)式
流
//從一個(gè)列表中篩選金額較高的交易捕捂,然后按貨幣分組
Map<Currency,List<Transaction>> transactionByCurrencies = new HashMap<>();
for (Transaction transaction:transactions){
if (transaction.getPrice() > 1000){
Currency currency = transaction.getCurrency();
List<Transaction> transactionForCurrency = transactionByCurrencies.get(currency);
if (transactionForCurrency == null){
transactionForCurrency = new ArrayList<>();
transactionByCurrencies.put(currency,transactionForCurrency);
}
transactionForCurrency.add(transaction);
}
}
之前的寫(xiě)法很難一眼看出這些代碼是做什么的瑟枫,因?yàn)橛泻脦讉€(gè)嵌套的控制流指令,下面我們使用流來(lái)解決這個(gè)問(wèn)題
Map<Currency,List<Transaction>> transactionByCurrencies2 =
transactions.stream()
.filter((Transaction transaction) -> transaction.getPrice() > 1000)
.collect(Collectors.groupingBy(Transaction::getCurrency));
Java8的實(shí)現(xiàn)非常簡(jiǎn)潔指攒。
我們使用集合要自己去做迭代慷妙,for-each這種迭代是外部迭代,相反允悦,有了Stream API根本就不用操心循環(huán)的事情膝擂。數(shù)據(jù)處理完全是在庫(kù)里內(nèi)部進(jìn)行的。這種思想叫內(nèi)部迭代
并且流可以更好的利用多個(gè)處理器并行處理任務(wù)
Collection是為了存儲(chǔ)和訪問(wèn)數(shù)據(jù)隙弛,而Stream是對(duì)數(shù)據(jù)描述進(jìn)行計(jì)算
將蘋(píng)果篩選問(wèn)題轉(zhuǎn)化成流
順序處理蘋(píng)果篩選為題
List<Apple> heavyApples = lists.stream()
.filter((Apple apple) -> apple.getWeight() > 150)
.collect(Collectors.toList());
并行處理蘋(píng)果篩選問(wèn)題
List<Apple> heavyApple = lists.parallelStream()
.filter((Apple apple) -> apple.getWeight() > 150)
.collect(Collectors.toList());
為保證并行架馋,函數(shù)式編程中主要的意思是,把函數(shù)作為一等值全闷,并且含有第二層意思叉寂,即在執(zhí)行元素之間無(wú)互動(dòng)
接口中默認(rèn)方法
一般是庫(kù)設(shè)計(jì)師使用
Optional<T>
防止出現(xiàn)空指針異常
Java8的新特性
函數(shù)參數(shù)化
lambda表達(dá)式,匿名參數(shù)
流
默認(rèn)方法
Optional
CompletableFuture