jdk1.8の新機能、2番目の箇条書き「一般的に使用される機能インターフェイス」

一般的に使用される機能インターフェイス

レビュー

  機能インターフェイスの概念については、前の記事「ラムダ式」で説明しましたラムダ式で機能インターフェイスを使用すると、場合によってはJavaコードの記述を大幅に簡素化できます。機能インターフェイスとは、インターフェイスに抽象メソッドが1つだけあり、インターフェイスが@FunctionalInterfaceアノテーションで装飾されていることを指します。JDKは、一般的に使用される機能インターフェイスの定義に役立ちました。これらの機能インターフェイスは、Lambdaおよび後で説明するストリームと連携して、フィルタリングデータ操作を実行します。使用は非常に簡単です。一般的に使用される機能インターフェイスについて説明します。

  機能インターフェイスの比較的大規模なアプリケーションシナリオがパラメータとしてメソッドに渡されることは言及する価値があります
  

サプライヤーインターフェース

  (サプライヤサプライヤ)は、データを渡さずに、対応するデータタイプを「生成」するために使用される「ファクトリ」タイプのインターフェイスです。特定の用途は、次のストリームに反映されます。

@FunctionalInterface
public interface Supplier<T> {
    
    }

  

抽象的方法

T get():汎用パラメータータイプで指定されたデータを取得するため、つまり、要件を満たすデータタイプを提供し、「サプライヤー」と同様にデータを「生成」するために使用されます。

例:配列の最大値を取得する

public class SupplierDemo {
    
    
    public static int getMaxValue(Supplier<int> supplier) {
    
    	//接口作为参数进行传递
        return supplier.get();
    }
    
    public static void main(String[] args) {
    
    
        int[] nums = {
    
    2, 9, 19, 1, 20};
        int max = getMaxValue(()->{
    
    	//使用Lambad表达式
            int max = nums[0];
            for (int i = 1; i < nums.length; i++) {
    
    
               max = nums[i] > max ? nums[i] : max;
            }
            return max;
        });
       
    }
   
}

  もちろん、上記の例は、get()メソッドの目的が目的のデータタイプを提供することであることを確認するためのものです。
  

消費者インターフェース

(消費者消費)データを作成するサプライヤとは異なり、消費者はデータを消費する、つまり操作のためにデータを渡すためのものであり、戻り値はありません。

@FunctionalInterface
public interface Consumer<T> {
    
    }

  

抽象的方法

void accept(T):指定されたパラメーターのメソッドのコンテンツを実行します

例:渡された文字列データを逆にする

public class ConsumerDemo {
    
    
    public static void reserveString(String str, Consumer<String> con) {
    
    
        con.accept(str);
    }
    
    public static void main(String[] args) {
    
    
        String str = "lambda";
        reserveString(str, (str)->{
    
    
            System.out.println(str);	//lambda
            StringBuffer reStr = new StringBuffer(str);
            reStr.reverse().toString();		//将字符串进行逆转
            System.out.println(reStr);	//adbmal
        });
    }
    
}

  

デフォルトの方法

サプライヤインターフェイスとは異なり、デフォルトのメソッドはコンシューマインターフェイスに実装されています。addThen()

/**
 *	默认方法
 * 1. 返回一个组合的Consumer对象,并且会按照顺序执行accept方法:即可以拼接多个进行执行
 * 2. 如果after方法执行出现异常(或接下去拼接的出现异常了)就会将该异常转发给调用者(例如main)。
 * 3. 如果执行this操作出现异常时,不会执行after的操作。
 */
default Consumer<T> andThen(Consumer<? super T> after) {
    
    
    Objects.requireNonNull(after);		//判断是否为空指针
    return (T t) -> {
    
     
        accept(t); 
        after.accept(t); 
    };	//这也是一个Consumer接口accept的lambad实现
}

例:文字列を大文字小文字に変換する

public class ConsumerDemo {
    
    
     public static void method(String str, Consumer<String> con1, Consumer<String> con2) {
    
    
         con1.andThen(con2).accept(str);
     } 
    public static void main(String[] args) {
    
    
        String str = "Lambda";
        method(str, (t)->{
    
    
            System.out.println(t.toUpperCase());	//LAMBDA
        }, (t) -> {
    
    
            System.out.println(t.toLowerCase());	//lambda
        });
    }
}

  

述語インターフェース

(述語述語、離散数学の概念)、パラメータを渡し、パラメータが条件を満たしているかどうかを確認するためにパラメータを論理的に判断し(指定されたパラメータの述語を評価します)、戻り値はブール値です。

