在Java中实现这种模式的最佳方法(内部的Python示例)?

在Java中实现这种模式的最佳方法(内部的Python示例)?,java,python,loops,Java,Python,Loops,我还不熟悉Java语言和库。。。我经常在Python中使用这种模式,我想知道应该如何用Java实现这种模式 我需要逐行读取一个带有某种xml标记的大型文件(我正在生成输入,因此我确信不会有任何歧义) 我想在大型文件的某些部分进行迭代,如下面的python代码: (使用yield/python迭代器模式…Java中是否有任何等效项?我真的很喜欢我的收藏中的for item:yield about(许多项)) 实现这种行为的最佳(java)方法是什么 thx 第一次编辑:顺便说一句,我也会对列表和文

我还不熟悉Java语言和库。。。我经常在Python中使用这种模式,我想知道应该如何用Java实现这种模式

我需要逐行读取一个带有某种xml标记的大型文件(我正在生成输入,因此我确信不会有任何歧义)

我想在大型文件的某些部分进行迭代,如下面的python代码:

(使用yield/python迭代器模式…Java中是否有任何等效项?我真的很喜欢我的收藏中的
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);
// ...