基于管道过滤器风格的-KWIC
1、题前分析
kwic是什么到低要解决什么问题?
看这段英文的变化,输入的值的是绿色圈出的部分,第一次处理后的结果是橙色圈出的部分,第三次处理的结果是红色圈出的部分,第一次处理,先是对句话进行了切分,是按照单词之间的空格进行切分,将一整句话切分成多个单词,然后对这些单词的进行移位,每次都将第一个单词放在末尾从而组成新的句子,这样经过第一次处理之后,HELLO WORLD 这句话就变成了两句话HELLO WORLD 和WORLD HELLO。接下来进行第二步处理,对这几句话按照首字母进行排序,从而得到最终的结果。
2、管道过滤器风格
实现代码如下
第一版:(具体的思路看代码的注释)
package com.bren.cn;
import java.io.IOException;
import java.util.ArrayList;
import java.util.StringTokenizer;
import java.io.PipedInputStream;
import java.io.PipedOutputStream;
/**
*
* @author huihui 基于管道过滤器模式,这是第一版
*/
public class mypip {
/**
* 第一步我应该有一个管道 我需要导入java的管道流的包
* @throws IOException
*/
public static void main(String[] args) throws IOException {
/**
* 输入管道流
*/
PipedInputStream inPip;
PipedOutputStream outPip;
/**
* 管道相连
*/
inPip= new PipedInputStream();
outPip = new PipedOutputStream();
try {
inPip.connect(outPip);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
/**
* 第二步我需要向管道中读入数据"Hello Yolo I am Boss"
*/
byte[] out = new byte[1024];
byte[] in = new byte[1024];
String s = new String("hello yolo i am boss");//这里我可以按行读取一个外部的文件
outPip.write(s.getBytes());//向管道中写入数据
outPip.close();
/**
* 第三步我需要使用过滤器对管道中的数据进行切分
* 1、先拿取管道中的数据
* 2、进行切分移位之后再放回管道中
*/
int len = 0;
len=inPip.read(in);//从管道中拿取数据
s = new String(in, 0, len);//得到字符串s
inPip.close();
//1、切分
StringTokenizer tokener = new StringTokenizer(s," ");
//2、进行移位操作
String token = new String();
int index;
ArrayList<String> tokens = new ArrayList<String>();
int count = tokener.countTokens();
for (int j = 0; j < count; j++) {//将一行解析,并且将解析的word加入ArrayList中
token = tokener.nextToken();
tokens.add(token);
}
ArrayList<String> kwicList = new ArrayList<String>();
//对ArrayList中的字进行循环移位,得出最后结果
for (int i = 0; i < count; i++) {
index=i;
StringBuffer linebuffer = new StringBuffer();
for (int j = 0; j < count; j++) {
if (index >= count)
index = 0;
linebuffer.append ( tokens.get(index) );
linebuffer.append (" ");
index++;
}
String line = linebuffer.toString();
kwicList.add(line);
}
/**
* 3、移位之后再次写入到管道中,进行下一个过滤器
*/
PipedInputStream inPip2;
PipedOutputStream outPip2;
/**
* 管道相连
*/
inPip2= new PipedInputStream();
outPip2 = new PipedOutputStream();
try {
inPip2.connect(outPip2);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
String s1="";
for (int count1 = 0; count1 < kwicList.size(); count1++) {
s1 =s1+kwicList.get (count1)+"\n";
}
System.out.println(s1);
outPip2.write(s1.getBytes());
outPip2.close();
/**
* 4、再次读取管道中的数据、进行首字母排序处理,按照换行符读取形成字符串数组
*/
System.out.println("输出in"+in[0]);
len = inPip2.read(in);
s = new String(in, 0, len);
String []ss= s.split("\n").clone();
ArrayList<String> list=new ArrayList<String>();
for(String n:ss) {
System.out.println("输出"+n);
}
list.sort(null);
for(int coun=0;coun<list.size();coun++)
{
System.out.println(list.get(coun));
}
}
}
第二版(对代码进行分离)
1、先是要向管道中放入数据,所以创建一个mInput类。该类的方法Input(String filename)使用 BufferedReader bufread按行读取文件的数据,然后放入管道中pip.getOutPip().write(s.getBytes());。
mInput类
package com.ren.cn;
import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;
/**
*
* @author huihui
* 按行读取文件的数据并返回一个字符串的list
*/
public class mInput {
private BufferedReader bufread=null;
private ArrayList<String> list=new ArrayList<String>();
String s="";
private Pipe pip=null;
public mInput(Pipe pip) {
this.pip=pip;
}
public void Input(String filename) {
try {
bufread= new BufferedReader(new FileReader(filename));
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
try {
while((s=bufread.readLine())!=null) {
pip.getOutPip().write(s.getBytes());
}
bufread.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
2、将数据从管道中取出,进行第一次的过滤,对数据进行移位处理,从而形成一些移位后新的句子 Move类,详细解释看代码中的注释,移位完成之后,还要将数据再送回管道。
Move类
package com.ren.cn;
import java.io.IOException;
import java.io.PipedInputStream;
import java.io.PipedOutputStream;
import java.util.ArrayList;
import java.util.StringTokenizer;
/**
*
* @author huihui 这个类提供移位的方法
*/
public class Move {
byte[] out = new byte[1024];
byte[] in = new byte[1024];
int len = 0;
String s = "";
Pipe pip=null;
public Move(Pipe pip) {
this.pip=pip;
}
public void mymove() {
try {
len = pip.getInPip().read(in);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} // 从管道中拿取数据
s = new String(in, 0, len);// 得到字符串s
// 1、切分
StringTokenizer tokener = new StringTokenizer(s, " ");
// 2、进行移位操作
String token = new String();
int index;
ArrayList<String> tokens = new ArrayList<String>();
int count = tokener.countTokens();
for (int j = 0; j < count; j++) {// 将一行解析,并且将解析的word加入ArrayList中
token = tokener.nextToken();
tokens.add(token);
}
ArrayList<String> kwicList = new ArrayList<String>();
// 对ArrayList中的字进行循环移位,得出最后结果
for (int i = 0; i < count; i++) {
index = i;
StringBuffer linebuffer = new StringBuffer();
for (int j = 0; j < count; j++) {
if (index >= count)
index = 0;
linebuffer.append(tokens.get(index));
linebuffer.append(" ");
index++;
}
String line = linebuffer.toString();
kwicList.add(line);
}
/**
* 3、移位之后再次写入到管道2中,进行下一个过滤器
*/
String s1 = "";
for (int count1 = 0; count1 < kwicList.size(); count1++) {
s1 = s1 + kwicList.get(count1) + "\n";
}
try {
pip.getOutPip().write(s1.getBytes());
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
3、再将数据从管道中取出,进行首字母排序的处理,使用基于数组的容器ArrayList ,调用其方法sort进行一键排序,将排好序的这些句子又重新放回管道。
InOrder类
package com.ren.cn;
/**
*
* @author huihui
*进行排序并且再次写入到下一个管道中
*/
import java.io.IOException;
import java.util.ArrayList;
public class InOrder {
private ArrayList<String> list = null;
private byte[] in = new byte[1024];
private String s1 = "";
private Pipe pip=null;
public InOrder(Pipe pip) {
this.pip=pip;
}
public void inorder() {
int len;
try {
len = pip.getInPip().read(in);
String s = new String(in, 0, len);
String[] ss = s.split("\n").clone();
list = new ArrayList<String>();
for (String n : ss) {
list.add(n);
}
list.sort(null);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
for (int count1 = 0; count1 < list.size(); count1++) {
s1 = s1 + list.get(count1) + "\n";
}
try {
pip.getOutPip().write(s1.getBytes());
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
4、最后再从管道中取出处理好的数据,写入到新的文件中,详细看代码注释
mOutput类
package com.ren.cn;
/**
*
* @author huihui
*将所得的结果放回到文件中
*/
import java.io.BufferedWriter;
import java.io.FileWriter;
import java.io.IOException;
import java.util.ArrayList;
public class mOutput {
BufferedWriter writer=null;
String s="";
private Pipe pip;
byte[] b = new byte[1024];
public mOutput(Pipe pip) {
this.pip=pip;
}
public void Output(String filename,ArrayList<String>list){
try {
writer =new BufferedWriter(new FileWriter(filename));
int len = 0;
len=pip.getInPip().read(b);//从管道中拿取数据
s = new String(b, 0, len);
writer.write(s);
writer.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
5、当然了使用管道,对管道中的数据进行操作,怎么能没有管道呢!!!管道类,专门负责创建管道
Pipe类
package com.ren.cn;
import java.io.IOException;
import java.io.PipedInputStream;
import java.io.PipedOutputStream;
/**
*
* @author huihui
* 这是一个管道类,专门用于创建管道
*/
public class Pipe {
private PipedInputStream inPip;
private PipedOutputStream outPip;
public Pipe() {
outPip=new PipedOutputStream();
inPip= new PipedInputStream();
try {
inPip.connect(outPip);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public PipedInputStream getInPip() {
return inPip;
}
public PipedOutputStream getOutPip() {
return outPip;
}
}
6、在main方法中进行测试
package com.ren.cn;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.PipedInputStream;
import java.io.PipedOutputStream;
import java.util.ArrayList;
public class test {
/**
* 进行测试(这是最终版)
*
* @param args
* @throws IOException
*/
public static void main(String[] args) {
String out = "";
Pipe pip=new Pipe();
BufferedReader list = null;
ArrayList<String> outlist =new ArrayList<String>();
String filename = "main.txt";//要读取的文件
String filenameout="test.txt";//最后写入的文件
/**
* 1、输入文件
*/
mInput input = new mInput(pip);
input.Input(filename);
/**
* 2、进行移位
*/
Move mv = new Move(pip);
mv.mymove();
/**
* 3、进行排序
*/
InOrder inorder = new InOrder(pip);
inorder.inorder();
/**
* 4、写出文件
*/
mOutput oput=new mOutput(pip);
oput.Output(filenameout, outlist);
/**
* 5、关闭管道
*/
try {
pip.getInPip().close();
pip.getOutPip().close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
7、最后差点忘了,应该贴上一张UML图
8、使用eclipse,自动生成类图!!别着急走,继续看
右击项目,选择new 选择other
选择这个
从而得到这样一个文件
打开这个newfile.cld文件然后选择所有的java文件,往这个newfile.cld文件中拖拽
就自动生成类图了。
参考内容:https://blog.csdn.net/it_man/article/details/5003836?locationNum=8
本文地址:https://blog.csdn.net/hui1097/article/details/109842257