简体   繁体   English

通过HashSet进行迭代会清空HashMap条目

[英]Iterating through HashSet empties HashMap entry

The following method gets a "Route" (class name and class method): 以下方法获取“ Route”(类名和类方法):

public Route getRoute(final String method, final String request) {
    if (hasRoutes) {
        for (Map.Entry<Pattern, HashMap<String, String>> entry : routes) {
            Matcher match = entry.getKey().matcher(request);

            if (match.find()) {
                HashMap<String, String> methods = entry.getValue();

                // ISSUE: Returns FALSE after 1st call of Router.getRoute()
                if (methods.containsKey(method)) {
                    return new Route(match.group("interface"), "TRUE (" + method + " - " + match.group("interface") + "): " + methods.get(method));
                } else {
                    return new Route(match.group("interface"), "FALSE (" + method + " - " + match.group("interface") + "): " + methods.values().toString() + ", SIZE: " + entry.getValue().size());
                }

                //return entry.getValue().containsKey(method) ? new Route(match.group("interface"), entry.getValue().get(method)) : null;
            }
        }
    }

    return null;
}

"routes" is defined as: “路线”定义为:

private Set<Entry<Pattern, HashMap<String, String>>> routes;

It is a cached representation of a JSON configuration file that defines supported routes, eg: 它是JSON配置文件的缓存表示,定义了支持的路由,例如:

{
    "^/?(?<interface>threads)/?$": {
        "GET": "list",
        "POST": "create"
    },
    "^/?(?<interface>threads)/(?<id>\\d+)/?$": {
        "GET": "get",
        "POST": "reply",
        "PUT": "edit",
        "PATCH": "edit",
        "DELETE": "delete"
    }
}

EDIT, here's how "routes" is filled from the contents of the JSON file: 编辑,这是从JSON文件的内容填充“路线”的方式:

    try {
        JsonParser parser = JSONFactory.createJsonParser(in);
        JsonNode root = JSONMapper.readTree(parser);
        Iterator base = root.getFieldNames();
        Iterator node;
        String match, method;
        HashMap<Pattern, HashMap<String, String>> routesMap = new HashMap();

        while (base.hasNext()) {
            match = base.next().toString();

            if (match != null) {
                node = root.get(match).getFieldNames();
                HashMap<String, String> methods = new HashMap();

                while (node.hasNext()) {
                    method = node.next().toString();

                    if (method != null) {
                        methods.put(method, root.get(match).get(method).getTextValue());
                    }
                }

                if (!methods.isEmpty()) {
                    routesMap.put(Pattern.compile(match), methods);
                }
            }
        }

        if (!routesMap.isEmpty()) {
            hasRoutes = true;
            routes = routesMap.entrySet();
        }

        // Help garbage collection
        parser = null;
        root = null;
        base = null;
        node = null;
        match = null;
        method = null;
        routesMap = null;
    } catch (Exception ex) {
    }

EDIT 2, properties in question & init() method: 编辑2,有问题的属性和init()方法:

public final static JsonFactory JSONFactory = new JsonFactory();
public final static ObjectMapper JSONMapper = new ObjectMapper();
public static Router router;
private final Class self = getClass();
private final ClassLoader loader = self.getClassLoader();

public void init(ServletConfig config) throws ServletException {
    super.init(config);

    router = new Router(self.getResourceAsStream("/v1_0/Routes.json"), JSONFactory, JSONMapper);
}

For some reason when accessing the servlet after the first time the HashMap is empty of values. 出于某种原因,第一次访问HashMap时没有值。 A x.size() returns zero. x.size()返回零。

This is a rewrite of a PHP application from the ground up so I apologise in advance if the issue is something mundane. 这是从头开始重写的PHP应用程序,因此,如果问题是世俗的,我提前表示歉意。

Full source: - Router source - Route source 完整来源:- 路由器来源 - 路由来源

Iterating through HashSet empties HashMap entry 通过HashSet进行迭代会清空HashMap条目

That doesn't happen. 那不会发生。 Simply iterating a HashSet has no side-effects on the set's contents. 简单地迭代HashSet对集合的内容没有副作用。

There is something else going on here that is causing your problem. 这里还有其他事情正在引起您的问题。

Your getOptions() method removes every entry from this map as it iterates. 您的getOptions()方法会在迭代时从此映射中删除所有条目。 So, after calling getOptions() once, the map is empty. 因此,一次调用getOptions()后,映射为空。

By the way, assigning null to variables does not "help the garbage collector." 顺便说一句,为变量分配null 不会 “帮助垃圾收集器”。 The garbage collector knows that when the scope of a variable is exited, that variable no longer references the object. 垃圾收集器知道退出变量的范围时,该变量不再引用该对象。 You are actually slowing things down by assigning values ( null ) that can never be read (as well as cluttering your code with counterproductive noise). 实际上,您通过分配永远无法读取的值( null )来减慢运行速度(以及使代码产生适得其反的噪音)。 A good static analysis tool like FindBugs will warn you that this is bad code. 像FindBugs这样的好静态分析工具会警告您这是错误的代码。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM