日韩无码专区无码一级三级片|91人人爱网站中日韩无码电影|厨房大战丰满熟妇|AV高清无码在线免费观看|另类AV日韩少妇熟女|中文日本大黄一级黄色片|色情在线视频免费|亚洲成人特黄a片|黄片wwwav色图欧美|欧亚乱色一区二区三区

RELATEED CONSULTING
相關(guān)咨詢
選擇下列產(chǎn)品馬上在線溝通
服務(wù)時間:8:30-17:00
你可能遇到了下面的問題
關(guān)閉右側(cè)工具欄

新聞中心

這里有您想知道的互聯(lián)網(wǎng)營銷解決方案
Java函數(shù)式編程使用方法

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

一. 函數(shù)式編程

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

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

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

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

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

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

2.1 Function

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

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

比如List person里面有age,name…. 我傳入age,他就會返回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是一個謂詞函數(shù),主要作為一個謂詞演算推導(dǎo)真假值存在,返回布爾值的函數(shù)。Predicate等價(jià)于一個Function的boolean型返回值的子集。

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

比如我要過濾年齡 > 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ù),接受一個入?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 基本語法

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

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)€個人的年齡,現(xiàn)在篩選出年齡大于等于18的人。

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

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

原理其實(shí)是:

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

重寫了里面的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);
   }
}

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

四. 總結(jié)

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

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

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

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


分享題目:Java函數(shù)式編程使用方法
瀏覽路徑:http://www.5511xx.com/article/ccschog.html