JAVA不直接支持集合操作,因此需要嵌套循环来实现文本文件间的交、并、差等集合操作。如果文件数量较多文件过多,或者文件太大无法直接放入内存进行计算,或者需要根据多个字段进行set操作,对应的代码会比较复杂。集算器直接支持集合运算,可以辅助JAVA轻松实现此类算法。下面通过实例来看看具体方法。有两个小文件:f1.txt和f2.txt,***行是列名,现在需要对文件中的Name字段进行交集操作。部分数据如下:filef1.txt:filef2.txt:esProccode:A1,B1:使用导入函数读取文件=[A1.(Name),B1.(Name)].isect()写入内存,默认分隔符是制表符。这里的函数选项@t表示读取***行作为列名,这样后面的计算可以直接用Name和Dept来引用对应的列。如果***行不是列名,你应该使用_1和_2这个默认的列名来引用。计算后A1和B1的值如下:函数import可以读取指定的列,例如本例中只有Name会参与计算,所以只能读取Name列,对应的代码是:file("E:\\f1.txt").import@t(Name)。A2=函数isect可以进行集合之间的交集运算,A1.(Name)表示取出A1的Name列组成一个集合,B1.(Name)表示取出B1的Name列。本例最终结果如下:A3:resultA2。表示计算结果输出到JDBC接口。A3可以与A2合并为一个步骤:result[A1.(Name),B1.(Name)].isect()。以上就是找交集的过程。求并集只需要改函数:[A1.(Name),B1.(Name)].union(),计算结果如下:求差代码:[A1.(Name),B1.(Name)].diff(),计算结果如下:还有一种特殊的集合算法:sumset,即求并集时保留重复的元素,和的代码设置:[A1.(姓名),B1。(Name)].conj(),计算结果如下:可以直接用运算符代替函数,写法更简洁,如交集、并集、差集、并集可以改写为:A1.(名称)^B1.(名称)A1.(名称)&B1.(名称)A1.(名称)\B1.(名称)A1.(名称)|B1.(Name)也可以对多个文件进行set操作,比如f1.txt、f2.txt和f3.txt读入内存后,对应的变量分别是A1、B1、C1。求它们的交集,代码如下:A1.(Name)^B1.(Name)^C1.(Name)or[A1.(Name)or[A1.(Name)](姓名),B1.(姓名),C1.(姓名)].isect()。有时文件比较大,会影响set操作的性能。可以事先使用sort函数进行排序,然后使用merge函数进行set操作,这样性能会有明显的提升。其中求交时要用函数选项@i,求并时要用@u,求差时要用@d。对应代码如下:=[A1.(Name).sort(),B1.(Name).sort()].merge@i()=[A1.(Name).sort(),B1.(姓名).sort()].merge@u()=[A1.(姓名).sort(),B1.(Name).sort()].merge@d()函数合并也可以进行多字段集合操作。假设不同的Dept会有相同的Name,现在需要对Dept和Name作为一个整体进行交集操作。对应代码如下:[A1.sort(Dept,Name),B1.sort(Dept,Name)].merge@i(Dept,Name)。计算结果如下:对于内存无法存储的大文件,可以使用游标函数读取文件,使用合并函数实现集合操作。其中求交集的代码如下:A1=file("e:\\f1.txt").cursor()B1=file("e:\\f2.txt").cursor()A2=[A1.sortx(Name),B1.sortx(Name)].merge@xi(Name)注意,这里的函数cursor并不是将所有数据读入内存,而是以游标(或流)的形式打开文件。集算器引擎会自动分配一个合适的缓冲区,每次读取一部分数据参与计算,如此循环,完成最后的计算。与内存计算不同的是,需要使用游标函数来操作游标,例如需要使用函数sortx进行排序。这里的merge函数使用了两个函数选项,@i表示求交集,@x表示参与计算的对象不是内存数据,而是一个游标。另外union等函数只能对内存数据进行set操作,不能用于大文件。以上脚本已经完成了所有的数据处理工作,接下来将集算器脚本通过JDBC集成到JAVA中。JAVA代码如下://建立esProcjdbc连接Class.forName("com.esproc.jdbc.InternalDriver");con=DriverManager.getConnection("jdbc:esproc:local://");//调用esProc,其中test为脚本文件名st=(com.esproc.jdbc.InternalCStatement)con.prepareCall("calltest()");st.execute();//执行集算器存储过程ResultSetset=st.getResultSet();//得到计算结果
