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相关推荐

  1. fegin调用为什么要序列化_全方位解析Java的序列化

    前言 相信大家日常开发中,经常看到Java对象"implements Serializable".那么,它到底有什么用呢?本文从以下几个角度来解析序列这一块知识点~ 什么是Java ...

  2. java 属性不序列化_怎样对带有不可序列化属性的Java对象进行序列化

    原标题:怎样对带有不可序列化属性的Java对象进行序列化 出于很多原因我们想使用自定义的序列化方法取代Java默认的机制.一个最常见的原因是提高性能,而另一个原因是有时候我们无法使用默认的序列化方法. ...

  3. java arraylist 序列化_专题二、ArrayList序列化技术细节详解

    一.绪论 所谓的JAVA序列化与反序列化,序列化就是将JAVA 对象以一种的形式保持,比如存放到硬盘,或是用于传输.反序列化是序列化的一个逆过程. JAVA规定被序列化的对象必须实现java.io.S ...

  4. flutter 序列化_如何在Flutter中序列化对象

    flutter 序列化 If you intend to save user data to the shared preferences or local storage in your Flutt ...

  5. java marshal 序列化_求教Marshal类实现序列化出现的问题

    小弟最近在研究利用Marshal实现序列化和反系列化,主要是使用Marshal类里的两个方法,StructureToPtr和PtrToStructure,这两个类的具体讲解和用法我就不多赘述 了,具体 ...

  6. java8 lambda 视频_一文搞懂Java8 Lambda表达式(附带视频教程)

    Lambda表达式介绍 Java 8的一个大亮点是引入Lambda表达式,使用它设计的代码会更加简洁.通过Lambda表达式,可以替代我们以前经常写的匿名内部类来实现接口.Lambda表达式本质是一个 ...

  7. python封装函数、实现将任意的对象序列化到磁盘上_Python系列之lambda、函数、序列化...

    lambda 在python中使用lambda来创建匿名函数,而用def创建的方法是有名称的,除了从表面上的方法名不一样外,python lambda还有哪些和def不一样呢? 1 python la ...

  8. 字段变成小写 序列化_序列化/反序列化

    序列化是干啥用的? 序列化的原本意图是希望对一个Java对象作一下"变换",变成字节序列,这样一来方便持久化存储到磁盘,避免程序运行结束后对象就从内存里消失,另外变换成字节序列也更 ...

  9. java序列化_夯实Java基础系列22:一文读懂Java序列化和反序列化

    本系列文章将整理到我在GitHub上的<Java面试指南>仓库,更多精彩内容请到我的仓库里查看 https://github.com/h2pl/Java-Tutorial 喜欢的话麻烦点下 ...

最新文章

  1. CentOS 6.5环境实现corosync+pacemaker实现DRBD高可用
  2. Linux用init命令关机、重启、切换模式
  3. canvas 添加 竖版文字_CSS题目系列(4) - 文字穿透遮罩层
  4. 使用Navicat创建数据库,外键出现错误ERROR 1005: Can't create table (errno: 121)
  5. 到底什么时候该使用MQ 1
  6. xmpp with openfire之一 xmpp and openfire
  7. CentOS7安装VMware Tools
  8. Modelsim se仿真Xilinx IPcore
  9. 第一行代码学习笔记第四章——探究碎片
  10. Java中判断字符串是否为数字
  11. centos7下yum安装mysql
  12. c++vector操作
  13. 简述什么是SQL注入,写出简单的SQL注入语句。
  14. matlab实现kmeans聚类算法
  15. 如何在Mac上创建水彩画?Art Text来告诉你!
  16. 【计算机网络】DNS解析详解
  17. Hive 使用 Beeline 连接配置
  18. [CodeForces 332B]Maximum Absurdity[DP]
  19. 我看到西电通院考试——学生应该做的事情?
  20. 初创企业数据体系建设

热门文章

  1. P3185-[HNOI2007]分裂游戏【SG函数】
  2. 2018年10月17日普级B组【模拟赛】
  3. 形象的解释神经网络激活函数的作用是什么
  4. Java异常面试问题
  5. 在MySQL的InnoDB存储引擎中count(*)函数的优化
  6. Jsoup代码解读之四-parser(上)
  7. Oracle入门(十三C)之高级查询(下)
  8. laravel如何生成swagger接口文档
  9. 对ASCALL码的理解
  10. python一图带你精通time类型转换