Java新型可搜索树创建及JSON指定数据提取技术问询
Hey there! Let's tackle your two Java-related problems one by one, starting with the JSON extraction issue since you mentioned hitting roadblocks there.
power Value for a Specific username It sounds like your JsonPath attempt returned an empty array because your expression was likely misaligned with the JSON structure. Let's fix that first, then cover both JsonPath and native JSON library solutions.
Correct JsonPath Approach
The right JsonPath expression to target the power value for username: "knighthero" is:
$.data[?(@.registrant.username == 'knighthero')].power
Breakdown:
$.data: Navigates to the root-leveldataarray[?()]: Filters array elements that match the condition inside@: References the current array element being evaluatedregistrant.username == 'knighthero': Matches elements where the nestedusernamematches your target.power: Extracts thepowervalue from matching elements
Here's a working Java example using the Jayway JsonPath library:
import com.jayway.jsonpath.JsonPath; import java.util.List; public class JsonPathExtractor { public static void main(String[] args) { String json = "{ \"data\": [ { \"power\": 75, \"registrant\": { \"group\": \"elf\", \"username\": \"kevin23\" } }, { \"power\": 34, \"registrant\": { \"group\": \"fairy\", \"username\": \"msi56\" } }, { \"power\": 150, \"registrant\": { \"group\": \"orc\", \"username\": \"knighthero\" } } ] }"; // Extract matching power values List<Integer> powerValues = JsonPath.read(json, "$.data[?(@.registrant.username == 'knighthero')].power"); if (!powerValues.isEmpty()) { System.out.println("Power value: " + powerValues.get(0)); // Outputs 150 } else { System.out.println("No matching user found"); } } }
Native JSONObject/JSONArray Approach
If you prefer using Java's built-in JSON libraries (no external dependencies), you can manually iterate through the array:
import org.json.JSONArray; import org.json.JSONObject; public class NativeJsonExtractor { public static void main(String[] args) { String json = "{ \"data\": [ { \"power\": 75, \"registrant\": { \"group\": \"elf\", \"username\": \"kevin23\" } }, { \"power\": 34, \"registrant\": { \"group\": \"fairy\", \"username\": \"msi56\" } }, { \"power\": 150, \"registrant\": { \"group\": \"orc\", \"username\": \"knighthero\" } } ] }"; JSONObject root = new JSONObject(json); JSONArray dataArray = root.getJSONArray("data"); int targetPower = -1; String targetUsername = "knighthero"; for (int i = 0; i < dataArray.length(); i++) { JSONObject userObj = dataArray.getJSONObject(i); JSONObject registrant = userObj.getJSONObject("registrant"); if (registrant.getString("username").equals(targetUsername)) { targetPower = userObj.getInt("power"); break; } } if (targetPower != -1) { System.out.println("Power value: " + targetPower); // Outputs 150 } else { System.out.println("No matching user found"); } } }
For a custom searchable tree, we'll build a flexible, generic implementation that supports custom search criteria (like filtering by node properties). This design lets you adapt it to different data types and search needs.
Step 1: Define the Tree Node
First, create a generic node class to hold data and child nodes:
import java.util.ArrayList; import java.util.List; public class SearchableTreeNode<T> { private T data; private List<SearchableTreeNode<T>> children; public SearchableTreeNode(T data) { this.data = data; this.children = new ArrayList<>(); } // Getters and setters public T getData() { return data; } public void setData(T data) { this.data = data; } public List<SearchableTreeNode<T>> getChildren() { return children; } public void addChild(SearchableTreeNode<T> child) { children.add(child); } }
Step 2: Build the Searchable Tree
Create a tree class with recursive search logic, using a Predicate to let you define custom search conditions:
import java.util.ArrayList; import java.util.List; import java.util.function.Predicate; public class SearchableTree<T> { private SearchableTreeNode<T> root; public SearchableTree(T rootData) { this.root = new SearchableTreeNode<>(rootData); } // Search all nodes that match the given condition public List<SearchableTreeNode<T>> search(Predicate<T> condition) { List<SearchableTreeNode<T>> results = new ArrayList<>(); searchRecursive(root, condition, results); return results; } private void searchRecursive(SearchableTreeNode<T> currentNode, Predicate<T> condition, List<SearchableTreeNode<T>> results) { // Check if current node matches the condition if (condition.test(currentNode.getData())) { results.add(currentNode); } // Recursively search child nodes for (SearchableTreeNode<T> child : currentNode.getChildren()) { searchRecursive(child, condition, results); } } // Helper method to add a child node to a parent public void addChildNode(SearchableTreeNode<T> parent, T childData) { parent.addChild(new SearchableTreeNode<>(childData)); } }
Step 3: Usage Example
Let's use the tree with a sample User class to search for users by username or power level:
// Sample data class class User { private String username; private int power; public User(String username, int power) { this.username = username; this.power = power; } // Getters public String getUsername() { return username; } public int getPower() { return power; } @Override public String toString() { return "User{username='" + username + "', power=" + power + "}"; } } // Demo the tree public class TreeDemo { public static void main(String[] args) { // Create tree with a root node (e.g., a top-level group) SearchableTree<User> userTree = new SearchableTree<>(new User("root_group", 0)); // Add child nodes and groups SearchableTreeNode<User> orcGroup = new SearchableTreeNode<>(new User("orc_group", 0)); userTree.addChildNode(orcGroup, new User("knighthero", 150)); userTree.addChildNode(orcGroup, new User("orc_warrior", 120)); SearchableTreeNode<User> elfGroup = new SearchableTreeNode<>(new User("elf_group", 0)); userTree.addChildNode(elfGroup, new User("kevin23", 75)); userTree.addChildNode(userTree.root, orcGroup); userTree.addChildNode(userTree.root, elfGroup); // Search for user "knighthero" List<SearchableTreeNode<User>> targetUser = userTree.search(user -> user.getUsername().equals("knighthero")); System.out.println("Found user: " + targetUser.get(0).getData()); // Search for users with power > 100 List<SearchableTreeNode<User>> highPowerUsers = userTree.search(user -> user.getPower() > 100); System.out.println("\nHigh-power users:"); highPowerUsers.forEach(node -> System.out.println(node.getData())); } }
Extensions You Can Add
- Performance optimizations: Add caching for frequent searches, or use a balanced tree structure (like AVL or Red-Black) if your data is ordered.
- Non-recursive search: Implement an iterative approach using a stack/queue to avoid stack overflow with deep trees.
- Advanced search: Add support for fuzzy matching, range queries, or sorting results.
内容的提问来源于stack exchange,提问作者basviccc

