欢迎访问 生活随笔!

生活随笔

当前位置: 首页 >

lambda 序列化_如何以及为什么要序列化Lambda

发布时间:2023/12/3 40 豆豆
生活随笔 收集整理的这篇文章主要介绍了 lambda 序列化_如何以及为什么要序列化Lambda 小编觉得挺不错的,现在分享给大家,帮大家做个参考.

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 序列化

总结

以上是生活随笔为你收集整理的lambda 序列化_如何以及为什么要序列化Lambda的全部内容,希望文章能够帮你解决所遇到的问题。

如果觉得生活随笔网站内容还不错,欢迎将生活随笔推荐给好友。