Import Java.lang.ref.weakreference;import java.util.arraylist;public class Path{private static path Sroot = New Path ( NULL, "ROOT");p rivate 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 ();}} @Overridepublic 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;}}
Detail Description:
1. The constructor is private because path is building a list of data, not just objects built by the constructor itself.
Path object node structure it includes a reference to Mparent, and a container object Mchildren, which holds a reference to a child node, which is a reference to the msegment that constitutes the container's key-value pair.
As you know, this is a doubly linked list data structure.
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;}}
Analyzing a function, you can put it into the actual application scenario:
In conjunction with the next public static path FromString (String s) that will be described, we know that the Path linked list data object is built by the Getchild function, so mchildren must be null when building the object. For example, the path data object built by string s = "/aaa/bbb/123" is as follows
path1, path2, path3 three objects are generated by Getchild ().
Look at the list above, which is the path object that the string s = "/aaa/bbb/123" corresponds to.
The reason for using a doubly linked list instead of string is the need to take advantage of the structural advantages of a doubly linked list: Suppose that path p = path.fromstring ("/aaa/bbb") represents a collection, then path child = P.getchild ("123") You can represent a subset of this collection .
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;}}
What needs to be stated is that the path generated by this static class is the last child:path3, such as the table in 2, but here again it is a list structure data, rather than simply looking at the current object.
Details: (a), synchronzied (Path.class), which is the protection of static functions in the class is the concurrency function, (b), fromstring is static, Getchild is non-static, This is a good illustration of how static functions are called non-static methods-apparently static methods are class-related, non-static methods are object-dependent, so non-static methods can call static methods directly, which does not produce errors, and static methods to invoke non-static methods must be object-dependent, but not directly called methods.
Java Project Source Code learning Note (ii): Path