
Baeldung Pro comes with both absolutely No-Ads as well as finally with Dark Mode, for a clean learning experience:
Once the early-adopter seats are all used, the price will go up and stay at $33/year.
Last updated: May 4, 2025
When processing JSON, data in the JSONObject class – commonly provided by libraries like org.json – is a fundamental building block. A frequent requirement is to extract all the keys from a JSON object for purposes like validation, transformation, or data mapping. The keySet() method provides a simple and efficient way to obtain all these keys as a Set<String>, allowing us to easily iterate over them or perform operations like filtering or transformation.
In essence, a JSONObject in Java behaves much like a Map<String, Object>. Each key is a String, and the associated values can be primitives, arrays, other JSONObjects, or even null. The keySet() method, available in implementations such as the JSON-Java (org.json) library, offers a way to directly access these keys without needing to convert or traverse the object manually. We can find more examples in an introduction to this library.
Let’s begin with a basic use case where we extract keys from a flat (non-nested) JSON object. Here’s a method that does exactly that:
public static Set<String> extractKeys(String jsonString) {
JSONObject jsonObject = new JSONObject(jsonString);
return jsonObject.keySet();
}
This method parses a JSON string into a JSONObject and then calls keySet() to retrieve all the top-level keys. To validate this behavior, let’s write a quick unit test:
@Test
public void givenFlatJson_whenExtractKeys_thenReturnAllTopLevelKeys() {
String json = "{\"name\":\"Jane\", \"name_id\":12345, \"city\":\"Vancouver\"}";
keys = JSONGetValueWithKeySet.extractKeys(json);
assertTrue(keys.contains("name"));
assertTrue(keys.contains("name_id"));
assertTrue(keys.contains("city"));
assertEquals(3, keys.size());
}
Thus, we accurately extract all expected keys from the flat structure.
Flat structures are easy to manage, but what if the JSON contains nested objects? In such cases, we can use a recursive approach to traverse the structure and collect keys at every level. To maintain clarity, we’ll use dot notation to indicate hierarchy (such as user.name or city.id).
Let’s implement this recursive traversal:
public static void extractNestedKeys(JSONObject jsonObject, String parentKey, Set<String> result) {
for (String key : jsonObject.keySet()) {
String fullKey = parentKey.isEmpty() ? key : parentKey + "." + key;
Object value = jsonObject.get(key);
result.add(fullKey);
if (value instanceof JSONObject) {
extractNestedKeys((JSONObject) value, fullKey, result);
}
}
}
With this method, we walk through each key-value pair and, if we encounter another JSONObject, we recursively continue the traversal while preserving the full path of the key.
Let’s verify this with a corresponding unit test:
@Test
public void givenNestedJson_whenExtractNestedKeys_thenReturnAllKeysWithHierarchy() {
String json = "{"
+ "\"user\": {"
+ "\"id\": 101,"
+ "\"name\": \"Gregory\""
+ "},"
+ "\"city\": {"
+ "\"id\": 121,"
+ "\"name\": \"Calgary\""
+ "},"
+ "\"region\": \"CA\""
+ "}";
JSONObject jsonObject = new JSONObject(json);
Set<String> actualKeys = new HashSet<>();
JSONGetValueWithKeySet.extractNestedKeys(jsonObject, "", actualKeys);
Set<String> expectedKeys = Set.of("user", "user.id", "user.name", "city",
"city.id", "city.name", "region");
assertEquals(expectedKeys, actualKeys);
}
This way, we ensure that all nested keys are captured and that the hierarchy is accurately reflected in the key names.
The main aspects we should remember when working with JSONObject structures are safety checks and efficient usage. We’d always check for null and ensure the value is a JSONObject before casting, to avoid exceptions. We should treat the set returned by keySet() as immutable since it’s backed by the original object. Thus, if we modify the set (for example, by removing keys), it will affect the JSONObject itself. If our JSON contains arrays, we’d consider whether we need to extract keys from objects within those arrays as well. Finally, by using keySet(), we ensure certain efficiency even with large JSON objects, since we avoid the overhead of converting to another data structure like a Map unless necessary.
Extracting keys from a JSONObject in Java is simple and efficient with the keySet() method. For flat JSON objects, a direct iteration over keySet() suffices. For nested structures, a recursive approach ensures all keys are captured, even deep within the hierarchy. When following best practices, such as proper type checks and understanding the mutability of the returned set, we can reliably work with JSON keys in our Java applications. The complete source code for this article can be found over on GitHub.