Рекурсивно сгладить список с потоками - PullRequest
0 голосов
/ 05 октября 2018

У меня есть древовидная структура с внутренними узлами и терминальными узлами:

public interface Node
{
}

public class InternalNode implements Node {
    private List<Node> nodes;
}

public class TerminalNode implements Node {
    private String label;
}

Теперь у меня есть List<Node>, который я хочу сгладить.Здесь выравнивание означает, что я хочу рекурсивно заменить внутренние узлы его дочерними элементами, пока все внутренние узлы не будут заменены терминалами.

Я придумал эту функцию:

private static List<Node> flatten(final List<Node> nodes) {
    return nodes
            .stream()
            .map(node -> {
                if (node instanceof InternalNode) {
                    return flatten(((InternalNode) node).getNodes());
                }
                return Collections.singletonList(node);
            })
            .flatMap(List::stream)
            .collect(Collectors.toList());
}

Это кажетсяделать свою работу.Тем не менее, мне интересно, если есть лучшая реализация возможна.Кажется странным, что сначала я должен обернуть TerminalNode в одноэлементный список (типа List<TerminalNode>) через Collections.singletonList(node), а затем позже мне нужно снова преобразовать этот одноэлементный список обратно в узел через flatMap(List::stream).

Есть ли способ избежать этого бесполезного Collections.singletonList(node), за которым следует flatMap(List::stream) для терминальных узлов?

1 Ответ

0 голосов
/ 05 октября 2018

Вы можете просто использовать flatMap напрямую:

private static Stream<TerminalNode> flatten(final List<Node> nodes) {
    return nodes
            .stream()
            .flatMap(node -> {
                if (node instanceof InternalNode) {
                    return flatten(((InternalNode) node).getNodes());
                }
                return Stream.of((TerminalNode) node);
            });
}

Если вы хотите получить список, вы можете просто собрать результат этого вызова метода.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...