av激情亚洲男人的天堂国语,日韩欧美精品一中文字幕,无码av一区二区三区无码,国产又色又爽又刺激的a片,国产又色又爽又刺激的a片

Java函數(shù)式編程使用方法

函數(shù)式編程functional programming(FP)要么是一種理念先進(jìn)的、應(yīng)該廣泛傳播的程序設(shè)計(jì)方法;要么是一種偏學(xué)術(shù)性的、實(shí)際用途不多的編程方式,下面為大家講解一下Java函數(shù)式編程使用方法。

一. 函數(shù)式編程

Java8所有的新特性基本基于函數(shù)式編程的思想,函數(shù)式編程的帶來(lái),給Java注入了新鮮的活力。

下面來(lái)近距離觀察一下函數(shù)式編程的幾個(gè)特點(diǎn): ?函數(shù)可以作為變量、參數(shù)、返回值和數(shù)據(jù)類型。 ?基于表達(dá)式來(lái)替代方法的調(diào)用 ?函數(shù)無(wú)狀態(tài),可以并發(fā)和獨(dú)立使用 ?函數(shù)無(wú)副作用,不會(huì)修改外部的變量 ?函數(shù)結(jié)果確定性;同樣的輸入,必然會(huì)有同樣的結(jié)果。 下面jdk1.8里面對(duì)函數(shù)式編程的定義。只是一個(gè) FunctionalInterface 接口。特別的簡(jiǎn)單。

1 @Documented
2 @Retention(RetentionPolicy.RUNTIME)
3 @Target(ElementType.TYPE)
4 public @interface FunctionalInterface {}

這個(gè)函數(shù)式接口有幾點(diǎn)以下的限制: ?唯一的抽象方法,有且僅有一個(gè) (即所有的函數(shù)式接口,有且只能有一個(gè)抽象方法) ?加上標(biāo)注,則會(huì)觸發(fā)JavaCompiler的檢查。對(duì)于符合函數(shù)接口的接口,加不加都無(wú)關(guān)緊要,但是加上則會(huì)提供一層編譯檢查的保障。如果不符合,則會(huì)報(bào)錯(cuò)。 ?不能被覆蓋之后,再聲明為抽象方法,則不算抽象方法。例如接口實(shí)現(xiàn)了Object中的方法。 ?可用于lambda類型的使用方式

二. Java8新增函數(shù)式接口

Stream的操作是建立在函數(shù)式接口的組合之上的。Java8中新增的函數(shù)式接口都在java.util.function包下。這些函數(shù)式接口可以有多種分類方式。

2.1 Function

Function是從T到R的一元映射函數(shù)。將參數(shù)T傳遞給一個(gè)函數(shù),返回R。即R = Function(T)

Function最常用的應(yīng)該是 Stream map(Function mapper);

比如List person里面有age,name…. 我傳入age,他就會(huì)返回age的集合給我。

@FunctionalInterface
public interface Function {

   R apply(T t);

   default  Function compose(Function before) {
       Objects.requireNonNull(before);
       return (V v) -> apply(before.apply(v));
   }

   default  Function andThen(Function after) {
       Objects.requireNonNull(after);
       return (T t) -> after.apply(apply(t));
   }

   static  Function identity() {
       return t -> t;
   }
}

2.2 Predicate

Predicate是一個(gè)謂詞函數(shù),主要作為一個(gè)謂詞演算推導(dǎo)真假值存在,返回布爾值的函數(shù)。Predicate等價(jià)于一個(gè)Function的boolean型返回值的子集。

predicate最常用的莫過(guò)于 Stream filter(Predicate predicate);

比如我要過(guò)濾年齡 > 18 的人,我傳入age,判斷是否為true。為true則保留,false丟棄。

@FunctionalInterface
public interface Predicate
{

boolean test(T t);

default Predicate and(Predicate other) {
Objects.requireNonNull(other);
return (t) -> test(t) && other.test(t);
}

default Predicate negate() {
return (t) -> !test(t);
}

default Predicate or(Predicate other) {
Objects.requireNonNull(other);
return (t) -> test(t) || other.test(t);
}

static Predicate isEqual(Object targetRef) {
return (null == targetRef)
? Objects::isNull
: object -> targetRef.equals(object);
}
}

2.3 Consumer

