欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

java中functional interface的分類和使用詳解

 更新時間:2020年04月11日 09:32:36   作者:flydean  
這篇文章主要介紹了java中functional interface的分類和使用,本文通過實例代碼給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下

java 8引入了lambda表達式,lambda表達式實際上表示的就是一個匿名的function。

在java 8之前,如果需要使用到匿名function需要new一個類的實現(xiàn),但是有了lambda表達式之后,一切都變的非常簡介。

我們看一個之前講線程池的時候的一個例子:

//ExecutorService using class
 ExecutorService executorService = Executors.newSingleThreadExecutor();
 executorService.submit(new Runnable() {
  @Override
  public void run() {
  log.info("new runnable");
  }
 });

executorService.submit需要接收一個Runnable類,上面的例子中我們new了一個Runnable類,并實現(xiàn)了它的run()方法。

上面的例子如果用lambda表達式來重寫,則如下所示:

//ExecutorService using lambda
 executorService.submit(()->log.info("new runnable"));

看起是不是很簡單,使用lambda表達式就可以省略匿名類的構(gòu)造,并且可讀性更強。

那么是不是所有的匿名類都可以用lambda表達式來重構(gòu)呢?也不是。

我們看下Runnable類有什么特點:

@FunctionalInterface
public interface Runnable

Runnable類上面有一個@FunctionalInterface注解。這個注解就是我們今天要講到的Functional Interface。

Functional Interface

Functional Interface是指帶有 @FunctionalInterface 注解的interface。它的特點是其中只有一個子類必須要實現(xiàn)的abstract方法。如果abstract方法前面帶有default關(guān)鍵字,則不做計算。

其實這個也很好理解,因為Functional Interface改寫成為lambda表達式之后,并沒有指定實現(xiàn)的哪個方法,如果有多個方法需要實現(xiàn)的話,就會有問題。

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

Functional Interface一般都在java.util.function包中。

根據(jù)要實現(xiàn)的方法參數(shù)和返回值的不同,Functional Interface可以分為很多種,下面我們分別來介紹。

Function:一個參數(shù)一個返回值

Function接口定義了一個方法,接收一個參數(shù),返回一個參數(shù)。

@FunctionalInterface
public interface Function<T, R> {

 /**
 * Applies this function to the given argument.
 *
 * @param t the function argument
 * @return the function result
 */
 R apply(T t);

一般我們在對集合類進行處理的時候,會用到Function。

Map<String, Integer> nameMap = new HashMap<>();
 Integer value = nameMap.computeIfAbsent("name", s -> s.length());

上面的例子中我們調(diào)用了map的computeIfAbsent方法,傳入一個Function。

上面的例子還可以改寫成更短的:

Integer value1 = nameMap.computeIfAbsent("name", String::length);

Function沒有指明參數(shù)和返回值的類型,如果需要傳入特定的參數(shù),則可以使用IntFunction, LongFunction, DoubleFunction:

@FunctionalInterface
public interface IntFunction<R> {

 /**
 * Applies this function to the given argument.
 *
 * @param value the function argument
 * @return the function result
 */
 R apply(int value);
}

如果需要返回特定的參數(shù),則可以使用ToIntFunction, ToLongFunction, ToDoubleFunction:

@FunctionalInterface
public interface ToDoubleFunction<T> {

 /**
 * Applies this function to the given argument.
 *
 * @param value the function argument
 * @return the function result
 */
 double applyAsDouble(T value);
}

如果要同時指定參數(shù)和返回值,則可以使用DoubleToIntFunction, DoubleToLongFunction, IntToDoubleFunction, IntToLongFunction, LongToIntFunction, LongToDoubleFunction:

@FunctionalInterface
public interface LongToIntFunction {

 /**
 * Applies this function to the given argument.
 *
 * @param value the function argument
 * @return the function result
 */
 int applyAsInt(long value);
}

BiFunction:接收兩個參數(shù),一個返回值

如果需要接受兩個參數(shù),一個返回值的話,可以使用BiFunction:BiFunction, ToDoubleBiFunction, ToIntBiFunction, ToLongBiFunction等。

@FunctionalInterface
public interface BiFunction<T, U, R> {

 /**
 * Applies this function to the given arguments.
 *
 * @param t the first function argument
 * @param u the second function argument
 * @return the function result
 */
 R apply(T t, U u);

我們看一個BiFunction的例子:

//BiFunction
 Map<String, Integer> salaries = new HashMap<>();
 salaries.put("alice", 100);
 salaries.put("jack", 200);
 salaries.put("mark", 300);

 salaries.replaceAll((name, oldValue) ->
  name.equals("alice") ? oldValue : oldValue + 200);

Supplier:無參的Function

如果什么參數(shù)都不需要,則可以使用Supplier:

@FunctionalInterface
public interface Supplier<T> {

 /**
 * Gets a result.
 *
 * @return a result
 */
 T get();
}

Consumer:接收一個參數(shù),不返回值

Consumer接收一個參數(shù),但是不返回任何值,我們看下Consumer的定義:

@FunctionalInterface
public interface Consumer<T> {

