Рубрики
Без рубрики

Правильный API для списка Java

Пересмотр API коллекций Java. Помечено java, lang, обсуждение.

Фреймворк Java Collection довольно старый. Впервые появился в Java 1.2, и с тех пор он изменился не так сильно. Он отражает ОО-концепции в том виде, в каком они были поняты к концу 20-го века.

С тех пор многое изменилось, и выросло новое понимание того, что на самом деле нужно из Списка, набора, карты и т. Д. API-интерфейсы. Гораздо чаще мы используем неизменяемые коллекции, и многие из нас понимают, что нам нужны совершенно другие API, отличные от того, который предоставляется стандартными классами JDK.

Эта статья посвящена спискам, поэтому я предлагаю обсудить, как должен выглядеть идеальный API для реализации неизменяемых списков Java.

Исходя из своего опыта, я попытался подготовить версию API, которая должна быть более удобной в использовании:

public interface List {
    /**
     * Return first element from list.
     * 
     * @return First element wrapped into {@link Option} if element is present or {@link Option#empty()} otherwise
     */
    Option first();

    /**
     * Return first {@code N} elements from the list. If there are less elements than requested, then avalable
     * elements returned.
     * @param n
     *        Number of elements to return.
     *        
     * @return New list with at most requested number of elements
     */
    List first(final int n);

    /**
     * Return last element from list.
     *
     * @return Last element wrapped into {@link Option} if element is present or {@link Option#empty()} otherwise
     */
    Option last();

    /**
     * Return list which contains elements from current list followed by elements from list provided as parameter.
     * 
     * @param other
     *        List to append
     *        
     * @return List with elements from current list followed by elements from {@code other} list
     */
    List append(final List other);

    /**
     * Return list which contains elements from list provided as parameter followed by elements of current list.
     * 
     * @param other
     *        List to append to
     *        
     * @return List with elements from {@code other} list followed by elements from current list
     */
    List prepend(final List other);

    /**
     * Return list consisting of elements obtained from elements of current list with applied 
     * transformation function.
     * 
     * @param mapper
     *        Transformation function
     *        
     * @return New list with transformed elements
     */
     List map(final FN1 mapper);

    /**
     * Return list consisting of elements obtained from elements of current list with applied 
     * transformation function. Unlike {@link #map(FN1)} this method passes index of element
     * along with element to transformation function.
     *
     * @param mapper
     *        Transformation function
     *        
     * @return New list with transformed elements
     */
     List mapN(final FN2 mapper);

    /**
     * Applies specified consumer to elements of current list.
     * 
     * @param consumer
     *        Consumer for elements
     *        
     * @return Current list  
     */
    List apply(final Consumer consumer);

    /**
     * Applies specified consumer to elements of current list. 
     * Unlike {@link #apply(Consumer)} element index is passed along with element to consumer.
     * 
     * @param consumer
     *        Consumer for elements
     *        
     * @return Current list
     */
    List applyN(final BiConsumer consumer);

    /**
     * Create {@link Stream} from list elements.
     * 
     * @return Created stream
     */
    Stream stream();

    /**
     * Return list size.
     * 
     * @return number of elements in list
     */
    int size();

    /**
     * Create new list which will hold the same elements but sorted according to 
     * provided comparator.
     * 
     * @param comparator
     *        Element comparator
     *        
     * @return Sorted list
     */
    List sort(final Comparator comparator);

    /**
     * Create new list which will hold only elements which satisfy provided predicate.
     * 
     * @param predicate
     *        Predicate to apply to elements
     * 
     * @return List of elements for which predicate returned {@code true}
     */
    List filter(final Predicate predicate);

    /**
     * Split current list into two using provided predicate. Result is a pair of lists. Left element of pair
     * contains list with elements evaluated to {@code false} by predicate. Right element of pair contains
     * list with elements evaluated to {@code true} by predicate.
     * 
     * @param predicate
     *        Predicate to apply to elements
     * 
     * @return Pair of lists with results 
     */
    Pair, List> splitBy(final Predicate predicate);
}

Помимо перечисленных выше API, должны быть фабричные методы и реализация Collector , которые должны обеспечивать удобное взаимодействие с API Stream , но эта часть более или менее ясна.

Я был бы рад получить отзывы о предложенном выше API списка и получить любые комментарии/идеи/предложения/соображения по этому поводу.

Оригинал: “https://dev.to/siy/proper-api-for-java-list-1n1f”