Consumer是從T到void的一元函數(shù),接受一個(gè)入?yún)⒌环祷厝魏谓Y(jié)果的操作。

Consumer最常用的肯定是 default void forEach(Consumer action) {}

這是一段forEach循環(huán)的代碼,傳入實(shí)現(xiàn)的方法,并不返回任何值。只是循環(huán)。

@FunctionalInterface
public interface Consumer {

   void accept(T t);

   default Consumer
andThen(Consumer after) { Objects.requireNonNull(after); return (T t) -> { accept(t); after.accept(t); }; } }

三. Lambda表達(dá)式

3.1 基本語(yǔ)法

Lambda 的基本結(jié)構(gòu)為 (arguments) -> body,有如下幾種情況: ?參數(shù)類型可推導(dǎo)時(shí),不需要指定類型,如 (a) -> System.out.println(a) ?當(dāng)只有一個(gè)參數(shù)且類型可推導(dǎo)時(shí),不強(qiáng)制寫(xiě) (), 如 a -> System.out.println(a) ?參數(shù)指定類型時(shí),必須有括號(hào),如 (int a) -> System.out.println(a) ?參數(shù)可以為空,如 () -> System.out.println(“hello”) ?body 需要用 {} 包含語(yǔ)句,當(dāng)只有一條語(yǔ)句時(shí) {} 可省略

3.2 Lambda原理

比如如下代碼:

List list = new ArrayList();

list.stream().filter((x) -> x >= 18)

Stream filter(Predicate predicate);

@FunctionalInterface
public interface Predicate {

   boolean test(T t);

}

比如List里面存?zhèn)€個(gè)人的年齡,現(xiàn)在篩選出年齡大于等于18的人。

此時(shí)我們就可以用 list.stream().filter((x) -> x >= 18) 這就是一個(gè)典型的lambda表達(dá)式

(x) -> x >= 18 傳給 Predicate 函數(shù)式接口。

原理其實(shí)是:

JVM幫我們動(dòng)態(tài)生成了一個(gè)內(nèi)部類,然后這個(gè)內(nèi)部類實(shí)現(xiàn)了 Predicate 這個(gè)函數(shù)式接口。

重寫(xiě)了里面的test方法。生成的類似如下:

static final class Main$$Lambda$1 implements Predicate {
   private Main$$Lambda$1() {
   }

   @Override
   public boolean test(Integer x) {
       return x >= 18;
   }
}

3.3 Lambda用法

public class Main {
   public static void main(String[] args) {

       List list = new ArrayList();
       list.add(40);
       list.add(50);
       list.add(20);
       list.add(30);
       List collect = list.stream().filter(x -> x >= 30)
               .map((x) -> x + 10).sorted((x, y) -> -x.compareTo(y))
               .collect(Collectors.toList());
       System.out.println(collect);
   }
}

這個(gè)一段很典型的Lambda + Stream的用法。 ?list.stream()獲取list的stream的流 ?filter篩選出年齡大于30的人 (里面是一個(gè)Predicate接口,返回真假) ?map做一個(gè)function映射 ?sort排序,里面是compartor

四. 總結(jié)

Lambda 表達(dá)式可以減少很多代碼,能提高生產(chǎn)力。但也要理解其原理。比如3.3中的代碼,為什么filter里面是斷言表達(dá)式,map里面是function表達(dá)式。

這都要從lambda的原理入手,也就是JVM動(dòng)態(tài)生成一個(gè)內(nèi)部類,并繼承其中的抽象方法。

本次主要介紹了Java函數(shù)式編程的原理以及應(yīng)用,主要從Stream和lambda入手。通過(guò)一些簡(jiǎn)單的概念,以及代碼,更好的理解Java的函數(shù)式編程。

掌握J(rèn)ava的函數(shù)式編程,對(duì)平時(shí)我們開(kāi)發(fā)代碼,看其他人的代碼,都有很大的幫助。


網(wǎng)頁(yè)標(biāo)題:Java函數(shù)式編程使用方法
文章鏈接:http://uogjgqi.cn/article/ccschog.html
掃二維碼與項(xiàng)目經(jīng)理溝通

我們?cè)谖⑿派?4小時(shí)期待你的聲音

解答本文疑問(wèn)/技術(shù)咨詢/運(yùn)營(yíng)咨詢/技術(shù)建議/互聯(lián)網(wǎng)交流