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

com.diffplug.common.base.TreeDef Maven / Gradle / Ivy

There is a newer version: 3.4.0
Show newest version
/**
 * Copyright 2015 DiffPlug
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.diffplug.common.base;

import java.util.List;
import java.util.function.Function;
import java.util.function.Predicate;
import java.util.stream.Collectors;

/** Function which defines a Tree structure based on a root object. */
@FunctionalInterface
public interface TreeDef {
	/** Returns all the children of the given node. */
	List childrenOf(T node);

	/** Returns a new TreeDef which whose childrenOf() method is filtered by the given predicate. */
	default TreeDef filter(Predicate predicate) {
		return TreeDef.of(node -> filteredList(childrenOf(node), predicate));
	}

	/** Creates a TreeDef which is implemented by the given function. */
	public static  TreeDef of(Function> childFunc) {
		return new TreeDef() {
			@Override
			public List childrenOf(T node) {
				return childFunc.apply(node);
			}
		};
	}

	/**
	 * A "doubly-linked" tree, where nodes know about both their parent and their children.
	 * 
	 * It is CRITICAL that the TreeDef.Parented is consistent - if Vader claims that Luke
	 * and Leia are his children, then both Luke and Leia must say that Vader is their parent.
	 * 
	 * If Luke or Leia don't agree that Vader is their father, then the algorithms that use
	 * this TreeDef.Parented are likely to fail in unexpected ways.
	 */
	public interface Parented extends TreeDef {
		/** Returns the parent of the given node. */
		T parentOf(T node);

		/** Returns a new TreeDef which whose childrenOf() and parentOf() methods are filtered by the given predicate. */
		@Override
		default Parented filter(Predicate predicate) {
			return of(node -> filteredList(childrenOf(node), predicate), node -> {
				if (predicate.test(node)) {
					return parentOf(node);
				} else {
					return null;
				}
			});
		}

		/** Creates a TreeDef.Parented which is implemented by the given two functions. */
		public static  TreeDef.Parented of(Function> childFunc, Function parentFunc) {
			return new TreeDef.Parented() {
				@Override
				public List childrenOf(T node) {
					return childFunc.apply(node);
				}

				@Override
				public T parentOf(T node) {
					return parentFunc.apply(node);
				}
			};
		}
	}

	/** Returns a filtered version of the given list. */
	static  List filteredList(List unfiltered, Predicate filter) {
		return unfiltered.stream().filter(filter).collect(Collectors.toList());
	}
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy