使用 MongoDB 的 Java 语法

2022-09-02 19:18:17

我正在浏览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);
    }
});

是否出于某种原因必须在上述示例的每次迭代中创建实例?为什么不做一些更简单的事情,比如:BlockforEach

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

答案 1

虽然您当然可以使用您建议的表单:

for (Document document : col.find()) {
    // do something
}

当 for 循环的主体引发异常时,它引入了一个问题:如果发生这种情况,游标将不会关闭。防止这种情况的正确习语是显式使用MongoCursor(实现Closeable):

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

forEach方法只是一点语法上的糖,以避免应用程序代码担心必须像这样手动关闭光标。

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

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

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

col.find().forEach((Block<Document>) document -> {
    System.out.println(document);
});

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

col.find().forEach((Block<Document>) System.out::println);

lambda 元工厂将确保不会创建不必要的对象。


答案 2

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

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

for (Document restaurant : restaurants) {
    System.out.println(restaurant);
}