@FunctionalInterface
public interface Predicate<T> {
    
     }

  

抽象インターフェース

boolean test(T t):入力パラメーターが条件を満たすかどうかを判別します

例:文字列のリストを渡し、4より大きい長さの文字列を出力します

public class PredicateDemo {
    
    
    public static void checkString(String[] strs, Predicate<String> pre) {
    
    
        for (int i = 0; i < strs.length; i++) {
    
    
            if (pre.test(strs[i])) {
    
    
                System.out.println(strs[i]);
            }
        }
	}
    public static void main(String[] args) {
    
    
        String[] strs = {
    
    "java", "c", "C++", "python", "javascript", "Typescript"};
        checkString(strs, (str)->{
    
    
            return str.length() > 4;
        });	//python, javascript,Typescript
    }
}

  

デフォルトの方法

  論理的な判断に使用されるため、論理演算子が不可欠であり、いくつかのデフォルトの論理操作メソッドがPredicateインターフェイスに組み込まれています。

/**
 * 1.返回一个通过逻辑与组合的Predicate接口
 * 2.other.test抛出异常的话将该异常转发给调用者
 * 3.this.test抛出异常的话不执行other.test的内容
 */
default Predicate<T> and(Predicate<? super T> other) {
    
    
        Objects.requireNonNull(other);
        return (t) -> test(t) && other.test(t);
}
//逻辑非
default Predicate<T> negate() {
    
    
        return (t) -> !test(t);
}
//逻辑或
default Predicate<T> or(Predicate<? super T> other) {
    
    
        Objects.requireNonNull(other);
        return (t) -> test(t) || other.test(t);
}

例:文字列にが含まれていて、長さが5より大きいことを確認します

public class PredicateDemo {
    
    

    public static boolean checkString(String str, Predicate<String> pre1, Predicate<String> pre2) {
    
    
        return pre1.and(pre2).test(str);
    }

    public static void main(String[] args) {
    
    
        String str = "lambda";
        boolean b = checkString(str, (str1)->{
    
    
            return str1.length() > 5;
        }, (str1) -> {
    
    
            return str1.contains("a");
        });
        System.out.println(b);	// true
    }
}

  

機能インターフェース

@FunctionalInterface
public interface Function<T, R> {
    
    }

  このインターフェイスは、タイプTをタイプRに変換するために使用されます。Tは前提条件と呼ばれ、Rは事後条件と呼ばれます。
  

抽象的方法

R apply(T t):指定されたパラメータータイプTをRタイプに変換します

たとえば、文字列タイプの数値を整数タイプに変換します

public class FunctionDemo {
    
    
    private static void transform(Function<String, Integer> function) {
    
    
        int num = function.apply("10");		//数字10
        System.out.println(num + 20);
    }
    public static void main(String[] args) {
    
    
        transform(s ‐> Integer.parseInt(s));
    }
}

  

デフォルトの方法

  Consumerと同様に、FunctionにもaddThenメソッドがあります。このメソッドも、結合された操作の後にFunctionインターフェイスを返し、最終的に変換されたデータタイプは変換後のデータタイプと一致します。

default <V> Function<T, V> andThen(Function<? super R, ? extends V> after) {
    
    
    Objects.requireNonNull(after);	//判断是否为空指针
    return (T t) -> after.apply(apply(t));	//这也是一个Consumer接口apply的lambad实现
}

例:文字列番号を整数型に変換してから、+ 10を文字列に変換します

public class FunctionDemo{
    
    
	public static void addTen(String str, Function<String, Integer> fun1, Function<Integer, String> fun2) {
    
    	//注意最后返回的与fun2的类型相同
        String s = fun1.andThen(fun2).apply(str);
        System.out.println(s);	//"20"
    }

    public static void main(String[] args) {
    
    
        String s = "10";
        addTen(s, (String str1) ->{
    
    
            return Integer.parseInt(str1) + 10;
        }, (Integer integer) -> {
    
    
            return integer.toString();
        });

    }
}

  

概要

  1. 機能インターフェイスを通じて、ラムダ式の簡潔さを確認できます。もちろん、より簡潔な方法は、メソッド参照を使用することです。
  2. この段階では、この操作は不要だと感じるかもしれませんが、これらのインターフェイスは後続のストリームで非常に役立ちます。

おすすめ

転載: blog.csdn.net/weixin_44184990/article/details/108429021