JDK8は機能的なインターフェースとStramフローを備えています

JDK8は機能的なインターフェースとStramフローを備えています

機能的なインターフェース

関数型インターフェース、通常、Javaのインターフェースの1つのメソッドのみが関数型インターフェースと見なされます。jdk8のlamdaに適合する
ためにjdkで使用される多くの関数型インターフェースがあります。たとえば、一般的なRunableおよびComparableインターフェースはすべて関数です
。jdk1では.8、@ FunctionalInterfaceアノテーションを機能インターフェイスのインターフェイスに追加する必要があることに同意します。これは必須ではありません。Comparableにはこのアノテーションはありません。このアノテーションの意味は単なる慣例です。このアノテーションを追加する場合インターフェイスの設計、新しいメソッドを追加する場合は、このアノテーションが一般的になります。これは、これが機能的に合意されたインターフェイスであり、メソッドの数が1に等しくないことを示します。
開発でこのアノテーションを追加する意味は次のとおりです。このインターフェイスに追加しないように開発者に通知するメソッド

1つは、JDK8の新しい機能インターフェイスです。

将来のストリームストリームの使用を容易にするために、jdk8は新たに4つの機能インターフェイスを追加しました。これらの4つのインターフェイスを柔軟に使用することで、開発が簡素化され、コードが美しくなります。公式の設計により、多くのことが可能になりました。デザインのインスピレーション。

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

java.util.function.Supplier <T>
インターフェースには、パラメーターのないメソッドが含まれています。Tget ();は、ジェネリックパラメーターで指定されたタイプのオブジェクトデータを取得するために使用されます。
このインターフェースは、ジェネリックを指定するプロダクションインターフェースとも呼ばれますインターフェイスどのタイプのデータが返されますか?
ジェネリックは、生成する必要のあるタイプを指定できます

public class Demo01Supplier{
    
    
	public static void main(String[] args) {
    
    
		System.out.println(getSupplier(()->"我自己"));//这里生产了一个字符串
	}
	public static String getSupplier(Supplier<String> supplier) {
    
    
		return supplier.get();
	}
}
消費者インターフェース

java.util.function.Consumer <T>
インターフェースには、デフォルトのメソッドとaccept(T t)メソッドが含まれています。Acceptは、渡された指定のジェネリック・オブジェクトを消費するために使用されます。
このインターフェースは、コンシューマー・インターフェースとも呼ばれます。1つのジェネリックを指定します。このジェネリックオブジェクトを処理するロジックをカスタマイズして、このオブジェクトを消費します
。Consumerのデフォルトメソッド:AndThenは、多くの
例を接続できる2つのコンシューマーインターフェイスを接続します
Consumer <String> c1;
Consumer <String> c2;
c1。AndThen(c2 ).accept(String);
前のコンシューマーインターフェイスを最初に実行します

public class Demo02Consumer {
    
    
	public static void main(String[] args) {
    
    
		acceptConsumer("迪丽热巴", (name)->System.out.println(new StringBuilder(name).reverse().toString()));//将输入的字符串反转然后打印到控制台
		AndThenConsumer("迪丽热巴",(name)->System.out.println(name)
				,(name)->System.out.println(new StringBuilder(name).reverse().toString()));//将输入的字符串先打印一边,然后再反转再打印一遍
		String[] arr= {
    
    "迪丽热巴,女","古力娜扎,女","马尔扎哈,男"};
		AndThenConsumer(arr,(string)->{
    
    
			String ar=string.split(",")[0];
			System.out.print("姓名:"+ar+"	");
		},(string)->{
    
    
			String ar=string.split(",")[1];
			System.out.println("性别:"+ar);
		});//两次处理后 输出的样子是 姓名:迪丽热巴 &nbsp; 性别:女,然后一行一行打印
	}
	public static void acceptConsumer(String name,Consumer<String> con) {
    
    //对字符串做消费
		con.accept(name);
	}
	public static void AndThenConsumer(String name,Consumer<String> c1,Consumer<String> c2) {
    
    //对字符串做两次消费
		c1.andThen(c2).accept(name);
	}
	public static void AndThenConsumer(String[] name,Consumer<String> c1,Consumer<String> c2) {
    
    //对字符串数组做两次消费
		for (String string : name) {
    
    
			c1.andThen(c2).accept(string);
		}
	}
}
アサーションインターフェイス述語

java.util.function.Predicate <T>
関数:特定のデータ型のデータを判断すると、結果はブール値を返します。
このインターフェイスはアサーションインターフェイスと呼ばれ、主にオブジェクトのフィルタリングと判断に使用されます。形式はjunitの形式に似てい
ます。インターフェイスで抽象メソッドをアサートします。
ブールテスト(T t)
trueを返す
ように準拠し
ますが、falseを返すインターフェイスのデフォルトメソッドには準拠しません
および
p1.and(p2).test(T t);
&&同等であり、同時にtrueを返し
ます。複数のインターフェイスに別のデフォルトメソッドが存在する可能性があります:
p1.or(p2).test(T t);
||と同等であり、
それがあればfalseを返します。満足していませんここにコードの実装はありません!
インターフェイスの最後のデフォルトメソッド
p1.negate()。test(T t);は
まったく同じです。つまり、noを意味し、満たされない場合はtrueを返します。注意してください!ここには2つのアサーションはありません
。インターフェイスには静的メソッドもあります:
isEqual

