java学习:Iterator数据加工厂
前不久听一大神讲课,期间提到Iterator,别看它方法简单,可是组装起来就像“数据加工厂”一样!
next()获得序列中的下一个元素。
hasNext()检查序列中是否还有元素。
remove()将迭代器新返回的元素删除。
数据加工厂主要用到的是next()和hasNext()这两个方法,拿下面这个问题来说
<问题>
linux下有很多对文本进行操作的命令,比如cat filename 可以将文件的所有内容输出到控制台上。
grep keyword filename可以将文件内容中包含keyword的行内容输出到控制台上。
wc -l filename可以统计filename文件中的行数。
|是代表管道的意思,管道左边命令的结果作为管道右边命令的输入,比如cat filename | grep exception | wc -l,可以用来统计一个文件中exception出现的行数。
请实现一个功能,可以解析一个linux命令(只包含上面三个命令和上面提到的参数以及和管道一起完成的组合,其它情况不考虑),比如下面这几个例子:
cat xx.txt
cat xx.txt | grep xml
wc -l xx.txt
cat xx.txt | grep xml | wc --l
</问题>
上面这个问题是要对一个数据源进行几种不同的处理,
第一种思路大致如下:
首先把输入的命令分割成单个的命令,然后根据命令的功能编写处理数据的功能模块,遍历命令列表,对数据处理,将结果记录,作为下一个命令的传入参数,直到所有命令执行完毕。
优点:灵活性不错,各种命令可以很方便地组合成不同的功能,扩展性也很好,需要增加新的命令的时候只需要编写新的功能模块就行了,执行的主流程几乎不用修改。
缺点:需要留存中间结果,也就是说当数据源过大的时候就无能为力了,另外,如果处理数据的中途出现意外,那么即使你已经完成绝大部分工作,到最后还是什么结果也不会得到。
第二种思路:流水线工厂,使用Iterator的特点来实现:(hasNext()判断是否有下一条数据,next()取出下一条数据,下面提到的每个Iterator都将反复用到这两个方法)
首先,将数据源(上面的问题里是文件)构造成Iterator;1
然后对每个命令编写各自的迭代器构造函数,各自实现hasNext和next,传入参数为Iterator,返回为Iterator;2
接着,根据输入的命令来拼接每个Iterator,得到最终的结果result(同样是Iterator);3
最后,输出result。4
上面的操作步骤中,123都没有对数据源进行任何操作,只是构造出了一套处理逻辑,最后的第4步看似是输出结果,其实在这一步里面数据才被加工。
优点:包含第一种思路的所有优点,而且第一种思路的缺点也得到解决,数据源任意大(因为内存里面永远只有当前正在处理的一行),而且即使中途出现问题,出现问题之前的正常数据也会得到正常的处理并且输出。
缺点:需要一直占用数据源的read句柄,其实占用的时间虽然比上一种方法长,也长不了多少
第一种方法占用的时间为:数据长度*(一次io时间 + 做一次处理的时间)
第二种方法占用的时间为:数据长度*(一次io时间 + 做多次处理的时间)
一般来说io时间是远大于处理时间的,因此占用时间其实是长不了多少的。
下面看第二种方法的代码:
主流程,根据命令构造一套处理逻辑
//result用于记录最后一个迭代器 Iterator<String> result = null; for (String command : commands) { List<String> args = splitter.omitEmptyStrings().splitToList(command); if (result == null) { //第一次执行的时候,result为空,需要对源文件进行处理得到源文件的迭代器 result = new FileIterator(new File(args.get(args.size() - 1))); } //根据命令名对相应的迭代器进行初始化 result = commandMap.getObject(args.get(0)).init(args, result); } return result;//构造文件迭代器FileIteratorprivate BufferedReader reader; private String line = null;public FileIterator(File file) throws FileNotFoundException { reader = Files.newReader(file, Charsets.UTF_8); }@Override public boolean hasNext() { try { line = (line == null) ? reader.readLine() : line; } catch (IOException e) { LOGGER.error("readLine() error", e); } if (line == null) { IOHandler.closeIgnoreException(reader); } return line != null; }@Override public String next() { try { String temp = (line == null) ? reader.readLine() : line; line = null; if(temp == null){ IOHandler.closeIgnoreException(reader); } return temp; } catch (IOException e) { LOGGER.error("readLine() error", e); } return null; }//Grep命令的迭代器(其他的差不多,就不贴了)private String filter; private String line = null;private void getLine() { String temp; while (line == null) { if (!parent.hasNext()) { break; } temp = parent.next(); if (temp.contains(filter)) { line = temp; break; } } }@Override public boolean hasNext() { getLine(); return line != null; }@Override public String next() { getLine(); String result = line; line = null; return result; }@Override public Iterator<String> init(List<String> args, Iterator<String> parent) { this.parent = parent; filter = args.get(1); return this; }
注:上面的代码都只是一部分,只是方便参看。
/*****************************2015-09-21*****************************/
重看这篇,当时主要是为了实践和体会老师介绍的一种方法,现在回头看,要做这个功能的话,没有必要用Iterator,功能方面是没问题,但是编码方面逻辑比较分散,后来维护的人比较难读。不如就用一个Queue,读到命令行时初始化queue,存入的类继承同一个接口,接口里设定处理方法和初始化方法,各命令类实现,初始化完成后得到一个处理逻辑的队列,读每一行遍历处理就好了。
当然之前的也是Iterator接口的一种使用方式,在合适的地方用合适的接口吧。
转载于:https://www.cnblogs.com/just84/p/4805386.html
java学习:Iterator数据加工厂相关推荐
- python本科生就业_准备报学习机构学习大数据、Java或者python,是计算机专业的本科生,请问选择哪种就业发展比较好?...
谢邀.对比java和python后者还算是小语种.不知道楼主的具体情况如何.根据个人情况,建议先学java,毕竟你目前的需求是尽快找到更合适的技术工作,java择业面相对较宽,虽然也难学,但学习资源丰 ...
- Java学习之容器上(Collection接口常用方法,Iterator接口,使用foreach循环遍历Collection集合元素,Set集合通用知识(Hashset类,hashcode()与Lin
1.容器API的类图结构如下: JAVA的集合类是一种特别有用的工具类,它可以用于存储数量不等的多个对象,并可以实现常用数据结构,如栈,队列等,除此之外,JAVA集合还可用于保存具有映射关系的关联数组 ...
- 什么是java的元数据_学习大数据,为什么要先学习Java?
是新朋友吗?记得先点蓝字关注我哦- 今日课程菜单 Java全栈开发 | Web前端+H5 大数据开发 | 数据分析 人工智能+Python | 人工智能+物联网 来源:小职(z_zhizuobiao ...
- 为何学习大数据,要先学Java
大数据的就业.工资的水平等等方面都让更多的人投身进入到学习大数据的旗下.在我之前写文章的时候,其实总是有这样的粉丝问我,你的这文章和大数据有关系?发出了这样的质疑. 其实,我们也不难发现,在外面报班学 ...
- 零基础是学习Java还是大数据?
大数据 可不是零基础就可以培训出来的,它是需要在特定环境下才能进行的,没有多少公司需要大数据的岗位,这个东西门槛很高. 说实话,我是不建议你直接报班学大数据的,但凡有点常识的人都知道,大数据的工作是已 ...
- 学习大数据的第13天——Java面向对象(接口、分析参数返回值的类型不同时如何解决、包以及访问权限修饰符(public、protected、默认、private))
学习大数据的第13天--Java面向对象(接口.分析参数返回值的类型不同时如何解决.包以及访问权限修饰符(public.protected.默认.private)) 接口 接口的基本定义: 1.1.语 ...
- java转大数据的学习路线
不要错过文末彩蛋] 申明: 本文旨在为普通程序员(Java程序员最佳)提供一个入门级别的大数据技术学习路径,不适用于大数据工程师的进阶学习,也不适用于零编程基础的同学. 前言: 一.背景介绍 二.大数 ...
- 初学者大数据java学习路线从入门到精通
大数据时代的出现简单的讲是海量数据同完美计算能力结合的结果,确切的说是移动互联网.物联网产生了海量的数据,大数据计算技术完美地解决了海量数据的收集.存储.计算.分析的问题.当我们最初谈大数据的时候,谈 ...
- java 与大数据学习较好的网站
C# C#中 Thread,Task,Async/Await,IAsyncResult 的那些事儿! https://www.cnblogs.com/doforfuture/p/6293926.htm ...
最新文章
- 近期Freecodecamp问题总结
- 第01章 PyTorch简介和安装 的学习笔记
- Centos7升级python
- docker 登陆mysql_启用登录docker mysql容器
- 重庆一银行发生火灾 浓烟直往外窜
- 使用 Castal DynamicProxy 简化 Silverlight 数据绑定
- GItHub--Makedown语法学习(快速入门)
- 阿里云数据库开源发布:PolarDB三节点高可用的功能特性和关键技术
- linux设备驱动模块引用和依赖
- linux开机自启动python脚本_Linux下Python脚本自启动和定时启动的详细步骤
- 快速上手Spring WebFlux框架
- 计算机win10+上锁,手把手教你在windows 10右键菜单中添加Bitlocker上锁/解锁教程-网络教程与技术
-亦是美网络...
- 岁月温柔-3 清明节医院复查,去昆明过冬是否会是一种奢望?
- 【记录】在新电脑安装Ubuntu16.04系统并移植虚拟机中catkin_ws过程
- python中复数的实部和虚部都是浮点数_Python基础:数值(布尔型、整型、长整型、浮点型、复数)...
- 27种迹象你该考虑辞掉程序员的工作
- 文心一言——何妨吟啸且徐行
- 流程二备选方案及评估
- 人生的极致:大道至简 知行合一
- java jsoup jar包_jsoup jar包
热门文章
- oracle剩余月份计算,[HELP]如何计算两个日期之间的月份(非MONTHS_BETWEEN)?
- 使用elementui实现表单上传功能_使用ElementUI中的upload组件上传Excel文件
- 网络推广外包介绍网站该如何加快收录量?
- 网站SEO优化该如何提高用户粘度?
- 网站页面内链如何布局才更有利于SEO?
- 搜索引擎蜘蛛为什么对网站不爬行呢?
- 某一列高度变化_高度近视,老了后会瞎吗?
- 记一次EventBus内存泄露导致的项目问题
- 大数据平台安全标准设计
- 超线程技术——超线程技术让(P4)处理器增加5%的裸晶面积,就可以换来15%~30%的效能提升,本质单核模拟双核!和异步编程的思想无异。...