工作中,遇到了在Java里面序列化一颗树、然后反序列化的时候出现Stack
Overflow异常的情况。整棵树的层次和在处理每层的当前对象的消耗(在栈上的消耗)累计起来造成了Stack
Overflow。
晚上在家里的时候,写了个小程序,实现了Java中对一个Tree的序列化。
这个程序主要想避免层次太深的问题,所以出发点很简单,就是要改变序列化的时候的对象关系,我们要把一个层次的关系变成平的。
这个程序完成了三个版本的序列化方式。先看第一个
第一个版本在写的时候没怎么想:大概的思路是这样的,就是我们对Tree上的每个节点独立序列化,然后我们保存节点间的父子关系,序列化后的结构数据结构是这样的:
NodeCount:4bytes
//每个节点的数据
NodeId:4bytes
Node序列化后的长度:4bytes
Node序列化后的数据:1byte*序列化后的长度
Node的Child个数:4bytes
Child的NodeId:4bytes*Child个数
......表示多个节点数据
其中,NodeId是从0开始自增
完成这个版本后,大概测试了一下,序列化后的长度比Java直接序列化多了14%左右,不爽。
思考了一下,其实NodeId是不需要的,因此,很快的改出了第二个版本,序列化后格式是这样的:
NodeCount:4bytes
//每个节点的数据
Node序列化后的长度:4bytes
Node序列化后的数据:1byte*序列化后的长度
Child的NodeId:4bytes*Child个数
......表示多个节点数据
测试了一下,长度有所减少,但是非常非常不明显,基本上是比Java序列化多了13%,还是不爽。
最后,想了一下,还是把Tree上的所有节点放到一个Array中,都交给Java序列化吧。这个时候,序列化后的格式就变为了
NodeCount:4bytes
Array序列化后的长度:4bytes
Array序列化后的内容
按照宽度优先的方式的每个TreeNode的ChildCount
这次之后,序列化后的数据和直接Java比,相差无几了,比Java直接序列化差不多少1%不到一些。
代码就放附件中了,随便写的,比较乱。
分享到:
相关推荐
7. **树的序列化和反序列化**:将二叉树转换为字符串存储或从字符串恢复二叉树结构,是处理大型树结构时常用的方法。 在"binaryTree2"这个压缩包中,可能包含了对上述概念的实现代码,包括不同的操作方法和测试用例...
- Python:Python的`xml.etree.ElementTree`模块可用于序列化,第三方库如`PyYAML`和`pickle`也可实现。 - JavaScript:JavaScript没有内置的XML序列化,但可以借助第三方库如`xml2js`进行转换。 - PHP:PHP使用`...
7. **序列化与反序列化**:为了保存和恢复目录树的状态,我们可以使用Java的序列化机制将树结构转换为字节流,然后在需要时再反序列化。然而,需要注意的是,序列化可能导致安全问题,因此在实际应用中应谨慎使用。 ...
javax.sql.rowset.serial 提供实用工具类,允许 SQL 类型与 Java 编程语言数据类型之间的可序列化映射关系。 javax.sql.rowset.spi 第三方供应商在其同步提供者的实现中必须使用的标准类和接口。 javax.swing 提供...
接下来,我们需要将这个树结构序列化到一个文件中。在这种情况下,选择了GBK编码的文本文件"文件清单.dat"。GBK编码兼容GB2312,能表示更多的中文字符,因此对于包含中文文件名的目录结构尤其适用。要将树结构写入...
5. **数据序列化与反序列化**:由于API返回的是JSON或XML格式的数据,开发者需要解析这些数据以获取翻译结果,可能用到Gson或Jackson库。 6. **错误处理与异常捕获**:良好的用户体验需要考虑网络错误、API错误等...
文章通过具体的例子展示了序列化的强大之处,例如将复杂的数据结构如树(Tree)和哈希表(Hashtable)序列化到文件中,然后在下次执行程序时可以从文件中读取这些对象并恢复它们的状态。这对于简化代码、提高复用性和...
5. 实现与库:许多编程语言都提供了支持XML和SOAP二进制序列化的库或框架,例如.NET Framework的BinaryFormatter和XmlSerializer,Java的XMLEncoder和XMLDecoder,Python的pickle模块和xml.etree.ElementTree等。...
反序列化支持(guava中的table均不支持或没有序列化器支持) 基本使用 1.使用代码 //创建起相应的类 ArrayTreeTable table = new ArrayTreeTable<>(String.class, String.class, String.class, (Class) String.CASE...
2. **serialized-form.html**:这个文件详细解释了Java中的序列化机制,包括如何将对象的状态保存到持久化存储,以及如何从存储中恢复这些状态。这对于理解和实现序列化类是至关重要的。 3. **constant-values.html...
MySQL数据库则负责存储数据,表结构应与前端展示的数据模型相匹配,以支持正确的数据序列化和反序列化。 Eclipse是Java开发的常用IDE,提供代码编辑、调试和项目管理等功能。提供的项目文件可以直接导入到Eclipse中...
Tree树结构是计算机科学中一种基础且重要的数据结构,它以节点的形式表示数据,并通过边连接这些节点,形成层次化的组织。在树结构中,每个节点都有一个父节点(除了根节点),并且可以有零个或多个子节点。这种结构...
Java中的IO流库可以帮助我们从文件中读取和写入这些序列化的数据。例如,可以使用`FileReader`和`BufferedReader`读取文件,用`FileWriter`和`BufferedWriter`写入文件。同时,`ObjectOutputStream`和`...
4. **命令行界面**:TreeTagger提供命令行接口,用户可以通过编写简单的脚本进行批处理,方便集成到自动化工作流程中。 5. **结果输出**:TreeTagger的输出格式简单明了,易于解析和进一步处理,通常是以空格分隔的...
Java中的序列化是将对象的状态转换为字节流的过程,以便可以存储或在网络上传输。如果一个类实现了`Serializable`接口,它的实例就可以被序列化。选项C提到的是`Forest`实例被序列化,这可能是因为`Forest`类实现了`...
在题目中,由于`Tree`类没有实现`Serializable`接口,所以在尝试序列化`Forest`实例时,会抛出`java.io.NotSerializableException`。 2. **对象的序列化与反序列化**:在问题2中,正确的序列化和反序列化代码是选项...
例如,你可以使用Java的集合框架如`ArrayList`或`LinkedList`来表示树节点,然后通过JSON序列化将树结构传递到前端。Spring Boot框架中的`@RestController`可以方便地处理这种需求。 此外,JavaFX是Java的一个模块...
本题属于SCJP考试中的一个经典题目,涉及Java对象序列化(Serialization)和IO流的使用。 题目描述了一个尝试将`Forest`类的实例写入到一个名为"Forest.Ser"的文件中的场景。`Forest`类实现了`Serializable`接口,...