您的位置:首页 > 编程语言 > Java开发

scala合并文件,删除具有相同字段的记录

2017-06-15 14:51 344 查看
合并结构相同,内容格式为json的两个文件,用scala代码实现。

编译环境:Scala IDE for Eclipse

1.下面是详细的代码:

package hyp
import scala.util.parsing.json._
import com.common.pinyin
import scala.io.Source
import scala.collection.mutable.Set
import java.io.PrintWriter;
import java.io.File;

/**
* IO操作
* @date Apr 24, 2017
* @author hyp
*
*/
object TestIO {
def main(args: Array[String]): Unit = {
val onePath = "C:/Users/Administrator/Desktop/test/1.txt";
val twoPath = "C:/Users/Administrator/Desktop/test/2.txt";
val threePath = "C:/Users/Administrator/Desktop/test/3.txt";
val actionIO = new ActionIO()
actionIO.mergeFile(onePath, twoPath, threePath)
}
}
class ActionIO {

/**
* 合并文件,删除具有相同字段url的记录,
* @date Jun 15, 2017
* @author hyp
* @param oneFilePath
* @param twoFilePath
* @param threeFilePath 合并后文件
*/
def mergeFile(oneFilePath: String, twoFilePath: String, threeFilePath: String) {
//1.读文件oneFilePath,并存为oneSet,url存为ourlSet
val oneSet = Source.fromFile(oneFilePath).getLines().toSet
val it = oneSet.iterator;
var ourlSet: Set[String] = Set()
while (it.hasNext) {
val labeljson = JSON.parseFull(it.next())
labeljson match {
case Some(labelmap: Map[String, Any]) =>
val url = labelmap("url").toString().replaceAll(" ", "")
ourlSet.+=(url) //NOTE1:注意两者的区别urlSet.+(url)
case _ => println(labeljson.toString());
}
}
println("ourlSet.length===" + ourlSet.size)

//2.读文件twoFilePath,并存为twoSet,url存为turlSet
val twoSet = Source.fromFile(twoFilePath).getLines().toSet
val its = twoSet.iterator;
var turlSet: Set[String] = Set()
while (its.hasNext) {
val labeljson = JSON.parseFull(its.next())
labeljson match {
case Some(labelmap: Map[String, Any]) =>
val url = labelmap("url").toString().replaceAll(" ", "")
turlSet.+=(url)
case _ => println(labeljson.toString());
}
}
println("turlSet.length===" + turlSet.size)

//3.重合的url存为thSet,ourlSet与turlSet相交
val thSet = ourlSet.&(turlSet)
//val thSet = ourlSet.intersect(turlSet) //同上,相交
println("重合的url:" + thSet.size + " 条")
//    thSet.foreach(println)

//4.删除oneSet中包含重合url的记录,fSet
val filterSet = oneSet.filter { x =>
thSet.forall { a =>
!x.contains(a)
}
}
println("过滤后的oneSet:" + filterSet.size + "条")

//5.两个set并集,并存为txt
val sSet = twoSet.union(filterSet)
println("并集:" + sSet.size + "条")
val writer = new PrintWriter(new File(threeFilePath))
sSet.foreach { x =>
writer.write(x + "\n")
}
writer.close()

println("执行成功!")

}
}


2.项目中用到的1.txt和2.txt格式都一样,可以按照这种格式自行编造数据,如下:

{"_id":{"$oid":"593f69e81d41c80a84c9728d"},"category":"车系首页","tit":"【九龙A52010款2.4L 精英型4RB2报价_图片_参数】_九龙汽车九龙A5怎么样_爱卡汽车","url":"http://newcar.xcar.com.cn/m18568/","address":"爱卡汽车\u003e轻客\u003e九龙A5\u003e2010款2.4L精英型4RB2\u003e车型首页"}


3.eclipse中执行Run as ->scala application ,控制台输出结果,并查看合并后的文件。



4.开发问题记录:

scala中Iterator只能访问一次。scala读文件Source.fromFile(twoFilePath).getLines()得到的是一个Iterator[String]对象,该对象只能访问一次,再次操作必须重新执行Source.fromFile(twoFilePath).getLines(),重新获取Iterator[String]对象,解决这个问题是把Iterator[String]转化为Array,List,Map,Set等,这样就可以一次读取文件,多次访问或者操作了。

原代码:

val linesIterator= Source.fromFile(filePath).getLines()


改为:

val linesSet = Source.fromFile(filePath).getLines().toSet


相关参考链接:http://www.cnblogs.com/lovegmail/p/4818883.html

集合Set操作+与+=是不相同的,+是添加一个元素并生成新的Set,而+=是在原Set中添加一个元素。

代码没有忽略空格行,如果文件中有空格行的话可能会出错。

forAll循环,返回boolean值,当所有元素都满足条件时返回true,常与filter结合使用实现双重循环。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  scala eclipse 合并文件
相关文章推荐