/** * Creates a Tree of the given elements. * * @param <T> Component type of the List. * @param values Zero or more values. * @return A Tree containing the given values. * @throws NullPointerException if {@code values} is null */ @SuppressWarnings("varargs") @SafeVarargs static <T> Tree<T> of(T... values) { Objects.requireNonNull(values, "values is null"); List<T> list = List.of(values); return list.isEmpty() ? Empty.instance() : new Node<>(list.head(), list.tail().map(Tree::of)); }
/** * Creates a Tree of the given elements. * * <p>If the given iterable is a tree, it is returned as result. if the iteration order of the * elements is stable. * * @param <T> Component type of the List. * @param iterable An Iterable of elements. * @return A list containing the given elements in the same order. * @throws NullPointerException if {@code elements} is null */ @SuppressWarnings("unchecked") static <T> Tree<T> ofAll(Iterable<? extends T> iterable) { Objects.requireNonNull(iterable, "iterable is null"); if (iterable instanceof Tree) { return (Tree<T>) iterable; } else { final List<T> list = List.ofAll(iterable); return list.isEmpty() ? Empty.instance() : new Node<>(list.head(), list.tail().map(Tree::of)); } }
@SuppressWarnings("unchecked") @Override default <C> Map<C, Seq<T>> groupBy(Function<? super T, ? extends C> classifier) { Objects.requireNonNull(classifier, "classifier is null"); if (isEmpty()) { return HashMap.empty(); } else { return (Map<C, Seq<T>>) traverse().groupBy(classifier); } }
@Override default <U> Tree<Tuple2<T, U>> zipAll(Iterable<U> that, T thisElem, U thatElem) { Objects.requireNonNull(that, "that is null"); if (isEmpty()) { return Iterator.ofAll(that).map(elem -> Tuple.of(thisElem, elem)).toTree(); } else { final java.util.Iterator<U> thatIter = that.iterator(); final Tree<Tuple2<T, U>> tree = ZipAll.apply((Node<T>) this, thatIter, thatElem); if (thatIter.hasNext()) { final Iterable<Node<Tuple2<T, U>>> remainder = Iterator.ofAll(thatIter).map(elem -> Tree.of(Tuple.of(thisElem, elem))); return new Node<>(tree.getValue(), tree.getChildren().appendAll(remainder)); } else { return tree; } } }
/** * Returns a new Node containing the given value and having the given children. * * @param value A value * @param children The child nodes, possibly empty * @param <T> Value type * @return A new Node instance. */ static <T> Node<T> of(T value, Iterable<Node<T>> children) { Objects.requireNonNull(children, "children is null"); return new Node<>(value, List.ofAll(children)); }
/** * Constructs a rose tree branch. * * @param value A value. * @param children A non-empty list of children. * @throws NullPointerException if children is null * @throws IllegalArgumentException if children is empty */ public Node(T value, List<Node<T>> children) { Objects.requireNonNull(children, "children is null"); this.value = value; this.children = children; this.size = Lazy.of(() -> 1 + children.foldLeft(0, (acc, child) -> acc + child.length())); this.hashCode = 31 * 31 + 31 * Objects.hashCode(value) + Objects.hashCode(children); }
@Override public boolean equals(Object o) { if (o == this) { return true; } else if (o instanceof Node) { final Node<?> that = (Node<?>) o; return Objects.equals(this.getValue(), that.getValue()) && Objects.equals(this.getChildren(), that.getChildren()); } else { return false; } }
protected FilterJoinNode( Class joinClass, String[] joinColumns, String column, FilterExpress express, Serializable value) { Objects.requireNonNull(joinClass); Objects.requireNonNull(joinColumns); this.joinClass = joinClass; this.joinColumns = joinColumns; this.column = column; this.express = express; this.value = value; }
/** * {@inheritDoc} * * <p>This method will, on a best-effort basis, throw a {@link * java.util.ConcurrentModificationException} if the remapping function modified this map during * computation. * * @throws ConcurrentModificationException if it is detected that the remapping function modified * this map */ @Override public synchronized V computeIfPresent( K key, BiFunction<? super K, ? super V, ? extends V> remappingFunction) { Objects.requireNonNull(remappingFunction); Entry<?, ?> tab[] = table; int hash = key.hashCode(); int index = (hash & 0x7FFFFFFF) % tab.length; @SuppressWarnings("unchecked") Entry<K, V> e = (Entry<K, V>) tab[index]; for (Entry<K, V> prev = null; e != null; prev = e, e = e.next) { if (e.hash == hash && e.key.equals(key)) { int mc = modCount; V newValue = remappingFunction.apply(key, e.value); if (mc != modCount) { throw new ConcurrentModificationException(); } if (newValue == null) { if (prev != null) { prev.next = e.next; } else { tab[index] = e.next; } modCount = mc + 1; count--; } else { e.value = newValue; } return newValue; } } return null; }
/** * {@inheritDoc} * * <p>This method will, on a best-effort basis, throw a {@link * java.util.ConcurrentModificationException} if the mapping function modified this map during * computation. * * @throws ConcurrentModificationException if it is detected that the mapping function modified * this map */ @Override public synchronized V computeIfAbsent(K key, Function<? super K, ? extends V> mappingFunction) { Objects.requireNonNull(mappingFunction); Entry<?, ?> tab[] = table; int hash = key.hashCode(); int index = (hash & 0x7FFFFFFF) % tab.length; @SuppressWarnings("unchecked") Entry<K, V> e = (Entry<K, V>) tab[index]; for (; e != null; e = e.next) { if (e.hash == hash && e.key.equals(key)) { // Hashtable not accept null value return e.value; } } int mc = modCount; V newValue = mappingFunction.apply(key); if (mc != modCount) { throw new ConcurrentModificationException(); } if (newValue != null) { addEntry(hash, key, newValue, index); } return newValue; }
@Override default Tree<T> peek(Consumer<? super T> action) { Objects.requireNonNull(action, "action is null"); if (!isEmpty()) { action.accept(head()); } return this; }
public static <T, E> T getKeyByValue(Map<T, E> map, E value) { for (Map.Entry<T, E> entry : map.entrySet()) { if (Objects.equals(value, entry.getValue())) { return entry.getKey(); } } return null; }
@Override default Seq<T> distinctBy(Comparator<? super T> comparator) { Objects.requireNonNull(comparator, "comparator is null"); if (isEmpty()) { return Stream.empty(); } else { return traverse().distinctBy(comparator); } }
@Override default <U> U foldRight(U zero, BiFunction<? super T, ? super U, ? extends U> f) { Objects.requireNonNull(f, "f is null"); if (isEmpty()) { return zero; } else { return iterator().foldRight(zero, f); } }
@Override default <U> Tree<Tuple2<T, U>> zip(Iterable<U> that) { Objects.requireNonNull(that, "that is null"); if (isEmpty()) { return Empty.instance(); } else { return Zip.apply((Node<T>) this, that.iterator()); } }
@Override default Seq<T> filter(Predicate<? super T> predicate) { Objects.requireNonNull(predicate, "predicate is null"); if (isEmpty()) { return Stream.empty(); } else { return traverse().filter(predicate); } }
@Override default <U> Seq<T> distinctBy(Function<? super T, ? extends U> keyExtractor) { Objects.requireNonNull(keyExtractor, "keyExtractor is null"); if (isEmpty()) { return Stream.empty(); } else { return traverse().distinctBy(keyExtractor); } }
@SuppressWarnings("unchecked") @Override public synchronized void replaceAll(BiFunction<? super K, ? super V, ? extends V> function) { Objects.requireNonNull(function); // explicit check required in case // table is empty. final int expectedModCount = modCount; Entry<K, V>[] tab = (Entry<K, V>[]) table; for (Entry<K, V> entry : tab) { while (entry != null) { entry.value = Objects.requireNonNull(function.apply(entry.key, entry.value)); entry = entry.next; if (expectedModCount != modCount) { throw new ConcurrentModificationException(); } } } }
@SuppressWarnings("unchecked") @Override default Tuple2<Seq<T>, Seq<T>> span(Predicate<? super T> predicate) { Objects.requireNonNull(predicate, "predicate is null"); if (isEmpty()) { return Tuple.of(Stream.empty(), Stream.empty()); } else { return (Tuple2<Seq<T>, Seq<T>>) traverse().span(predicate); } }
@SuppressWarnings("unchecked") @Override default <T1, T2, T3> Tuple3<Tree<T1>, Tree<T2>, Tree<T3>> unzip3( Function<? super T, Tuple3<? extends T1, ? extends T2, ? extends T3>> unzipper) { Objects.requireNonNull(unzipper, "unzipper is null"); if (isEmpty()) { return Tuple.of(Empty.instance(), Empty.instance(), Empty.instance()); } else { return (Tuple3<Tree<T1>, Tree<T2>, Tree<T3>>) (Object) Unzip.apply3((Node<T>) this, unzipper); } }
@Override public synchronized boolean replace(K key, V oldValue, V newValue) { Objects.requireNonNull(oldValue); Objects.requireNonNull(newValue); Entry<?, ?> tab[] = table; int hash = key.hashCode(); int index = (hash & 0x7FFFFFFF) % tab.length; @SuppressWarnings("unchecked") Entry<K, V> e = (Entry<K, V>) tab[index]; for (; e != null; e = e.next) { if ((e.hash == hash) && e.key.equals(key)) { if (e.value.equals(oldValue)) { e.value = newValue; return true; } else { return false; } } } return false; }
// Idea: // Traverse (depth-first) until a match is found, then stop and rebuild relevant parts of the // tree. // If not found, return the same tree instance. static <T> Node<T> apply(Node<T> node, T currentElement, T newElement) { if (Objects.equals(node.getValue(), currentElement)) { return new Node<>(newElement, node.getChildren()); } else { for (Node<T> child : node.getChildren()) { final Node<T> newChild = Replace.apply(child, currentElement, newElement); final boolean found = newChild != child; if (found) { final List<Node<T>> newChildren = node.getChildren().replace(child, newChild); return new Node<>(node.getValue(), newChildren); } } return node; } }
@Override public synchronized V replace(K key, V value) { Objects.requireNonNull(value); Entry<?, ?> tab[] = table; int hash = key.hashCode(); int index = (hash & 0x7FFFFFFF) % tab.length; @SuppressWarnings("unchecked") Entry<K, V> e = (Entry<K, V>) tab[index]; for (; e != null; e = e.next) { if ((e.hash == hash) && e.key.equals(key)) { V oldValue = e.value; e.value = value; return oldValue; } } return null; }
@SuppressWarnings("unchecked") @Override public synchronized void forEach(BiConsumer<? super K, ? super V> action) { Objects.requireNonNull(action); // explicit check required in case // table is empty. final int expectedModCount = modCount; Entry<?, ?>[] tab = table; for (Entry<?, ?> entry : tab) { while (entry != null) { action.accept((K) entry.key, (V) entry.value); entry = entry.next; if (expectedModCount != modCount) { throw new ConcurrentModificationException(); } } } }
/** * Traverses the Tree in a specific order. * * @param order the tree traversal order * @return A List containing all elements of this tree, which is List if this tree is empty. * @throws java.lang.NullPointerException if order is null */ default Seq<T> traverse(Order order) { Objects.requireNonNull(order, "order is null"); if (isEmpty()) { return Stream.empty(); } else { switch (order) { case PRE_ORDER: return Traversal.preOrder(this); case IN_ORDER: return Traversal.inOrder(this); case POST_ORDER: return Traversal.postOrder(this); case LEVEL_ORDER: return Traversal.levelOrder(this); default: throw new IllegalStateException("Unknown order: " + order.name()); } } }
@Override public synchronized V putIfAbsent(K key, V value) { Objects.requireNonNull(value); // Makes sure the key is not already in the hashtable. Entry<?, ?> tab[] = table; int hash = key.hashCode(); int index = (hash & 0x7FFFFFFF) % tab.length; @SuppressWarnings("unchecked") Entry<K, V> entry = (Entry<K, V>) tab[index]; for (; entry != null; entry = entry.next) { if ((entry.hash == hash) && entry.key.equals(key)) { V old = entry.value; if (old == null) { entry.value = value; } return old; } } addEntry(hash, key, value, index); return null; }
@Override public synchronized boolean remove(Object key, Object value) { Objects.requireNonNull(value); Entry<?, ?> tab[] = table; int hash = key.hashCode(); int index = (hash & 0x7FFFFFFF) % tab.length; @SuppressWarnings("unchecked") Entry<K, V> e = (Entry<K, V>) tab[index]; for (Entry<K, V> prev = null; e != null; prev = e, e = e.next) { if ((e.hash == hash) && e.key.equals(key) && e.value.equals(value)) { if (prev != null) { prev.next = e.next; } else { tab[index] = e.next; } e.value = null; // clear for gc modCount++; count--; return true; } } return false; }
@Override protected FilterNode any(final FilterNode node0, boolean signor) { Objects.requireNonNull(node0); if (!(node0 instanceof FilterJoinNode)) { throw new IllegalArgumentException( this + (signor ? " or " : " and ") + " a node but " + String.valueOf(node0) + "is not a " + FilterJoinNode.class.getSimpleName()); } final FilterJoinNode node = (FilterJoinNode) node0; if (this.nodes == null) { this.nodes = new FilterNode[] {node}; this.or = signor; return this; } if (or == signor || this.column == null) { FilterNode[] newsiblings = new FilterNode[nodes.length + 1]; System.arraycopy(nodes, 0, newsiblings, 0, nodes.length); newsiblings[nodes.length] = node; this.nodes = newsiblings; if (this.column == null) this.or = signor; return this; } this.nodes = new FilterNode[] {new FilterJoinNode(node), node}; this.column = null; this.express = null; this.value = null; this.joinClass = null; this.joinEntity = null; this.joinColumns = null; this.or = signor; return this; }
/** * Returns a new Node containing the given value and having the given children. * * @param value A value * @param children The child nodes, possibly empty * @param <T> Value type * @return A new Node instance. */ @SuppressWarnings("varargs") @SafeVarargs static <T> Node<T> of(T value, Node<T>... children) { Objects.requireNonNull(children, "children is null"); return new Node<>(value, List.of(children)); }
@Override default Seq<T> takeWhile(Predicate<? super T> predicate) { Objects.requireNonNull(predicate, "predicate is null"); return traverse().takeWhile(predicate); }