All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.qwlabs.tree.TreeNode Maven / Gradle / Ivy

There is a newer version: 0.2.354
Show newest version
package com.qwlabs.tree;

import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonPropertyOrder;
import com.fasterxml.jackson.annotation.JsonUnwrapped;
import com.google.common.collect.Streams;
import lombok.Getter;
import lombok.Setter;

import java.util.List;
import java.util.Objects;
import java.util.Optional;
import java.util.function.BiConsumer;
import java.util.function.BiFunction;
import java.util.function.BiPredicate;
import java.util.function.Function;
import java.util.stream.Stream;

@Getter
@Setter
@JsonPropertyOrder(alphabetic = true)
@JsonInclude(value = JsonInclude.Include.NON_NULL)
public class TreeNode implements TreeNodeAble {

    @JsonUnwrapped
    private N node;

    private TreeNodes children;

    private TreeNodes safeChildren() {
        return Optional.ofNullable(children).orElseGet(TreeNodes::empty);
    }

    @Override
    public void forEach(BiConsumer>, TreeNode> consumer,
                        Location> parentLocation,
                        boolean parallel) {
        consumer.accept(parentLocation, this);
        var location = parentLocation.child(this);
        safeChildren().forEach(consumer, location, parallel);
    }

    @Override
    public  Optional> find(List path,
                                          BiPredicate, E> filter,
                                          boolean parallel) {
        if (path.isEmpty()) {
            return Optional.of(this);
        }
        var findFor = path.get(0);
        var found = filter.test(this, findFor);
        if (!found) {
            return Optional.empty();
        }
        if (path.size() == 1) {
            return Optional.of(this);
        }
        var childPath = path.subList(1, path.size());
        return children.find(childPath, filter, parallel);
    }

    @Override
    public Optional>> find(BiPredicate>, TreeNode> filter,
                                                Location> parentLocation,
                                                boolean parallel) {
        var location = parentLocation.child(this);
        if (filter.test(parentLocation, this)) {
            return Optional.of(location);
        }
        return safeChildren().find(filter, location, parallel);
    }

    @Override
    public  Stream all(BiFunction>, TreeNode, R> mapper, Location> parentLocation) {
        var location = parentLocation.child(this);
        Stream childStream = safeChildren().all(mapper, location);
        return Streams.concat(childStream, Stream.of(mapper.apply(parentLocation, this)));
    }

    public  TreeNode map(BiFunction>, TreeNode, R> mapper) {
        return map(mapper, Location.root(), false);
    }

    public  TreeNode mapParallel(BiFunction>, TreeNode, R> mapper) {
        return map(mapper, Location.root(), true);
    }

    public  TreeNode map(BiFunction>, TreeNode, R> mapper,
                               boolean parallel) {
        return map(mapper, Location.root(), parallel);
    }

    public  TreeNode map(BiFunction>, TreeNode, R> mapper, Location> parentLocation) {
        return map(mapper, parentLocation, false);
    }

    public  TreeNode mapParallel(BiFunction>, TreeNode, R> mapper, Location> parentLocation) {
        return map(mapper, parentLocation, true);
    }

    public  TreeNode map(BiFunction>, TreeNode, R> mapper,
                               Location> parentLocation,
                               boolean parallel) {
        R newNode = mapper.apply(parentLocation, this);
        var newTreeNode = new TreeNode();
        var location = parentLocation.child(this);
        newTreeNode.setNode(newNode);
        newTreeNode.setChildren(safeChildren().map(mapper, location, parallel));
        return newTreeNode;
    }

    public  R map(TreeNodeFunction mapper) {
        return map(mapper, Location.root(), false);
    }

    public  R mapParallel(TreeNodeFunction mapper) {
        return map(mapper, Location.root(), true);
    }

    public  R map(TreeNodeFunction mapper, boolean parallel) {
        return map(mapper, Location.root(), parallel);
    }

    public  R map(TreeNodeFunction mapper,
                     Location> parentLocation) {
        return map(mapper, parentLocation, false);
    }

    public  R mapParallel(TreeNodeFunction mapper,
                             Location> parentLocation) {
        return map(mapper, parentLocation, true);
    }

    public  R map(TreeNodeFunction mapper,
                     Location> parentLocation,
                     boolean parallel) {
        var location = parentLocation.child(this);
        var children = safeChildren().map(mapper, location, parallel);
        return mapper.apply(parentLocation, this, children);
    }

    public  R map(Function mapper) {
        return mapper.apply(node);
    }

    public TreeNode addChildren(TreeNode... addChildren) {
        if (addChildren != null && addChildren.length > 0) {
            TreeNodes children = Optional.ofNullable(getChildren())
                .orElseGet(TreeNodes::of);
            children.addAll(List.of(addChildren));
            setChildren(children);
        }
        return this;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) {
            return true;
        }
        if (o == null || getClass() != o.getClass()) {
            return false;
        }
        TreeNode treeNode = (TreeNode) o;
        return Objects.equals(node, treeNode.node) && Objects.equals(children, treeNode.children);
    }

    @Override
    public int hashCode() {
        return Objects.hash(node, children);
    }

    public static  TreeNode of(N node) {
        var treeNode = new TreeNode();
        treeNode.setNode(node);
        return treeNode;
    }

    public static  TreeNode of(N node, TreeNode... children) {
        var treeNode = new TreeNode();
        treeNode.setNode(node);
        treeNode.addChildren(children);
        return treeNode;
    }

    public static  TreeNode of(N node, TreeNodes children) {
        var treeNode = new TreeNode();
        treeNode.setNode(node);
        treeNode.setChildren(children);
        return treeNode;
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy