日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

如何以及为什么序列化Lambda

發布時間:2023/12/3 编程问答 27 豆豆
生活随笔 收集整理的這篇文章主要介紹了 如何以及为什么序列化Lambda 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

總覽

lambda序列化在許多用例中很有用,例如持久配置或作為遠程資源的訪客模式 。

遠程訪客

例如,因此我想訪問遠程Map上的資源,可以使用get / put,但是說我只想從Map的值中返回一個字段,我可以將lambda作為訪問者來傳遞以提取信息。我想要。

MapView userMap =Chassis.acquireMap("users", String.class, UserInfo.class); userMap.put("userid", new UserInfo("User's Name"));// print out changesuserInfo.registerSubscriber(System.out::println);// obtain just the fullName without downloading the whole object String name= userMap.applyToKey("userid", u -> u.fullName);// increment a counter atomically and trigger // an updated event printed with the subscriber. userMap.asyncUpdateKey("userid", ui -> {ui.usageCounter++;return ui; });// increment a counter and return the userid int count = userMap.syncUpdateKey("userid",ui -> { ui.usageCounter++; return ui;},ui -> ui.usageCounter);

如您所見,添加各種簡單功能或調用方法來執行所需的操作很容易。 唯一的問題是默認情況下lambda無法序列化。

可序列化的Lambda

使lambda可序列化的一種簡單方法是將&的可轉換類型添加到引用lambda的實現的變量中。

Function<UserInfo, String> fullNameFunc = (Function<UserInfo,String> & Serializable) ui -> ui.fullName; String fullName = userInfo.applyToKey("userid", fullNameFunc);

如您所見,這引入了很多樣板。 使用lambda的一個關鍵原因是避免樣板代碼,那么替代方法是什么?

使lambda可在您的API中序列化。

不幸的是,無法更改標準API或添加其子類,但是如果您擁有自己的API,則可以使用Serializable接口。

@FunctionalInterface public interface SerializableFunction<I, O> extends Function<I, O>, Serializable { }

該接口可用作參數類型。

default <R> R applyToKey(K key, @NotNull SerializableFunction<E, R> function) {return function.apply(get(key)); }

您的API用戶不必明確聲明lambda是可序列化的。

// obtain just the fullName without downloading the whole object String name= userMap.applyToKey("userid", u -> u.fullName);

遠程實現對lambda進行序列化,然后在服務器上執行該lambda并返回結果。

類似地,存在將lambda應用于整個地圖的方法。

查詢和訂閱

為了支持查詢,如果要隱式添加Serializable,則不能使用內置的stream()API。 但是,您可以創建一個盡可能相似的文件。

Map> collect = userMap.entrySet().query().filter(e -> e.getKey().matches("u*d")).map(e -> e.getValue()).collect(Collectors.groupingBy(u -> u.usageCounter));

或作為過濾的訂閱。

// print userid which have a usageCounter > 10 each time it is incremented. userMap.entrySet().query().filter(e -> e.getValue().usageCounter > 10).map(e -> e.getKey()).subscribe(System.out::println);

這與常規流API的不同之處在于,數據可以分布在許多服務器上,并且當任何服務器上的數據發生更改時,您都會得到回調。 在服務器上應用過濾器和映射時,只有您感興趣的數據才通過網絡發送。

Java序列化

Java序列化是一個很好的通用化,向后兼容的序列化庫。 替代方案嘗試解決的兩個最常見問題是性能和跨平臺序列化。

在上面的示例中,fullNameFunc序列化到700多個字節,并且有非常有限的選項來優化它以減少消息的大小或產生的垃圾量。 相比之下,簡單的二進制YAML序列化使用348,并提供更多選項來優化序列化。

這就提出了如何使用替代,跨平臺或更快的序列化格式來序列化lambda的問題。

替代序列化

您可以加入當前的序列化機制。 不支持此功能,它可以隨時更改,但是沒有其他受支持的方式來執行此操作。

無論如何,您可以這樣做:

Method writeReplace = lambda.getClass().getDeclaredMethod("writeReplace"); writeReplace.setAccessible(true); SerializedLambda sl = (SerializedLambda) writeReplace.invoke(lambda);

這為您提供了一個對象,您可以檢查該對象以提取lambda的內容。 要么查看它調用什么方法,要么對其進行序列化。 在反序列化方面,您可以重新創建該對象并可以在該對象上讀取Resolve。

標準API

當前,沒有用于內省lambda的標準API。 這樣做是有意進行的,以便將來可以更改實現,盡管沒有公共JEP可以這樣做。 但是,就像Unsafe是內部API一樣,我期待有一天可以使用標準API,而不必深入研究JVM的內部來實現解決方案。

結論

通過對API進行一些更改,您可以使序列化lambda對開發人員而言基本上是透明的。 這使實現簡單的分布式系統更易于使用,同時為您提供了優化方法。

翻譯自: https://www.javacodegeeks.com/2015/07/how-and-why-to-serialize-lambdas.html

總結

以上是生活随笔為你收集整理的如何以及为什么序列化Lambda的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。