Phonebook using a trie
Naming:

name and surname are somewhat unclear in what they specifically mean. The "actual" purpose of these variables is to serve as "root" of the trie. Incidentally I'd rename ancestor to rootin all the usages in your code, simply because I'm more used to it. YMMV :)
I'd rename name and surname to nameRoot and surnameRoot.

Simplifications:


Initialize private fields that are not dependent on constructor arguments in the field declaration to save on space and complexity.
Use Comparator.comparing and thenComparing to simplify your comparator.


I personally also prefer to not leave too much space between fields.

private final Node name = new Node();
private final Node surname = new Node();
private static final Comparator&lt;Record&gt; comparator = Comparator.comparing(Record::getName)
    .thenComparing(Record::getSurname).thenComparing(Record::getNumber);


Note that I also changed the comparator to be static. It could also do with a better name, but I'm coming up empty right now...

Possible Trie Optimizations:

Currently your trie is using a lot of memory. It's not quite as bad as it could be, but considering that names are very much non-uniform, you will have a lot of "degenerated branches", where the branching factor is very low, if not 1 for "long" stretches of the data structure.

These long stretches of basically linked lists can be collapsed by sacrificing a WORD of memory to store how many characters you can skip before the next actual branching.

Currently Node does not support this in any way.



The traversal during add can be simplified a bit with computeIfAbsent like so:

for (final char c: str.toCharArray()) {
    final Node child = node.children.computeIfAbsent(c, Node::new);
    child.records.add(record);
    node = child;
}


This simplification pretty quickly vanishes when you implement the optimization mentioned above (or rather it becomes somewhat complicated).