删除mongodb iteratior报错:java.lang.UnsupportedOperationException: Cursors do not support removal

错误信息

Caused by: java.lang.UnsupportedOperationException: Cursors do not support removal
	at com.mongodb.client.internal.MongoBatchCursorAdapter.remove(MongoBatchCursorAdapter.java:44) ~[mongodb-driver-sync-4.0.3.jar:na]
	at com.example.demo.service.MongoService.getHisUserInfo(MongoService.java:55) ~[classes/:na]
	at com.example.demo.MongoDbCommandLinner.run(MongoDbCommandLinner.java:21) ~[classes/:na]
	at org.springframework.boot.SpringApplication.callRunner(SpringApplication.java:795) [spring-boot-2.3.0.RELEASE.jar:2.3.0.RELEASE]
	... 5 common frames omitted

代码demo

package com.example.demo.service;

import java.util.HashMap;
import java.util.Map;

import org.bson.Document;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.stereotype.Service;

import com.mongodb.BasicDBObject;
import com.mongodb.client.FindIterable;
import com.mongodb.client.MongoCollection;
import com.mongodb.client.MongoCursor;
import com.mongodb.client.MongoDatabase;

@Service
public class MongoService {

    @Autowired
    private MongoTemplate mongoTemplate;

    private MongoCollection<Document> getCollection() {
        MongoDatabase mongoDatabase = mongoTemplate.getMongoDbFactory().getMongoDatabase("mytest");
        MongoCollection<Document> collection = mongoDatabase.getCollection("his_data");
        return collection;
    }

    public Map<String, Object> getHisUserInfo(String name) {
        Map<String, Object> result = new HashMap<>();
        MongoCollection<Document> collection = getCollection();

        BasicDBObject filter = new BasicDBObject();
        filter.append("name", name);

        BasicDBObject showCols = new BasicDBObject();
        showCols.append("addr", 1).append("age", 1).append("_id", 0);

        FindIterable<Document> find = collection.find(filter).limit(1);
        MongoCursor<Document> iterator = find.iterator();

        Document doc = null;
        while (iterator.hasNext()) {
            doc = iterator.next();
            break;
        }

        if (doc != null) {
            result.put("name", name);
            result.put("addr", doc.get("addr"));
            result.put("age", doc.get("age"));
        }

        iterator.remove();

        return result;
    }
}

调用getHisUserInfo方法时,出现异常

测试List遍历删除

我们知道如果一个集合中的数据遍历获取后,就不再需要了,对于这种情况,边遍历边删除是一种比较好的处理方式,可以节省内存

public static void main(String[] args) {
        List<String> list = new ArrayList<String>();
        list.add("test 001");
        list.add("test 002");
        list.add("test 003");
        
        System.out.println("before remove: " + list);
        Iterator<String> iterator = list.iterator();
        while(iterator.hasNext()) {
            iterator.remove();
        }
        System.out.println("after remove: " + list);
        
    }

运行结果

before remove: [test 001, test 002, test 003]
Exception in thread "main" java.lang.IllegalStateException
	at java.util.ArrayList$Itr.remove(Unknown Source)
	at com.example.demo.CommonTest.main(CommonTest.java:18)

删除时出现了异常,之前每太注意过这种情况,查看remove方法api介绍

从这个异常情况的描述信息可知,在调用iterator的remove方法时,要先调用其next方法,否则就会发生这样的异常,再while循环中remove方法调用前调用下next,确实是可以正常删除,此处不再贴出来代码,其实我们如果要清空一个集合,肯定也不会用这种方式来清空,直接调用list的clear方法更好,如果要删除指定的元素,也会调用下next方法,判断其值后进行删除,所以一般也不会出现什么问题。

Mongodb迭代删除异常原因

从上述遍历删除从mongodb获取的数据可以看出,已经调用了next方法,但是还会出现异常,究其原因,是由于ArrayList重写了Iterator的remmove方法,从mongodb删除报错的异常信息看,

MongoBatchCursorAdapter中的remove方法抛出的异常,我们进入到该类,查看其remove方法,

mongodb不允许我们在取出元素的同时,对其做删除操作

原文地址:https://www.cnblogs.com/qq931399960/p/12899618.html