在Java中是否有标准的Java库类来表示树?
具体来说,我需要表示以下内容:
任意节点上的子树可以有任意数量的子树 每个节点(根节点之后)及其子节点都有字符串值 我需要得到一个给定节点的所有子(某种类型的列表或字符串数组),它的字符串值(即。一个方法,将一个节点作为输入,并返回子节点的所有字符串值作为输出)
是否有任何可用的结构,或者我需要创建我自己的(如果是这样,实施建议将是伟大的)。
在Java中是否有标准的Java库类来表示树?
具体来说,我需要表示以下内容:
任意节点上的子树可以有任意数量的子树 每个节点(根节点之后)及其子节点都有字符串值 我需要得到一个给定节点的所有子(某种类型的列表或字符串数组),它的字符串值(即。一个方法,将一个节点作为输入,并返回子节点的所有字符串值作为输出)
是否有任何可用的结构,或者我需要创建我自己的(如果是这样,实施建议将是伟大的)。
当前回答
我写了一个基于“HashMap”的小“TreeMap”类,它支持添加路径:
import java.util.HashMap;
import java.util.LinkedList;
public class TreeMap<T> extends LinkedHashMap<T, TreeMap<T>> {
public void put(T[] path) {
LinkedList<T> list = new LinkedList<>();
for (T key : path) {
list.add(key);
}
return put(list);
}
public void put(LinkedList<T> path) {
if (path.isEmpty()) {
return;
}
T key = path.removeFirst();
TreeMap<T> val = get(key);
if (val == null) {
val = new TreeMap<>();
put(key, val);
}
val.put(path);
}
}
它可以用来存储一个“T”(泛型)类型的树,但(目前)不支持在节点中存储额外的数据。如果你有一个这样的文件:
root, child 1
root, child 1, child 1a
root, child 1, child 1b
root, child 2
root, child 3, child 3a
然后你可以通过执行:
TreeMap<String> root = new TreeMap<>();
Scanner scanner = new Scanner(new File("input.txt"));
while (scanner.hasNextLine()) {
root.put(scanner.nextLine().split(", "));
}
你会得到一棵漂亮的树。它应该很容易适应你的需要。
其他回答
JDK中实际上实现了一个非常好的树结构。
看看javax.swing。tree、TreeModel和TreeNode。它们被设计为与JTreePanel一起使用,但实际上,它们是一个非常好的树实现,没有什么可以阻止你使用它与swing接口。
注意,从Java 9开始,你可能不希望使用这些类,因为它们不会出现在“压缩配置文件”中。
我写了一个处理通用树的小库。它比秋千轻多了。我也有一个专门的项目。
不使用Collection框架的Tree的自定义树实现。 它包含Tree实现所需的不同基本操作。
class Node {
int data;
Node left;
Node right;
public Node(int ddata, Node left, Node right) {
this.data = ddata;
this.left = null;
this.right = null;
}
public void displayNode(Node n) {
System.out.print(n.data + " ");
}
}
class BinaryTree {
Node root;
public BinaryTree() {
this.root = null;
}
public void insertLeft(int parent, int leftvalue ) {
Node n = find(root, parent);
Node leftchild = new Node(leftvalue, null, null);
n.left = leftchild;
}
public void insertRight(int parent, int rightvalue) {
Node n = find(root, parent);
Node rightchild = new Node(rightvalue, null, null);
n.right = rightchild;
}
public void insertRoot(int data) {
root = new Node(data, null, null);
}
public Node getRoot() {
return root;
}
public Node find(Node n, int key) {
Node result = null;
if (n == null)
return null;
if (n.data == key)
return n;
if (n.left != null)
result = find(n.left, key);
if (result == null)
result = find(n.right, key);
return result;
}
public int getheight(Node root){
if (root == null)
return 0;
return Math.max(getheight(root.left), getheight(root.right)) + 1;
}
public void printTree(Node n) {
if (n == null)
return;
printTree(n.left);
n.displayNode(n);
printTree(n.right);
}
}
没有回答提到过度简化但有效的代码,所以下面是:
public class TreeNodeArray<T> {
public T value;
public final java.util.List<TreeNodeArray<T>> kids = new java.util.ArrayList<TreeNodeArray<T>>();
}
在过去,我只是为此使用了一个嵌套映射。这是我今天用的,它很简单,但它符合我的需要。也许这能帮到另一个人。
import com.fasterxml.jackson.annotation.JsonValue;
import com.fasterxml.jackson.databind.ObjectMapper;
import java.util.HashMap;
import java.util.Map;
import java.util.TreeMap;
/**
* Created by kic on 16.07.15.
*/
public class NestedMap<K, V> {
private final Map root = new HashMap<>();
public NestedMap<K, V> put(K key) {
Object nested = root.get(key);
if (nested == null || !(nested instanceof NestedMap)) root.put(key, nested = new NestedMap<>());
return (NestedMap<K, V>) nested;
}
public Map.Entry<K,V > put(K key, V value) {
root.put(key, value);
return (Map.Entry<K, V>) root.entrySet().stream().filter(e -> ((Map.Entry) e).getKey().equals(key)).findFirst().get();
}
public NestedMap<K, V> get(K key) {
return (NestedMap<K, V>) root.get(key);
}
public V getValue(K key) {
return (V) root.get(key);
}
@JsonValue
public Map getRoot() {
return root;
}
public static void main(String[] args) throws Exception {
NestedMap<String, Integer> test = new NestedMap<>();
test.put("a").put("b").put("c", 12);
Map.Entry<String, Integer> foo = test.put("a").put("b").put("d", 12);
test.put("b", 14);
ObjectMapper mapper = new ObjectMapper();
System.out.println(mapper.writeValueAsString(test));
foo.setValue(99);
System.out.println(mapper.writeValueAsString(test));
System.out.println(test.get("a").get("b").getValue("d"));
}
}