MongoDB的Java语法

Hal*_*000 15 java mongodb

我正在浏览MongoDB for java的介绍.有一些示例代码可以检索集合中的所有文档.代码有效,但我发现它有点......笨拙的缺乏一个更好的词.我想知道是否有一个特定的原因使它成为必要.给出的例子是:

FindIterable<Document> iterable = db.getCollection("restaurants").find();
iterable.forEach(new Block<Document>() {
    @Override
    public void apply(final Document document) {
        System.out.println(document);
    }
});
Run Code Online (Sandbox Code Playgroud)

是否有某些原因Block必须在上例中的每次迭代中创建一个forEach实例?为什么不能更简单一些:

FindIterable<Document> iterable = db.getCollection("restaurants").find();
for (Document document : iterable) {
    System.out.println(document);
}
Run Code Online (Sandbox Code Playgroud)

jye*_*min 33

虽然你当然可以使用你建议的表格:

for (Document document : col.find()) {
    // do something
}
Run Code Online (Sandbox Code Playgroud)

它会在for循环体引发异常时引入一个问题:如果发生这种情况,游标将不会被关闭.保护它的正确习惯是明确使用MongoCursor(实现Closeable):

try (MongoCursor<Document> cursor = col.find().iterator()) {
    while (cursor.hasNext()) {
        System.out.println(cursor.next());
    }
}
Run Code Online (Sandbox Code Playgroud)

forEach方法只是一些语法糖,以避免需要应用程序代码担心必须像这样手动关闭游标.

如果您不想为每次迭代创建一个新块,您可以重构您的代码拉出匿名内部类创建,例如:

Block<Document> block = new Block<Document>() {
    @Override
    public void apply(final Document document) {
        System.out.println(document);
    }
};
col.find().forEach(block);
Run Code Online (Sandbox Code Playgroud)

当然,这甚至更笨拙,所以如果你能够使用Java 8,你可以用lambda替换整个东西:

col.find().forEach((Block<Document>) document -> {
    System.out.println(document);
});
Run Code Online (Sandbox Code Playgroud)

或者在这种情况下简单地:

col.find().forEach((Block<Document>) System.out::println);
Run Code Online (Sandbox Code Playgroud)

拉姆达metafactory将确保不产生不必要的对象.

  • 任何`MongoIterable`类型 - 就像`find()`返回的类型一样,提供了迭代时可以使用的辅助方法.这些是'forEach`,`into`,`map`,当然还有`iterator`.`forEach`方法采用`Block`,它包含您要为每个文档执行的逻辑.在内部,它将为您迭代`MongoCursor`并确保它正确关闭. (2认同)

Wes*_*lor 7

我问自己同样的问题,我发现以下代码很容易处理这种情况:

List<Document> restaurants = db.getCollection("restaurants").find().into(new ArrayList<Document>());

for (Document restaurant : restaurants) {
    System.out.println(restaurant);
}
Run Code Online (Sandbox Code Playgroud)

  • 这会将整个结果集复制到内存中的集合中。根据结果​​的大小,这可能不切实际,甚至不可能。另一方面,forEach() 和 company 逐个处理条目,这适用于任意大小的结果集。 (3认同)