首页 > 解决方案 > JsonElement 中的递归键搜索不返回值

问题描述

我面临一个相对简单的递归函数的问题,我改编自Find value for a key from a dynamic json using java。该函数包括在嵌套的 JsonElement (arg2) 中搜索键 (arg1),如果该键在输入中匹配,则返回其对应的值。原始方法由一个 void 方法组成,该方法将值存储在一个静态列表中,但我需要更改该方法以返回一个字符串。

我面临的问题是,尽管该算法在找到正确的键并返回其值时设法在 JSON 的结构中进行递归搜索,但由于方法本身的递归调用,它实际上并没有退出该方法。这在此链接中进行了解释:Java Return not exiting method (loops)。因此,该方法始终返回“无值”字符串。

我尝试了不同的策略来解决这个问题,但没有成功。

我可以请你帮忙解决这个问题吗?

import java.util.Map;
import java.util.Set;

import com.google.gson.JsonArray;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;

public class Utils {
    
    public Utils() {}
    
    public String searchJson(String key, JsonElement jsonElement) {
        
        String value = "No value";
        
        // If input is an array, iterate through each element
        if (jsonElement.isJsonArray()) {
            for (JsonElement jsonElement1 : jsonElement.getAsJsonArray()) {
                searchJson(key, jsonElement1);
            }
        }
        
        else {
            
            // If input is object, iterate through the keys
            if (jsonElement.isJsonObject()) {
                Set<Map.Entry<String, JsonElement>> entrySet = jsonElement
                        .getAsJsonObject().entrySet();
                for (Map.Entry<String, JsonElement> entry : entrySet) {
                    
                    // If key corresponds to the 
                    String key1 = entry.getKey();
                    if (key1.equals(key)) {
                        value = entry.getValue().toString();
                        return value;
                    }
                    
                    // Use the entry as input, recursively
                    searchJson(key, entry.getValue());
                }
            }
            
            // If input is element, check whether it corresponds to the key
            else {
                if (jsonElement.toString().equals(key)) {
                    value = jsonElement.toString();
                    return value;
                }
            }
        }
        return value;
    }
    
    
    public static void main(String[] args) {
        
        Utils utils = new Utils();
        
        // Create JSON response
        String response = "{\"jsonData\":[{\"cards\":[{\"card\":\"MTE14019797\",\"Explanation\":{\"Message\":\"No explaination key identified\",\"Status\":\"Failed\"},\"Prediction\":{\"Confidence_intervals\":[{\"confidence\":\"0.614\",\"distance\":\"0.3\",\"range_lower\":\"1.117\",\"range_upper\":\"1.717\"}],\"Message\":\"\",\"Status\":\"Success\",\"point_estimate\":\"1.417\"}},{\"card\":\"MTE14019798\",\"Explanation\":{\"Message\":\"No explaination key identified\",\"Status\":\"Failed\"},\"Prediction\":{\"Confidence_intervals\":[{\"confidence\":\"0.584\",\"distance\":\"0.3\",\"range_lower\":\"1.852\",\"range_upper\":\"2.452\"}],\"Message\":\"\",\"Status\":\"Success\",\"point_estimate\":\"2.152\"}}],\"Status\":\"Success\",\"modelTarget\":\"MTEter\",\"modelType\":\"conformalRegression\",\"modelUpdated\":\"2020-09-01\",\"principalResults\":[\"point_estimate\",\"confidence\",\"distance\",\"modelUpdated\"]}]}\r\n";
        JsonParser parser = new JsonParser();
        JsonObject json = parser.parse(response.toString()).getAsJsonObject();
        
        System.out.println(json.toString());
        System.out.println();
        
        // Access card response
        JsonArray cardResponse = json.get("jsonData").getAsJsonArray()
                .get(0).getAsJsonObject()
                .get("cards").getAsJsonArray();
        
        // Iterate through individual responses
        Iterator<JsonElement> cardIter = cardResponse.iterator();
        
        while (cardIter.hasNext()) {
            
            // Select next card
            JsonObject card = cardIter.next().getAsJsonObject();
            System.out.println(card);
            
            String key = "Status";
            
            // TODO: Replace with variable from map
            // If selected card Id corresponds to that in the iterator, 
            // then search for the value associated to the selected end-point 
            String cardId = card.get("card").getAsString();
            if (cardId.equals("MTE14019798")) {
                String value = utils.searchJson(key, card);
                System.out.print(value);
            }
        }
    }
    
}```

标签: javajsonrecursion

解决方案


您没有在递归调用中返回值,因此它会丢失,您可以将返回值保存在变量中并检查 null,如果它不为 null,则您已找到该值,您可以从任何循环中中断并从递归函数返回.

我修改了一些部分,通过它。此外,在需要的地方添加空检查。

class Utils {

public Utils() {
}

public String searchJson(String key, JsonElement jsonElement) {

    String value = null;

    // If input is an array, iterate through each element
    if (jsonElement.isJsonArray()) {
        for (JsonElement jsonElement1 : jsonElement.getAsJsonArray()) {
            value = searchJson(key, jsonElement1);
            if (value != null) {
                return value;
            }
        }
    } else {

        // If input is object, iterate through the keys
        if (jsonElement.isJsonObject()) {
            Set<Map.Entry<String, JsonElement>> entrySet = jsonElement
                    .getAsJsonObject().entrySet();
            for (Map.Entry<String, JsonElement> entry : entrySet) {

                // If key corresponds to the
                String key1 = entry.getKey();
                if (key1.equals(key)) {
                    value = entry.getValue().toString();
                    return value;
                }

                // Use the entry as input, recursively
                value = searchJson(key, entry.getValue());
                if (value != null) {
                    return value;
                }
            }
        }

        // If input is element, check whether it corresponds to the key
        else {
            if (jsonElement.toString().equals(key)) {
                value = jsonElement.toString();
                return value;
            }
        }
    }
    return value;
}
}

class Main {
public static void main(String[] args) {

    Utils utils = new Utils();

    // Create JSON response
    String response = "{\"jsonData\":[{\"cards\":[{\"card\":\"MTE14019797\",\"Explanation\":{\"Message\":\"No explaination key identified\",\"Status\":\"Failed\"},\"Prediction\":{\"Confidence_intervals\":[{\"confidence\":\"0.614\",\"distance\":\"0.3\",\"range_lower\":\"1.117\",\"range_upper\":\"1.717\"}],\"Message\":\"\",\"Status\":\"Success\",\"point_estimate\":\"1.417\"}},{\"card\":\"MTE14019798\",\"Explanation\":{\"Message\":\"No explaination key identified\",\"Status\":\"Failed\"},\"Prediction\":{\"Confidence_intervals\":[{\"confidence\":\"0.584\",\"distance\":\"0.3\",\"range_lower\":\"1.852\",\"range_upper\":\"2.452\"}],\"Message\":\"\",\"Status\":\"Success\",\"point_estimate\":\"2.152\"}}],\"Status\":\"Success\",\"modelTarget\":\"MTEter\",\"modelType\":\"conformalRegression\",\"modelUpdated\":\"2020-09-01\",\"principalResults\":[\"point_estimate\",\"confidence\",\"distance\",\"modelUpdated\"]}]}\r\n";
    JsonParser parser = new JsonParser();
    JsonObject json = parser.parse(response.toString()).getAsJsonObject();

    System.out.println(json.toString());
    System.out.println();

    // Access card response
    JsonArray cardResponse = json.get("jsonData").getAsJsonArray()
            .get(0).getAsJsonObject()
            .get("cards").getAsJsonArray();

    // Iterate through individual responses
    Iterator<JsonElement> cardIter = cardResponse.iterator();

    while (cardIter.hasNext()) {

        // Select next card
        JsonObject card = cardIter.next().getAsJsonObject();
        System.out.println(card);

        String key = "Status";

        // TODO: Replace with variable from map
        // If selected card Id corresponds to that in the iterator,
        // then search for the value associated to the selected end-point
        String cardId = card.get("card").getAsString();
        if (cardId.equals("MTE14019798")) {
            String value = utils.searchJson(key, card);
            System.out.print(value);
        }
    }
}

}

推荐阅读