Simulate the "cd" command of a file system
Overcomplicated

The implementation is really overcomplicated and hard to read.


  It works, but I feel there must be better way to do that?


Your instincts are good. When you know there's a better way, something you can try is start over from scratch using a different algorithm and see where that goes. Another technique is using TDD and let the tests drive your design.

Poor readability

The code is too compactly written at many places, for example:


    if( "".equals(this.path)||"".equals(newPath)||!this.path.startsWith("/"))
    // ...

    return this.cd(newPath.length()&gt;1?newPath.substring(1):"");
    // ...

    return this.cd(newPath.length()&gt;3?newPath.substring(3):"");



This is really hard to read like that and doesn't help the understandability of the code.
All modern IDE's have an auto-reformat function that will put spaces around operators and make the code much easier to read.

Normalization

The cd method effectively normalizes the path, for example a/b/.. becomes correctly a. But the initial path passed to the constructor is never normalized. For example new Path("/a/b/../..").cd("c").getPath() returns /a/b/../../c instead of c.

This is a bit confusing inconsistency. It would be better to normalize the initial path too.

With a good normalizer method, the implementation of cd itself could be much simpler:

public Path cd(String newPath) {
    if (isAbsolutePath(newPath)) {
        path = normalizePath(newPath);
        return this;
    }

    path = normalizePath(path + SEPARATOR + newPath);
    return this;
}


In this case, of course, normalizePath does the real heavy lifting.
It could go something like this:

private String normalizePath(String path) {
    boolean isAbsolute = isAbsolutePath(path);

    List&lt;String&gt; parts = new ArrayList&lt;&gt;();
    for (String part : path.split(SEPARATOR)) {
        if (part.isEmpty() || part.equals(".")) {
            continue;
        }
        if (part.equals("..")) {
            if (parts.isEmpty()) {
                if (isAbsolute) {
                    continue;
                }
            } else {
                if (!parts.get(parts.size() - 1).equals("..")) {
                    parts.remove(parts.size() - 1);
                    continue;
                }
            }
        }
        parts.add(part);
    }

    String prefix = isAbsolute ? SEPARATOR : "";
    return prefix + String.join(SEPARATOR, parts);
}


Bug or unclear specs?

What should new Path("a/b").cd("..").getPath() return?
I would expect a, but in fact it gives a/b.

What about new Path("a/b").cd("../../..").getPath()?
I would expect .., but it gives a/b for this too.

Special treatment of ...

There is a condition for path segments starting with .... Why is that? The description says that directory names contain only letters of the alphabet.
That makes this special treatment odd.
It seems that such path segment is illegal, and throwing an IllegalArgumentException would seem appropriate.

Testing

For something a bit tricky like this,
the main method in the class is really far too little to verify that the class works well.
Not to mention of course that testing in a main method is not a good way.
I strongly recommend to develop test cases and cover as many interesting corner cases as possible, to flush out obscure bugs.