在Java中实现这种模式的最佳方法(内部的Python示例)?
我还不熟悉Java语言和库。。。我经常在Python中使用这种模式,我想知道应该如何用Java实现这种模式 我需要逐行读取一个带有某种xml标记的大型文件(我正在生成输入,因此我确信不会有任何歧义) 我想在大型文件的某些部分进行迭代,如下面的python代码: (使用yield/python迭代器模式…Java中是否有任何等效项?我真的很喜欢我的收藏中的在Java中实现这种模式的最佳方法(内部的Python示例)?,java,python,loops,Java,Python,Loops,我还不熟悉Java语言和库。。。我经常在Python中使用这种模式,我想知道应该如何用Java实现这种模式 我需要逐行读取一个带有某种xml标记的大型文件(我正在生成输入,因此我确信不会有任何歧义) 我想在大型文件的某些部分进行迭代,如下面的python代码: (使用yield/python迭代器模式…Java中是否有任何等效项?我真的很喜欢我的收藏中的for item:yield about(许多项)) 实现这种行为的最佳(java)方法是什么 thx 第一次编辑:顺便说一句,我也会对列表和文
for item:yield about(许多项)
)
实现这种行为的最佳(java)方法是什么
thx
第一次编辑:顺便说一句,我也会对列表和文件之间的类似映射感兴趣,在使用File和[Python List]时,从Python的角度来看,这两种映射都是可用的,当然,如果可以使用Java=>回答:请参阅Jeff Foster关于使用Apache.IOUtils的建议
def myAcc(instream, start, end):
acc = []
inside = False
for line in instream:
line = line.rstrip()
if line.startswith(start):
inside = True
if inside:
acc.append(line)
if line.startswith(end):
if acc:
yield acc
acc = []
inside = False
f = open("c:/test.acc.txt")
s = """<c>
<a>
this is a test
</a>
<b language="en" />
</c>
<c>
<a>
ceci est un test
</a>
<b language="fr" />
</c>
<c>
<a>
esta es una prueba
</a>
<b language="es" />
</c>"""
f = s.split("\n") # here mimic for a input file...
print "Reading block from <c> tag!"
for buf in myAcc(f, "<c>", "</c>"):
print buf # actually process this inner part... printing is for simplification
print "-" * 10
print "Reading block from <a> tag!"
for buf in myAcc(f, "<a>", "</a>"):
print buf # actually process this inner part...
print "-" * 10
Java不支持类似于
yield
,但是您可以通过创建一个接口来实现同样的功能,该接口封装了您将在单独的行上执行的操作
interface WorkerThing {
void doSomething(string lineOfText);
}
class ThatReadsLargeFiles {
public void readAHugeFile(WorkerThing actions) {
// TODO write some code to read through the file and store it in line
// Here you are yielding control to something else
action.doSomething(line);
}
}
当您使用它时,您可以使用匿名接口实现使事情稍微更容易忍受
new ThatReadsLargeFiles().readAHugeFile(new WorkerThing() {
void doSomething(string text) {
System.out.println(text);
}
};
如果我正确理解Python代码和您的任务,可以通过以下方式完成:
//表示要在字符串数组上调用的函数的回调
公共接口回调{
作废流程(列表行);
}
公共void进程文件(最终字符串路径、最终字符串开始、最终字符串结束、最终回调){
BufferedReader reader=null;
试一试{
最终文件读取器文件读取器=新文件读取器(路径);
reader=新的BufferedReader(文件读取器);
列表行=新的ArrayList();
布尔内部=假;
字符串行=null;
而((line=reader.readLine())!=null){
if(行开始与(开始)){
内=真;
}
如果(内部){
行。添加(行);
}
if(行开始与(结束)){
内=假;
回调。进程(行);
行=新的ArrayList();
}
}
//下面是正确关闭读者的样板
}捕获(最终IOEX){
例如printStackTrace();
}最后{
if(读卡器!=null){
试一试{
reader.close();
}捕获(最终IOE例外){
e、 printStackTrace();
}
}
}
}
然后在代码中的某个地方,您可以像下面这样调用此方法:
/。。。
//创建实现回调接口的类的实例(在Java中称为“匿名”类)
最终回调myCallback=新回调(){
公共作废流程(列表行){
用于(字符串行:行){
系统输出打印项次(行);
}
}
};
processFile(“路径/到/文件”,“我的回调”);
processFile(“路径/到/文件”,“我的回调”);
// ...
希望这有助于…我重新插入了以前无效的代码。我希望我做对了。(这就是为什么你应该使用空格,而不是制表符来缩进,最重要的是,永远不要将两者混用)谢谢!是的,我在另一个文本编辑器中粘贴时错过了这一点,只是为了在此处插入粘贴的空格,这样代码就可以被看到。非常感谢尤拉,对不起,我接受了杰夫·福斯特的答案,因为他是第一个,但你比我更快地重写了正确的代码!谢谢,编辑了我的问题,复制了你的答案,帮助我构建了一个工作代码。顺便问一下,是否可以映射文件和列表?所以它可以像Python一样通用?Apache.IOUtils可以提供帮助器方法将文件转换为列表,但没有通用(即内置到语言中)方法。谢谢!顺便说一句,这个解决方案还有另一个问题,那就是根据我的理解,如何将
doSomething
中的acc
分配给上层的var?这样就可以用在上面的通话中了?或者我应该问另一个这样的问题吗?最好是让类不匿名,然后捕获变量(例如MyWorkerThing=new MyWorkerThing();new ThatReadsLargeFiles(workerThing);string myAcc=workerThing.acc;好的,我明白了。我将编辑我的问题,为这一部分提供一个有效的示例答案。顺便说一句,由于acc.clear()
在我清除所有内容的代码中,我真的不明白为什么…但看起来重置acc必须使用acc=new ArrayList();
。。。
class betweenWorker implements WorkerThing {
private List<String> acc;
public void process(List<String> acc) {
this.acc = acc;
}
public List<String> getAcc() { return this.acc; }
}
interface WorkerThing {
void doSomething(string lineOfText);
}
class ThatReadsLargeFiles {
public void readAHugeFile(WorkerThing actions) {
// TODO write some code to read through the file and store it in line
// Here you are yielding control to something else
action.doSomething(line);
}
}
new ThatReadsLargeFiles().readAHugeFile(new WorkerThing() {
void doSomething(string text) {
System.out.println(text);
}
};
// callback representing function to be invoked on String array
public interface Callback {
void process(List<String> lines);
}
public void processFile(final String path, final String start, final String end, final Callback callback) {
BufferedReader reader = null;
try {
final FileReader fileReader = new FileReader(path);
reader = new BufferedReader(fileReader);
List<String> lines = new ArrayList<String>();
boolean inside = false;
String line = null;
while((line = reader.readLine()) != null) {
if(line.startsWith(start)) {
inside = true;
}
if(inside) {
lines.add(line);
}
if(line.startsWith(end)) {
inside = false;
callback.process(lines);
lines = new ArrayList<String>();
}
}
// following is just boilerplate to correctly close readers
} catch(final IOException ex) {
ex.printStackTrace();
} finally {
if(reader != null) {
try {
reader.close();
} catch(final IOException e) {
e.printStackTrace();
}
}
}
}
// ...
// creating instance of class implementing Callback interface (this is called 'anonymous' class in Java)
final Callback myCallback = new Callback() {
public void process(List<String> lines) {
for(String line : lines) {
System.out.println(line);
}
}
};
processFile("path/to/file", "<c>", "</c>", myCallback);
processFile("path/to/file", "<a>", "</a>", myCallback);
// ...