Filtering through a JSON document using Java 8 Stream API involves converting the JSON document into a stream of objects and then using the filter method to select the objects that match a given condition. Here are the steps to filter through a JSON document using Java 8 Stream API.
Plain Java Streams filtering
Java Streams are wrappers around a data source, which allow us to operate with a data source, making bulk processing convenient and fast. A stream does not store data and, for this reason, is not a data structure. It also never modifies the underlying data source.
There are many usages of Java Streams API however we will show here how it can be used to filter through data. Consider the following example:
List<String> list = Arrays.asList("apple", "peach", "banana"); List<String> result = list.stream() // convert list to stream .filter(line -> !"apple".equals(line)) // we exclude apple .collect(Collectors.toList()); // collect the output and convert streams to a List result.forEach(System.out::println); //output : peach banana
How can we use the same to filter a JSON Document? Let’s assume you have the following JSON Document:
{ "name": "School ABC", "topics": [ "Math", "Science", "Music", "History", "English" ], "classrooms": [ "SectionA", "SectionB", "SectionC" ], "notes": null, "active": true, "visitors": 10000000 }
So, assumed that you have loaded your javax.json.JsonObject in a variable named ‘jsonObject’, here is how you can filter through the topics which start with ‘M’:
private JsonObject jsonObject = loadJsonObject(); public List<String> filterJsonArrayToList() { List<String> topics = jsonObject.getJsonArray("topics").stream() .filter(jsonValue -> ((JsonString) jsonValue).getString().startsWith("M")) .map(jsonValue -> ((JsonString) jsonValue).getString()) .collect(Collectors.toList()); return topics; }
That will return a List of Strings (‘Math’,’Music’). On the other hand, if you want it as JsonArray, you can use the following code:
public JsonArray filterJsonArrayToJsonArray() { JsonArray topics = jsonObject.getJsonArray("topics").stream() .filter(jsonValue -> ((JsonString) jsonValue).getString().startsWith("C")) .collect(JsonCollectors.toJsonArray()); return topics; }
Filtering JSON with Jackson
If you want a more concise version, you can use Jackson databinding to simplify filtering JSON Data in combination with the Stream API. Let’s see a practical example of it:
///usr/bin/env jbang "$0" "$@" ; exit $? //DEPS com.fasterxml.jackson.core:jackson-core:2.14.2 //DEPS com.fasterxml.jackson.core:jackson-databind:2.14.2 //DEPS com.fasterxml.jackson.core:jackson-annotations:2.14.2 import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.ObjectMapper; import java.util.stream.Collectors; import java.util.stream.Stream; import java.util.stream.StreamSupport; public class Main { public static void main(String[] args) throws Exception { // Example JSON document String jsonString = "[{\"name\": \"John\", \"age\": 30}, {\"name\": \"Jane\", \"age\": 25}, {\"name\": \"Bob\", \"age\": 35}]"; // Parse the JSON document ObjectMapper objectMapper = new ObjectMapper(); JsonNode jsonNode = objectMapper.readTree(jsonString); // Convert the JSON document to a stream of objects Stream<JsonNode> stream = StreamSupport.stream(jsonNode.spliterator(), false); // Filter the stream of objects Stream<JsonNode> filteredStream = stream.filter(node -> node.get("name").asText().equals("John")); // Convert the filtered stream back to a JSON document JsonNode filteredJsonNode = objectMapper.valueToTree(filteredStream.collect(Collectors.toList())); String filteredJsonString = objectMapper.writeValueAsString(filteredJsonNode); // Print the filtered JSON document System.out.println(filteredJsonString); } }
Firstly, we will mention that the above source code contains JBang comments so that you can run it from the shell with no project attached to it. If you are new to JBang we recommend checking this article: JBang: Create Java scripts like a pro
In this example, the main method reads in a sample JSON document as a string, parses it into a JsonNode object using the Jackson library, converts it into a stream of JsonNode objects, filters the stream to only include objects where the “name” field is equal to “John”, and then converts the filtered stream back into a JsonNode object and prints it out as a string.
You can run this class to see the filtered JSON document printed to the console.
jbang Main.java [{"name":"John","age":30}]
Conclusion
There are several options to filter through a JSON document using Java Stream API. In this article we have covered a plain Java Stream solution and another example which uses Jackson dependencies to simplify the filtering of data