我想构建一个 immutable 树数据结构,表示filsystem目录结构的任意子集。通常会有一个过滤器知道包含/排除,我基本上希望在构造中有一些线程支持。
这听起来像编写自己的纯粹书呆子乐趣,但我实际上想知道这个主题是否有任何好的例子,文本或类似内容?源代码很好;)
答案 0 :(得分:1)
答案 1 :(得分:0)
我不知道这是否有用。 Java SortedMap使用红黑树,你可以在这里查看源代码。
https://www.docjar.com/html/api/org/eclipse/ant/internal/ui/dtd/util/SortedMap.java.html
对于不可修改的SortedMap。你可以在这里看到Collections.unmodifiableSortepMap的源代码
http://www.docjar.com/html/api/java/util/Collections.java.html
答案 2 :(得分:0)
我建议维护一个“工作项目”队列。每个工作项都封装一个要探索的目录,以及一个将生成的树节点附加到的现有父节点(如果有)。每个线程在循环中执行,从队列前面拉出项目,执行它们,并将任何子目录作为新工作项推送到队列末尾。
通过将根目录(没有父树节点)作为第一个工作项来启动该过程。当队列为空,并且所有线程都空闲/等待时,该过程结束。
以上假设树一旦构造就是不可变的,但在构造过程中是可变的。如果不是这种情况,则需要构建树“自下而上”,因此您需要一个临时的,可变的结构来保存节点,因为它们被追加。否则,过程应该是相同的。
答案 3 :(得分:0)
致krosenvold:
我认为你没有理解我的意图。也许我应该让自己更清楚。
假设Tree和TreeBuilder在同一个包中。
正如您所见,Tree构造函数和freeze()方法具有包级别访问权限。所以你不能在包外面创建它,也不能在包外面冻结它。
唯一的方法是通过build()方法。只有TreeBuilder可以使用同步的构建方法创建Tree。
现在我甚至意识到你甚至可以更简单地删除readonly标志并将Tree.addChild()方法更改为包可见性。因此,您将获得一个没有公共mutators的树只有访问者。
就像我说Tree没有同步。 TreeBuilder是您进行同步的地方。仔细查看访问器和更改器。查看public和package修饰符所在的位置,您将看到修改树的唯一方法是当您在同一个包中时,只有树构建器才能执行此操作。
public class Tree<T extends Filterable>{
private final T data;
private Tree<T> parent;
private List<Tree<T>> children;
private List<FilterChain<T>> filterChain;
private boolean readonly = false;
/*package*/ Tree(T data) {...}
/*package*/ Tree(Tree<T> parent, T data) {...}
/*package*/ void addChild(Tree<T> child){
children.add(child);
}
public List<?> getResults(){
return data.returnResults(filterChain);
}
}
public class TreeBuilder<T>{
public synchronized TreeNode createRoot(T data);
public synchronized void addSubElement(TreeNode parentNode ,T data);
public synchronized void addFilter(TreeNode node, Filter<T> filter);
public Tree<T> synchronized build(){
Tree<T> tree= ...
//build your tree
//build filter chain for specific tree node
return tree;
}
}
答案 4 :(得分:-1)
嗨我不知道你想要什么,特别是在线程安全方面,但也许在伪代码下可以用作草案。
public interface Filterable {
List<?> returnResults(FilterChain chain);
}
public class Tree<T extends Filterable>{
private final T data;
private Tree<T> parent;
private List<Tree<T>> children;
private List<FilterChain<T>> filterChain;
private boolean readonly = false;
/*package*/ Tree(T data) {...}
/*package*/ Tree(Tree<T> parent, T data) {...}
//freeze mtd makes object read-only
/*package*/ void freeze(){
readonly = true;
for(Tree<T> child: children){
child.freeze();
}
}
public void addChild(Tree<T> child){
if(readonly){
throws new NonModifiableException(...);
}
children.add(child);
}
public List<?> getResults(){
return data.returnResults(filterChain);
}
}
您可以专注于在树的构建器上进行同步
,而不是在树上进行同步public class TreeBuilder<T>{
public synchronized TreeNode createRoot(T data);
public synchronized void addSubElement(TreeNode parentNode ,T data);
public synchronized void addFilter(TreeNode node, Filter<T> filter);
public Tree<T> synchronized build(){
Tree<T> tree= ...
//build your tree
//build filter chain for specific tree node
tree.freeze(); //make your tree readonly
return tree;
}
}