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

org.abego.commons.seq.Seq Maven / Gradle / Ivy

There is a newer version: 1.1.0
Show newest version
/*
 * MIT License
 *
 * Copyright (c) 2020 Udo Borkowski, ([email protected])
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in all
 * copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 */

package org.abego.commons.seq;

import org.eclipse.jdt.annotation.Nullable;

import java.util.Comparator;
import java.util.List;
import java.util.NoSuchElementException;
import java.util.Objects;
import java.util.function.Function;
import java.util.function.Predicate;
import java.util.stream.Stream;

/**
 * A sequence of items of type T.
 * 

* A Seq is a way to abstract from implementation details of "classic" * data types representing sequences, such as {@link List}s or arrays. *

* In contrast to an {@link Iterable} or a {@link Stream} a Seq also provides * the number of items in the sequence ({@link #size()}) as well as indexed * access to the items ({@link #item(int)}). Also Seq introduces the concept of * a "single item" sequence. */ public interface Seq extends Iterable { String MORE_THAN_ONE_ELEMENT_MESSAGE = "More than one element"; //NON-NLS String NO_SUCH_ELEMENT_MESSAGE = "No such element"; //NON-NLS /** * Return the size of the sequence. */ int size(); /** * Return the index-ed item in the sequence. * *

index is zero-based.

*/ T item(int index); /** * Return the index of the first occurrence of the specified item in this * Seq, or -1 if this Seq does not contain the item. *

* {@link Objects#equals(Object, Object)} is used to check for the occurrence. */ default int indexOf(@Nullable T item) { int i = 0; for (T o : this) { if ((Objects.equals(item, o))) return i; i++; } return -1; } /** * Return {@code true} when the Seq contains the specified item, * {@code false} otherwise. *

* {@link Objects#equals(Object, Object)} is used to check for the occurrence. */ default boolean contains(@Nullable T item) { return indexOf(item) >= 0; } /** * Return the items of the sequence as a {@link Stream}. */ default Stream stream() { Stream.Builder builder = Stream.builder(); for (T o : this) { builder.add(o); } return builder.build(); } /** * Return true when the sequence is empty, * false otherwise. */ default boolean isEmpty() { return size() == 0; } /** * Return true when the sequence has one or more items, * false otherwise. *

* It is equivalent to {@code !isEmpty()}. *

*/ default boolean hasItems() { return !isEmpty(); } /** * Return true when the sequence has exactly one item, * false otherwise. */ default boolean hasSingleItem() { return size() == 1; } /** * Return the first item of the sequence. * *

Throw an {@link NoSuchElementException} when the sequence is empty.

*/ default T first() { if (isEmpty()) { throw new NoSuchElementException(); } return item(0); } /** * Returns a new Seq consisting of the items of this sequence that match * the predicate. * *

See {@link SeqUtil#filter(Seq, Predicate)} for a default implementation.

* *

This method has no default implementation to avoid cyclic dependencies.

*/ Seq filter(Predicate condition); /** * Returns a new Seq consisting of the results of applying the given * mapper function to the elements of this Seq. * *

See {@link SeqUtil#map(Seq, Function)} for a default implementation.

* *

This method has no default implementation to avoid cyclic dependencies.

*/ Seq map(Function mapper); /** * Returns a new Seq consisting of the elements of this Seq * sorted by the given sortKey. */ > Seq sortedBy(Function sortKey); /** * Return a new Seq consisting of the elements of this Seq * sorted in ascending order, according to the {@linkplain Comparable * natural ordering} of its elements. * *

All elements in the Seq must implement the {@link Comparable} * interface. Furthermore, all elements in the Seq must be * mutually comparable (that is, {@code e1.compareTo(e2)} * must not throw a {@code ClassCastException} for any elements * {@code e1} and {@code e2} in the Seq). */ Seq sorted(); /** * Return a new Seq consisting of the elements of this Seq * sorted in ascending order, according to the given comparator. * *

All elements in this list must be mutually comparable using the * specified comparator (that is, {@code c.compare(e1, e2)} must not throw * a {@code ClassCastException} for any elements {@code e1} and {@code e2} * in the list). */ Seq sorted(Comparator comparator); /** * Return the one and only item of this sequence. *

* Throw a {@link NoSuchElementException} when the sequence is empty or * contains more than one item. */ default T singleItem() { if (!hasSingleItem()) { throw new NoSuchElementException(size() > 1 ? MORE_THAN_ONE_ELEMENT_MESSAGE : NO_SUCH_ELEMENT_MESSAGE); } return first(); } /** * Return the one and only item of this sequence, or null when * the sequence is empty. *

* Throw a {@link NoSuchElementException} when the sequence contains more * than one item. */ @Nullable default T singleItemOrNull() { if (!hasSingleItem()) { if (isEmpty()) { return null; } throw new NoSuchElementException(MORE_THAN_ONE_ELEMENT_MESSAGE); } return first(); } /** * Return any item of this sequence, or null when * the sequence is empty. */ @Nullable default T anyItemOrNull() { return isEmpty() ? null : anyItem(); } /** * Return any item of this sequence. *

* Throw a {@link NoSuchElementException} when the sequence is empty. *

* It is not required to always return the first item. */ default T anyItem() { if (isEmpty()) { throw new NoSuchElementException(); } return first(); } default String joined(CharSequence separator, Function mapToString) { return String.join(separator, map(mapToString)); } default String joined(CharSequence separator) { return joined(separator, Object::toString); } default String joined() { return joined(""); } /** * Return true if the specified object is a * Seq and equal to this Seq, return false otherwise. * *

Two Seqs are equal if they contain the same elements in the same * order. Two elements e1 and e2 are the same * elements if (e1==null ? e2==null : e1.equals(e2)). * *

This definition ensures that the equals method works properly * across different implementations of the Seq interface. */ boolean equals(@Nullable Object object); /** * Return the hash code value for this Seq. * *

The hash code of a Seq is defined to be the result of the * following calculation: *

     *         int hashCode = 1;
     *         for (Object e : this) {
     *             hashCode = 31 * hashCode + (e == null ? 0 : e.hashCode());
     *         }
     * 
*

* This ensures that seq1.equals(seq2) implies that * seq1.hashCode()==seq2.hashCode() for any two Seqs, seq1 and seq2, * as required by the general contract of Object.hashCode(). */ int hashCode(); }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy