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

javaslang.collection.Stack Maven / Gradle / Ivy

There is a newer version: 2.0.0-RC4
Show newest version
/*     / \____  _    _  ____   ______  / \ ____  __    _ _____
 *    /  /    \/ \  / \/    \ /  /\__\/  //    \/  \  / /  _  \   Javaslang
 *  _/  /  /\  \  \/  /  /\  \\__\\  \  //  /\  \ /\\/  \__/  /   Copyright 2014-now Daniel Dietrich
 * /___/\_/  \_/\____/\_/  \_/\__\/__/___\_/  \_//  \__/_____/    Licensed under the Apache License, Version 2.0
 */
package javaslang.collection;

import javaslang.Tuple2;
import javaslang.control.Match;
import javaslang.control.Option;

import java.util.ArrayList;
import java.util.Comparator;
import java.util.Objects;
import java.util.function.*;
import java.util.stream.Collector;

/**
 * An immutable {@code Stack} stores elements allowing a last-in-first-out (LIFO) retrieval.
 * 

* Stack API: * *

    *
  • {@link #peek()}
  • *
  • {@link #peekOption()}
  • *
  • {@link #pop()}
  • *
  • {@link #popOption()}
  • *
  • {@link #pop2()}
  • *
  • {@link #pop2Option()}
  • *
  • {@link #push(Object)}
  • *
  • {@link #push(Object[])}
  • *
  • {@link #pushAll(Iterable)}
  • *
* * See Okasaki, Chris: Purely Functional Data Structures (p. 7 ff.). Cambridge, 2003. * * @param component type * @author Daniel Dietrich * @since 2.0.0 */ public interface Stack extends LinearSeq { long serialVersionUID = 1L; /** * Returns a {@link java.util.stream.Collector} which may be used in conjunction with * {@link java.util.stream.Stream#collect(java.util.stream.Collector)} to obtain a {@link javaslang.collection.Stack} * . * * @param Component type of the Stack. * @return A javaslang.collection.Stack Collector. */ static Collector, Stack> collector() { final Supplier> supplier = ArrayList::new; final BiConsumer, T> accumulator = ArrayList::add; final BinaryOperator> combiner = (left, right) -> { left.addAll(right); return left; }; final Function, Stack> finisher = Stack::ofAll; return Collector.of(supplier, accumulator, combiner, finisher); } /** * Returns the empty Stack. * * @param Component type * @return The empty Stack. */ static Stack empty() { return List.empty(); } /** * Returns a singleton {@code Stack}, i.e. a {@code Stack} of one element. * * @param element An element. * @param The component type * @return A new Stack instance containing the given element */ static Stack of(T element) { return List.of(element); } /** * Creates a Stack of the given elements. * * @param Component type of the Stack. * @param elements Zero or more elements. * @return A stack containing the given elements in the same order. * @throws NullPointerException if {@code elements} is null */ @SuppressWarnings("varargs") @SafeVarargs static Stack of(T... elements) { Objects.requireNonNull(elements, "elements is null"); return List.of(elements); } /** * Creates a Stack of the given elements. * * @param Component type of the Stack. * @param elements An Iterable of elements. * @return A stack containing the given elements in the same order. * @throws NullPointerException if {@code elements} is null */ @SuppressWarnings("unchecked") static Stack ofAll(Iterable elements) { Objects.requireNonNull(elements, "elements is null"); if (elements instanceof Stack) { return (Stack) elements; } else { return List.ofAll(elements); } } /** * Creates a Stack based on the elements of a boolean array. * * @param array a boolean array * @return A new Stack of Boolean values */ static Stack ofAll(boolean[] array) { Objects.requireNonNull(array, "array is null"); return List.ofAll(array); } /** * Creates a Stack based on the elements of a byte array. * * @param array a byte array * @return A new Stack of Byte values */ static Stack ofAll(byte[] array) { Objects.requireNonNull(array, "array is null"); return List.ofAll(array); } /** * Creates a Stack based on the elements of a char array. * * @param array a char array * @return A new Stack of Character values */ static Stack ofAll(char[] array) { Objects.requireNonNull(array, "array is null"); return List.ofAll(array); } /** * Creates a Stack based on the elements of a double array. * * @param array a double array * @return A new Stack of Double values */ static Stack ofAll(double[] array) { Objects.requireNonNull(array, "array is null"); return List.ofAll(array); } /** * Creates a Stack based on the elements of a float array. * * @param array a float array * @return A new Stack of Float values */ static Stack ofAll(float[] array) { Objects.requireNonNull(array, "array is null"); return List.ofAll(array); } /** * Creates a Stack based on the elements of an int array. * * @param array an int array * @return A new Stack of Integer values */ static Stack ofAll(int[] array) { Objects.requireNonNull(array, "array is null"); return List.ofAll(array); } /** * Creates a Stack based on the elements of a long array. * * @param array a long array * @return A new Stack of Long values */ static Stack ofAll(long[] array) { Objects.requireNonNull(array, "array is null"); return List.ofAll(array); } /** * Creates a Stack based on the elements of a short array. * * @param array a short array * @return A new Stack of Short values */ static Stack ofAll(short[] array) { Objects.requireNonNull(array, "array is null"); return List.ofAll(array); } /** * Returns a Stack containing {@code n} values of a given Function {@code f} * over a range of integer values from 0 to {@code n - 1}. * * @param Component type of the Stack * @param n The number of elements in the Stack * @param f The Function computing element values * @return A Stack consisting of elements {@code f(0),f(1), ..., f(n - 1)} * @throws NullPointerException if {@code f} is null */ static Stack tabulate(int n, Function f) { Objects.requireNonNull(f, "f is null"); return Collections.tabulate(n, f, Stack.empty(), Stack::of); } /** * Returns a Stack containing {@code n} values supplied by a given Supplier {@code s}. * * @param Component type of the Stack * @param n The number of elements in the Stack * @param s The Supplier computing element values * @return A Stack of size {@code n}, where each element contains the result supplied by {@code s}. * @throws NullPointerException if {@code s} is null */ static Stack fill(int n, Supplier s) { Objects.requireNonNull(s, "s is null"); return Collections.fill(n, s, Stack.empty(), Stack::of); } static Stack range(char from, char toExclusive) { return List.range(from, toExclusive); } static Stack rangeBy(char from, char toExclusive, int step) { return List.rangeBy(from, toExclusive, step); } static Stack rangeBy(double from, double toExclusive, double step) { return List.rangeBy(from, toExclusive, step); } /** * Creates a Stack of int numbers starting from {@code from}, extending to {@code toExclusive - 1}. *

* Examples: *

     * 
     * Stack.range(0, 0)  // = Stack()
     * Stack.range(2, 0)  // = Stack()
     * Stack.range(-2, 2) // = Stack(-2, -1, 0, 1)
     * 
     * 
* * @param from the first number * @param toExclusive the last number + 1 * @return a range of int values as specified or the empty range if {@code from >= toExclusive} */ static Stack range(int from, int toExclusive) { return List.range(from, toExclusive); } /** * Creates a Stack of int numbers starting from {@code from}, extending to {@code toExclusive - 1}, * with {@code step}. *

* Examples: *

     * 
     * Stack.rangeBy(1, 3, 1)  // = Stack(1, 2)
     * Stack.rangeBy(1, 4, 2)  // = Stack(1, 3)
     * Stack.rangeBy(4, 1, -2) // = Stack(4, 2)
     * Stack.rangeBy(4, 1, 2)  // = Stack()
     * 
     * 
* * @param from the first number * @param toExclusive the last number + 1 * @param step the step * @return a range of long values as specified or the empty range if
* {@code from >= toInclusive} and {@code step > 0} or
* {@code from <= toInclusive} and {@code step < 0} * @throws IllegalArgumentException if {@code step} is zero */ static Stack rangeBy(int from, int toExclusive, int step) { return List.rangeBy(from, toExclusive, step); } /** * Creates a Stack of long numbers starting from {@code from}, extending to {@code toExclusive - 1}. *

* Examples: *

     * 
     * Stack.range(0L, 0L)  // = Stack()
     * Stack.range(2L, 0L)  // = Stack()
     * Stack.range(-2L, 2L) // = Stack(-2L, -1L, 0L, 1L)
     * 
     * 
* * @param from the first number * @param toExclusive the last number + 1 * @return a range of long values as specified or the empty range if {@code from >= toExclusive} */ static Stack range(long from, long toExclusive) { return List.range(from, toExclusive); } /** * Creates a Stack of long numbers starting from {@code from}, extending to {@code toExclusive - 1}, * with {@code step}. *

* Examples: *

     * 
     * Stack.rangeBy(1L, 3L, 1L)  // = Stack(1L, 2L)
     * Stack.rangeBy(1L, 4L, 2L)  // = Stack(1L, 3L)
     * Stack.rangeBy(4L, 1L, -2L) // = Stack(4L, 2L)
     * Stack.rangeBy(4L, 1L, 2L)  // = Stack()
     * 
     * 
* * @param from the first number * @param toExclusive the last number + 1 * @param step the step * @return a range of long values as specified or the empty range if
* {@code from >= toInclusive} and {@code step > 0} or
* {@code from <= toInclusive} and {@code step < 0} * @throws IllegalArgumentException if {@code step} is zero */ static Stack rangeBy(long from, long toExclusive, long step) { return List.rangeBy(from, toExclusive, step); } static Stack rangeClosed(char from, char toInclusive) { return List.rangeClosed(from, toInclusive); } static Stack rangeClosedBy(char from, char toInclusive, int step) { return List.rangeClosedBy(from, toInclusive, step); } static Stack rangeClosedBy(double from, double toInclusive, double step) { return List.rangeClosedBy(from, toInclusive, step); } /** * Creates a Stack of int numbers starting from {@code from}, extending to {@code toInclusive}. *

* Examples: *

     * 
     * Stack.rangeClosed(0, 0)  // = Stack(0)
     * Stack.rangeClosed(2, 0)  // = Stack()
     * Stack.rangeClosed(-2, 2) // = Stack(-2, -1, 0, 1, 2)
     * 
     * 
* * @param from the first number * @param toInclusive the last number * @return a range of int values as specified or the empty range if {@code from > toInclusive} */ static Stack rangeClosed(int from, int toInclusive) { return List.rangeClosed(from, toInclusive); } /** * Creates a Stack of int numbers starting from {@code from}, extending to {@code toInclusive}, * with {@code step}. *

* Examples: *

     * 
     * Stack.rangeClosedBy(1, 3, 1)  // = Stack(1, 2, 3)
     * Stack.rangeClosedBy(1, 4, 2)  // = Stack(1, 3)
     * Stack.rangeClosedBy(4, 1, -2) // = Stack(4, 2)
     * Stack.rangeClosedBy(4, 1, 2)  // = Stack()
     * 
     * 
* * @param from the first number * @param toInclusive the last number * @param step the step * @return a range of int values as specified or the empty range if
* {@code from > toInclusive} and {@code step > 0} or
* {@code from < toInclusive} and {@code step < 0} * @throws IllegalArgumentException if {@code step} is zero */ static Stack rangeClosedBy(int from, int toInclusive, int step) { return List.rangeClosedBy(from, toInclusive, step); } /** * Creates a Stack of long numbers starting from {@code from}, extending to {@code toInclusive}. *

* Examples: *

     * 
     * Stack.rangeClosed(0L, 0L)  // = Stack(0L)
     * Stack.rangeClosed(2L, 0L)  // = Stack()
     * Stack.rangeClosed(-2L, 2L) // = Stack(-2L, -1L, 0L, 1L, 2L)
     * 
     * 
* * @param from the first number * @param toInclusive the last number * @return a range of long values as specified or the empty range if {@code from > toInclusive} */ static Stack rangeClosed(long from, long toInclusive) { return List.rangeClosed(from, toInclusive); } /** * Creates a Stack of long numbers starting from {@code from}, extending to {@code toInclusive}, * with {@code step}. *

* Examples: *

     * 
     * Stack.rangeClosedBy(1L, 3L, 1L)  // = Stack(1L, 2L, 3L)
     * Stack.rangeClosedBy(1L, 4L, 2L)  // = Stack(1L, 3L)
     * Stack.rangeClosedBy(4L, 1L, -2L) // = Stack(4L, 2L)
     * Stack.rangeClosedBy(4L, 1L, 2L)  // = Stack()
     * 
     * 
* * @param from the first number * @param toInclusive the last number * @param step the step * @return a range of int values as specified or the empty range if
* {@code from > toInclusive} and {@code step > 0} or
* {@code from < toInclusive} and {@code step < 0} * @throws IllegalArgumentException if {@code step} is zero */ static Stack rangeClosedBy(long from, long toInclusive, long step) { return List.rangeClosedBy(from, toInclusive, step); } /** * Returns the head element without modifying the Stack. * * @return the first element * @throws java.util.NoSuchElementException if this Stack is empty */ T peek(); /** * Returns the head element without modifying the Stack. * * @return {@code None} if this Stack is empty, otherwise a {@code Some} containing the head element */ Option peekOption(); /** * Removes the head element from this Stack. * * @return the elements of this Stack without the head element * @throws java.util.NoSuchElementException if this Stack is empty */ Stack pop(); /** * Removes the head element from this Stack. * * @return {@code None} if this Stack is empty, otherwise a {@code Some} containing the elements of this Stack without the head element */ Option> popOption(); /** * Removes the head element from this Stack. * * @return a tuple containing the head element and the remaining elements of this Stack * @throws java.util.NoSuchElementException if this Stack is empty */ Tuple2> pop2(); /** * Removes the head element from this Stack. * * @return {@code None} if this Stack is empty, otherwise {@code Some} {@code Tuple} containing the head element and the remaining elements of this Stack */ Option>> pop2Option(); /** * Pushes a new element on top of this Stack. * * @param element The new element * @return a new {@code Stack} instance, containing the new element on top of this Stack */ Stack push(T element); /** * Pushes the given elements on top of this Stack. A Stack has LIFO order, i.e. the last of the given elements is * the first which will be retrieved. * * @param elements Elements, may be empty * @return a new {@code Stack} instance, containing the new elements on top of this Stack * @throws NullPointerException if elements is null */ @SuppressWarnings("unchecked") Stack push(T... elements); /** * Pushes the given elements on top of this Stack. A Stack has LIFO order, i.e. the last of the given elements is * the first which will be retrieved. * * @param elements An Iterable of elements, may be empty * @return a new {@code Stack} instance, containing the new elements on top of this Stack * @throws NullPointerException if elements is null */ Stack pushAll(Iterable elements); // -- Adjusted return types of Seq methods @Override Stack append(T element); @Override Stack appendAll(Iterable elements); @Override Stack clear(); @Override Stack> combinations(); @Override Stack> combinations(int k); @Override Stack> crossProduct(); @Override Stack> crossProduct(int power); @Override Stack> crossProduct(Iterable that); @Override Stack distinct(); @Override Stack distinctBy(Comparator comparator); @Override Stack distinctBy(Function keyExtractor); @Override Stack drop(long n); @Override Stack dropRight(long n); @Override Stack dropUntil(Predicate predicate); @Override Stack dropWhile(Predicate predicate); @Override Stack filter(Predicate predicate); @Override Stack flatMap(Function> mapper); @Override Map> groupBy(Function classifier); @Override Iterator> grouped(long size); @Override Stack init(); @Override Option> initOption(); @Override Stack insert(int index, T element); @Override Stack insertAll(int index, Iterable elements); @Override Stack intersperse(T element); @Override Stack map(Function mapper); @Override Match.MatchValue.Of> match(); @Override Stack padTo(int length, T element); @Override Stack patch(int from, Iterable that, int replaced); @Override Tuple2, ? extends Stack> partition(Predicate predicate); @Override Stack peek(Consumer action); @Override Stack> permutations(); @Override Stack prepend(T element); @Override Stack prependAll(Iterable elements); @Override Stack remove(T element); @Override Stack removeFirst(Predicate predicate); @Override Stack removeLast(Predicate predicate); @Override Stack removeAt(int index); @Override Stack removeAll(T element); @Override Stack removeAll(Iterable elements); @Override Stack replace(T currentElement, T newElement); @Override Stack replaceAll(T currentElement, T newElement); @Override Stack retainAll(Iterable elements); @Override Stack reverse(); @Override Stack scan(T zero, BiFunction operation); @Override Stack scanLeft(U zero, BiFunction operation); @Override Stack scanRight(U zero, BiFunction operation); @Override Stack slice(long beginIndex, long endIndex); @Override Iterator> sliding(long size); @Override Iterator> sliding(long size, long step); @Override Stack sort(); @Override Stack sort(Comparator comparator); @Override > Stack sortBy(Function mapper); @Override Stack sortBy(Comparator comparator, Function mapper); @Override Tuple2, ? extends Stack> span(Predicate predicate); @Override Tuple2, ? extends Stack> splitAt(long n); @Override Tuple2, ? extends Stack> splitAt(Predicate predicate); @Override Tuple2, ? extends Stack> splitAtInclusive(Predicate predicate); @Override Stack subSequence(int beginIndex); @Override Stack subSequence(int beginIndex, int endIndex); @Override Stack tail(); @Override Option> tailOption(); @Override Stack take(long n); @Override Stack takeRight(long n); @Override Stack takeUntil(Predicate predicate); @Override Stack takeWhile(Predicate predicate); @Override Stack unit(Iterable iterable); @Override Tuple2, ? extends Stack> unzip( Function> unzipper); @Override Stack update(int index, T element); @Override Stack> zip(Iterable that); @Override Stack> zipAll(Iterable that, T thisElem, U thatElem); @Override Stack> zipWithIndex(); }