/** * 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)); } }
/** * Die Liste pList wird an die Liste angehaengt. Anschliessend wird pList eine leere Liste. Das * aktuelle Objekt bleibt unveraendert. Falls pList null oder eine leere Liste ist, bleibt die * Liste unveraendert. * * @param pList Liste */ public void concat(List pList) { Node lCurrent1, lCurrent2, lPos0; if (pList != null && !pList.isEmpty()) { if (this.isEmpty()) { first = pList.first; tail = pList.tail; current = tail; } else { lPos0 = current; current = tail.getNext(); lCurrent1 = current; pList.toFirst(); current = pList.current; lCurrent2 = pList.current; lCurrent1.setNext(lCurrent2); if (lPos0 != tail) { current = lPos0; } else { current = pList.tail; } tail = pList.tail; } // pList wird zur leeren Liste pList.tail = new Node(null); // Dummy pList.first = pList.tail; pList.tail.setNext(tail); pList.current = pList.tail; } }
/** * Binds the given function across each element of this list with a final join. * * @param f The function to apply to each element of this list. * @return A new list after performing the map, then final join. */ public <B> NonEmptyList<B> bind(final F<A, NonEmptyList<B>> f) { final List.Buffer<B> b = new List.Buffer<B>(); final NonEmptyList<B> p = f.f(head); b.snoc(p.head); b.append(p.tail); tail.foreachDoEffect( new Effect1<A>() { public void f(final A a) { final NonEmptyList<B> p = f.f(a); b.snoc(p.head); b.append(p.tail); } }); final List<B> bb = b.toList(); return nel(bb.head(), bb.tail()); }
/** * Returns a potential non-empty list from the given list. A non-value is returned if the given * list is empty. * * @param as The list to construct a potential non-empty list with. * @return A potential non-empty list from the given list. */ public static <A> Option<NonEmptyList<A>> fromList(final List<A> as) { return as.isEmpty() ? Option.<NonEmptyList<A>>none() : some(nel(as.head(), as.tail())); }
/** * Zips this non empty list with the given non empty list using the given function to produce a * new list. If this list and the given list have different lengths, then the longer list is * normalised so this function never fails. * * @param bs The non empty list to zip this non empty list with. * @param f The function to zip this non empty list and the given non empty list with. * @return A new non empty list with a length the same as the shortest of this list and the given * list. */ public <B, C> NonEmptyList<C> zipWith(final List<B> bs, final F2<A, B, C> f) { final List<C> list = toList().zipWith(bs, f); return nel(list.head(), list.tail()); }
/** * Sorts this non empty list using the given order over elements using a <em>merge sort</em> * algorithm. * * @param o The order over the elements of this non empty list. * @return A sorted non empty list according to the given order. */ public NonEmptyList<A> sort(final Ord<A> o) { final List<A> list = toList().sort(o); return nel(list.head(), list.tail()); }
/** * Reverse this non empty list in constant stack space. * * @return A new non empty list with the elements in reverse order. */ public NonEmptyList<A> reverse() { final List<A> list = toList().reverse(); return nel(list.head(), list.tail()); }
/** * Intersperses the given argument between each element of this non empty list. * * @param a The separator to intersperse in this non empty list. * @return A non empty list with the given separator interspersed. */ public NonEmptyList<A> intersperse(final A a) { final List<A> list = toList().intersperse(a); return nel(list.head(), list.tail()); }