public class Demo03Predicate {
    
    
	public static void main(String[] args) {
    
    
		String ar="abcdfe";
		System.out.println(TestPredicate(ar, (str)->str.length()>=6));//字符串长度是否大于等于6   
		System.out.println(AndTestPredicate(ar, (str)->str.length()>3,(str)->str.contains("a")));//判断长度大于3且包含字符串"a"
		System.out.println(NegateTestPredicate(ar,(str)->str.length()>3));//长度大于3返回false

	}
	public static boolean TestPredicate(String str,Predicate<String> pre) {
    
    //test
		return pre.test(str);
	}
	public static boolean AndTestPredicate(String str,Predicate<String> p1,Predicate<String> p2) {
    
    //and
		return p1.and(p2).test(str);
	}
	public static boolean NegateTestPredicate(String str,Predicate<String> pre) {
    
    //negate
		return pre.negate().test(str);
	}
}
変換型インターフェース機能

java.util.function <T、R>
このインターフェースは、あるタイプのデータを別のタイプのデータに従って取得するために使用されます。前者は前提条件であり、後者は事後条件
です。関数で最も重要な抽象メソッドは次のとおりです
。Rapply(T t)。これはタイプTのパラメーターに従ってタイプRの結果を取得します。
シナリオを使用します。例:
文字列型から整数型への変換
Functionのデフォルトのメソッドは
f1.AndThen(f2).apply(T t)です。

FunctionのデフォルトのメソッドIDは、元々どのタイプであったかを確認するために使用されます

public class Demo04Function {
    
    
	public static void main(String[] args) {
    
    
		String b="赵丽颖,20";
		String a = "123456";
		System.out.println(ApplyFunction(a, (s) -> Integer.parseInt(s)));
		/*将String转成Integer然后给数值减10000再转换回来*/
		System.out.println(AndThenApplyFunction(a,(s)->Integer.parseInt(s)-10000,(s)->String.valueOf(s)));
		/*将字符串b分割,取后面的20转成Integer,然后在返回其-2*/
		System.out.println(FT(b,(s)->b.split(",")[1],(s)->Integer.parseInt(s),(s)->s-2));
	}
	public static Integer ApplyFunction(String s, Function<String, Integer> f) {
    
    
		return f.apply(s);
	}
	public static String AndThenApplyFunction(String s, Function<String, Integer> f1, Function<Integer, String> f2) {
    
    
		return f1.andThen(f2).apply(s);
	}
	public static Integer FT(String s,Function<String,String> f1,Function<String,Integer> f2,Function<Integer,Integer> f3) {
    
    //注意每一个Function的泛型
		return f1.andThen(f2.andThen(f3)).apply(s);
	}
}

二、ストリーム

ストリームストリームはパイプラインストリームに属し、使用されると閉じられるため、ストリームを受信するためにオブジェクトを使用する必要はありません。

Stream流中的终结方法:所有方法最后都要以终结方法作为结尾
		forEach(Consumer(<? super T> action);
		long count();这也是终结方法,返回元素个数
Stream流中的过滤方法:
		filter(Predicate(<? super T> predicate));
		使用Predicate中的方法test判断筛选过滤
Stream流中的映射方法:
		map(Function<T,R> fun);
		将一个一种类型转换成另一种类型数据
Stream流中截取前n个元素的方法:
		Stream<T> limit(long l);
Stream流中的跳过方法:
		Stream<T> skip(long l);
		跳过前l个元素,将后面的元素创建一个新的Stream流
Stream流中的合并方法:
		Stream<T> Stream.concat(Stream<? extends T> s1,Stream<? extends T> s2)

注:アクションコード、要素が指定された順序の流れ対流操作で順序付けられている値を返すことです。

@SafeVarargs
@SuppressWarnings("varargs") //从arrays创建一个流是安全的
public static<T> Stream<T> of(T... values) {
     
     
 return Arrays.stream(values);
}

ストリームを使用する場合、毎回オブジェクトを使用する必要はありません。次の2つの点に注意する必要があります。

  • Collection <T>には.streamメソッドがあり、Streamオブジェクトを作成できます
  • Map <T、T>コレクションに.streamメソッドはありません。間接的にインポートする必要があります
public class StreamInMethod {
    
    
	public static void main(String[] args) {
    
    
		Stream.of("张三","李四","王五","赵六").forEach(s->System.out.print(s+"	"));//forEach终结方法
		System.out.println();
		Stream.of("张三","李四","王五","赵六").filter(s->s.startsWith("张"))//filter过滤方法
				.forEach(s->System.out.println(s));
		Stream.of("1","2","3","4").map(s->Integer.parseInt(s))//map映射方法
				.forEach(s->System.out.print(s+"	"));
		System.out.println();
		System.out.println(Stream.of("1","2","3","4").count());//count终结方法,返回long
		Stream.of("1","2","3","4").limit(2).forEach(s->System.out.print(s+"	"));//limit截取方法
		System.out.println();
		Stream.of("1","2","3","4").skip(2).forEach(s->System.out.print(s+"	"));//skip跳过方法
		System.out.println();
		Stream.concat(Stream.of("我","你"), Stream.of("1","2")).forEach(s->System.out.print(s+"	"));//concat合并方法
	}
}

個人的な考え

これらの関数型インターフェース接続方式を使用する場合、プロセス指向の操作が必要だと感じます。途中で例外が発生すると、元のデータが変更され、残りのロジックが完成せず、問題が発生します。このメソッドの実行がアトミック性を満たしていないこと(ニーズを参照)。この途中の例外を解決する場合、プロセス内のパラメーター操作の各ステップをフィルター処理して判断するか、ロールバック戦略を設定することしかできません。設計時、この可能性も考慮する必要があります。

おすすめ

転載: blog.csdn.net/qq_44769485/article/details/114468975
おすすめ