 /**
 * Performs this operation on the given argument.
 *
 * @param t the input argument
 */
 void accept(T t);

看一個Consumer的具體應(yīng)用:

//Consumer
nameMap.forEach((name, age) -> System.out.println(name + " is " + age + " years old"));

Predicate:接收一個參數(shù),返回boolean

Predicate接收一個參數(shù),返回boolean值:

@FunctionalInterface
public interface Predicate<T> {

 /**
 * Evaluates this predicate on the given argument.
 *
 * @param t the input argument
 * @return {@code true} if the input argument matches the predicate,
 * otherwise {@code false}
 */
 boolean test(T t);

如果用在集合類的過濾上面那是極好的:

//Predicate
 List<String> names = Arrays.asList("A", "B", "C", "D", "E");
 List<String> namesWithA = names.stream()
  .filter(name -> name.startsWith("A"))
  .collect(Collectors.toList());

Operator:接收和返回同樣的類型

Operator接收和返回同樣的類型,有很多種Operator:UnaryOperator BinaryOperator ,DoubleUnaryOperator, IntUnaryOperator, LongUnaryOperator, DoubleBinaryOperator, IntBinaryOperator, LongBinaryOperator等。

@FunctionalInterface
public interface IntUnaryOperator {

 /**
 * Applies this operator to the given operand.
 *
 * @param operand the operand
 * @return the operator result
 */
 int applyAsInt(int operand);

我們看一個BinaryOperator的例子:

//Operator
 List<Integer> values = Arrays.asList(1, 2, 3, 4, 5);
 int sum = values.stream()
  .reduce(0, (i1, i2) -> i1 + i2);

Functional Interface是一個非常有用的新特性,希望大家能夠掌握。

本文的例子:https://github.com/ddean2009/learn-java-streams/tree/master/functional-interface

總結(jié)

到此這篇關(guān)于java中functional interface的分類和使用詳解的文章就介紹到這了,更多相關(guān)java中functional interface的分類和使用內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Java動態(tài)添加view的方法

    Java動態(tài)添加view的方法

    這篇文章主要介紹了Java動態(tài)添加view的方法,非常不錯,具有參考借鑒價值,需要的朋友可以參考下
    2017-01-01
  • Spring中的依賴注入DI源碼詳細解析

    Spring中的依賴注入DI源碼詳細解析

    這篇文章主要介紹了Spring中的依賴注入DI源碼詳細解析,Spring的依賴注入(Dependency Injection,DI)是Spring框架核心的一部分,它是實現(xiàn)控制反轉(zhuǎn)(Inversion of Control,IoC)的一種方式,需要的朋友可以參考下
    2023-11-11
  • 關(guān)于Mysql的四種存儲引擎

    關(guān)于Mysql的四種存儲引擎

    這篇文章主要介紹了關(guān)于Mysql的四種存儲引擎,MySql的核心就是存儲引擎,不同的存儲引擎提供不同的存儲機制、索引技巧、鎖定水平等功能,使用不同的存儲引擎,還可以 獲得特定的功能,需要的朋友可以參考下
    2023-05-05
  • Springboot配置文件內(nèi)容加密代碼實例

    Springboot配置文件內(nèi)容加密代碼實例

    這篇文章主要介紹了Springboot配置文件內(nèi)容加密代碼實例,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下
    2019-11-11
  • java 創(chuàng)建線程的方法總結(jié)

    java 創(chuàng)建線程的方法總結(jié)

    這篇文章主要介紹了java 創(chuàng)建線程的方法總結(jié)的相關(guān)資料,需要的朋友可以參考下
    2017-03-03
  • 淺談一下Java中的幾種JVM級別的鎖

    淺談一下Java中的幾種JVM級別的鎖

    這篇文章主要介紹了淺談一下Java中的幾種JVM級別的鎖,當存在安全漏洞時,也必須有相應(yīng)的防護措施。順應(yīng)這種趨勢,虛擬"鎖"被發(fā)明出來,以解決線程的安全問題。在這篇文章中,我們將研究多年來出現(xiàn)的?Java?中幾種典型的?JVM?級鎖,需要的朋友可以參考下
    2023-08-08
  • idea中java及java web項目的常見問題及解決

    idea中java及java web項目的常見問題及解決

    在IDEA中處理亂碼問題主要涉及四個方面:文件編碼設(shè)置為UTF-8、編輯器默認編碼調(diào)整、Tomcat運行配置編碼設(shè)置以及解決cmd中的亂碼,此外,詳細介紹了在IDEA中創(chuàng)建Web項目的步驟,包括新建Java工程、添加Web框架支持、添加Tomcat依賴庫
    2024-09-09
  • springboot整合druid連接池的步驟

    springboot整合druid連接池的步驟

    這篇文章主要介紹了springboot整合druid連接池的步驟,幫助大家更好的理解和學習springboot框架,感興趣的朋友可以了解下
    2020-11-11
  • springboot項目啟動類錯誤(找不到或無法加載主類 com.**Application)

    springboot項目啟動類錯誤(找不到或無法加載主類 com.**Application)

    本文主要介紹了spring-boot項目啟動類錯誤(找不到或無法加載主類 com.**Application),文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2024-05-05
  • Springboot自定義mvc組件如何實現(xiàn)

    Springboot自定義mvc組件如何實現(xiàn)

    這篇文章主要介紹了Springboot自定義mvc組件如何實現(xiàn),文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下
    2020-11-11

最新評論