private Node<T> internalFind(String key, boolean search) {
        int lastPos = 0;
        int nextDot = -1;
        Node<T> current = root;
        Node<T> wildcard = null;
        boolean done = false;

        while (!done) {
            String segment;

            nextDot = key.indexOf('.', lastPos);
            if (nextDot > 0) {
                segment = key.substring(lastPos, nextDot);
            } else {
                segment = key.substring(lastPos); // remainder
                done = true; // last segment
            }

            if (search) { // SEARCH, called from find(..)
                if (current.wildcardKid != null) {
                    wildcard = current.wildcardKid;
                }

                // Look for the node for the next package segment
                Node<T> next = current.findChild(segment);
                if (next == null) {
                    if (wildcard == null) {
                        // no match...
                        return null;
                    }
                    current = wildcard;
                } else {
                    current = next;
                }
            } else { // ADD, called from add(..)
                // Find or create new node, then proceed to the next
                current = current.findOrCreateChild(segment);
            }

            lastPos = nextDot + 1;
        }

        return current;
    }
private Node < T > internalFind ( String key , boolean search ) { int lastPos = 0 ; int nextDot = - 1 ; Node < T > current = root ; Node < T > wildcard = null ; boolean done = false ; while ( ! done ) { String segment ; nextDot = key . indexOf ( '.' , lastPos ) ; if ( nextDot > 0 ) { segment = key . substring ( lastPos , nextDot ) ; } else { segment = key . substring ( lastPos ) ; done = true ; } if ( search ) { if ( current . wildcardKid != null ) { wildcard = current . wildcardKid ; } Node < T > next = current . findChild ( segment ) ; if ( next == null ) { if ( wildcard == null ) { return null ; } current = wildcard ; } else { current = next ; } } else { current = current . findOrCreateChild ( segment ) ; } lastPos = nextDot + 1 ; } return current ; }
This does the actual work for both add and find (as the paths are very similar).
Note that matching behavior will change based on whether or not we're adding elements
into the trie. If we're adding, the match will be exact: A * is a exactly and only a *.
If we are searching, then the * behaves as a wildcard for matching.

@param key Key to lookup or to add.
@param search If true, we're in search mode. Otherwise, we're adding.
@return Matched TrieNode, or null if not found.