import java.lang.ref.WeakReference;
import java.util.ArrayList;
public class Path{
private static Path sRoot = new Path(null, "ROOT");
private final Path mParent;
private final String mSegment;
private WeakReference<Object> mObject;
private IdentityCache<String, Path> mChildren;
private Path(Path parent, String segment){
mParent = parent;
mSegment = segment;
}
public Path getChild(String segment){
synchronized(Path.class){
if(mChildren == null){
mChildren = new IdentityCache<String, Path>();
}else{
Path p = mChildren.get(segment);
if(p != null)return p;
}
Path p = new Path(this, segment);
mChildren.put(segment, p);
return p;
}
}
public Path getParent(){
synchronized(Path.class){
return mParent;
}
}
public void setObject(Object object){
synchronized(Path.class){
mObject = new WeakReference<Object>(object);
}
}
public Object getObject(){
synchronized(Path.class){
return (mObject == null) ? null : mObject.get();
}
}
@Override
public String toString(){
synchronized(Path.class){
StringBuilder sb = new StringBuilder();
String[] segments = split();
for(int i = 0; i < segments.length; i++){
sb.append("/");
sb.append(segments[i]);
}
return sb.toString();
}
}
public static Path fromString(String s){
synchronized(Path.class){
String[] segments = split(s);
Path current = sRoot;
for(int i =0; i < segments.length; i++){
current = current.getChild(segments[i]);
}
return current;
}
}
public String[] split(){
synchronized(Path.class){
int n = 0;
for(Path p = this; p != sRoot; p = p.mParent){
n++;
}
String[] segments = new String[n];
int i = n - 1;
for(Path p = this; p != sRoot; p = p.mParent){
segments[i--] = p.mSegment;
}
return segments;
}
}
public static String[] split(String s){
int n = s.length();
if(n == 0)return new String[0];
if(s.charAt(0) != ‘/‘){
throw new RuntimeException("malformed pa");
}
ArrayList<String> segments = new ArrayList<String>();
int i = 1;
while(i < n){
int brace = 0;
int j;
for(j = i; j < n; j++){
char c = s.charAt(j);
if(c == ‘{‘)++brace;
else if(c == ‘}‘)--brace;
else if(brace == 0 && c == ‘/‘)break;
}
if(brace != 0){
throw new RuntimeException("un");
}
segments.add(s.substring(i,j));
i = j + 1;
}
String[] result = new String[segments.size()];
segments.toArray(result);
return result;
}
}
细节说明:
1. 构造函数是private的,这是因为Path要构建的是一个数据链表,而不仅仅是构造函数本身构建的对象。
Path对象节点结构如图:它包括一个引用指向mParent,同时包含一个容器对象mChildren,这个容器对象中保存着指向子节点的引用,这个引用与mSegment构成容器的键值对。

如上可知这是一个双向链表数据结构
2.
public Path getChild(String segment){
synchronized(Path.class){
if(mChildren == null){
mChildren = new IdentityCache<String, Path>();
}else{
Path p = mChildren.get(segment);
if(p != null)return p;
}
Path p = new Path(this, segment);
mChildren.put(segment, p);
return p;
}
}
分析一个函数,可以把它代入到实际的应用场景中去:
结合下一个将要说明的public static Path fromString(String s),我们知道Path链表数据对象是由getChild函数构建起来的,所以在构建对象的时候mChildren肯定是null的。例如String s = "/aaa/bbb/123"构建的path数据对象如下

path1, path2, path3三个对象便是通过getChild()生成的。
看看上面的链表,这是String s = "/aaa/bbb/123"对应的Path对象的样子。
之所以用双向链表替代String,则是因为需要利用双向链表的结构优势:假设Path p = Path.fromString(“/aaa/bbb”)表示一个集合,那么Path child = p.getChild("123")则可以表示这个集合对应的一个子集。
3.
public static Path fromString(String s){
synchronized(Path.class){
String[] segments = split(s);
Path current = sRoot;
for(int i =0; i < segments.length; i++){
current = current.getChild(segments[i]);
}
return current;
}
}
需要说明的是如2中的表格,通过这个静态类生成的path是最后一个child:path3,但是这里要再次申明这是一个链表结构数据,而不是单纯的只看当前对象。
细节说明:(a)、synchronzied(Path.class),这是类中静态函数是并发函数时的保护方式;(b)、fromString是static的,getChild是非static的,这里很好的诠释了静态函数中如何调用非静态方法——显然静态方法是类相关的,非静态方法是对象相关的,因此非静态方法可以直接调用静态方法,这样并不会产生错误,而静态方法要调用非静态方法必须是对象相关的,而不能直接调用方法。
原文:http://www.cnblogs.com/fordreamxin/p/5398742.html