001// Copyright 2010 The Apache Software Foundation 002// 003// Licensed under the Apache License, Version 2.0 (the "License"); 004// you may not use this file except in compliance with the License. 005// You may obtain a copy of the License at 006// 007// http://www.apache.org/licenses/LICENSE-2.0 008// 009// Unless required by applicable law or agreed to in writing, software 010// distributed under the License is distributed on an "AS IS" BASIS, 011// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 012// See the License for the specific language governing permissions and 013// limitations under the License. 014 015package org.apache.tapestry5.func; 016 017import java.util.List; 018 019/** 020 * A flow is a a functional interface for working with an ordered collection of elements. 021 * A given Flow contains only elements of a particular type. Standard operations allow for 022 * filtering the flow, or appending elements to the Flow. Since flows are immutable, all operations 023 * on flows return new immutable flows. Flows are thread safe (to the extent that the {@link Mapper} , {@link Predicate} 024 * , {@link Worker} and {@link Reducer} objects applied to the flow are). 025 * Flows are <em>lazy</em>: filtering, mapping, and concatenating flows will do so with no, or a 026 * minimum, of evaluation. However, converting a Flow into a {@link List} (or other collection) will 027 * force a realization of the entire flow. 028 * <p> 029 * In some cases, a flow may be an infinite, lazily evaluated sequence. Operations that iterate over all elements (such 030 * as {@link #count()} or {@link #reduce(Reducer, Object)}) may become infinite loops. 031 * <p> 032 * Using flows allows for a very fluid interface. 033 * <p> 034 * Flows are initially created using {@link F#flow(java.util.Collection)}, {@link F#flow(Object...)} or 035 * {@link F#flow(Iterable)}. 036 * 037 * @since 5.2.0 038 * @see F#lazy(LazyFunction) 039 */ 040public interface Flow<T> extends FlowOperations<T, Flow<T>> 041{ 042 /** Maps a Flow into a new Flow with different type values. Mapping is a lazy operation. */ 043 <X> Flow<X> map(Mapper<T, X> mapper); 044 045 /** 046 * Combines two Flows using a two-parameter Mapper. Each element of 047 * this Flow, and the corresponding element of the other flow are passed through the Mapper 048 * to provide the elements of the output Flow. The length of the result Flow is 049 * the smaller of the lengths of the two input Flows. Mapping is a lazy operation. 050 */ 051 <X, Y> Flow<Y> map(Mapper2<T, X, Y> mapper, Flow<? extends X> flow); 052 053 /** 054 * Given a {@link Mapper} that maps a T to a Flow<X>, this method will lazily concatenate 055 * all the output flows into a single Flow<X>. 056 */ 057 <X> Flow<X> mapcat(Mapper<T, Flow<X>> mapper); 058 059 /** 060 * Converts the Flow into an array of values (due to type erasure, you have to remind the Flow 061 * about the type). 062 */ 063 T[] toArray(Class<T> type); 064 065 /** 066 * Returns a new Flow with the other Flow's elements appended to this Flow's. This is a lazy 067 * operation. 068 */ 069 Flow<T> concat(Flow<? extends T> other); 070 071 /** 072 * Appends any number of type compatible values to the end of this Flow. This is a lazy 073 * operation. 074 */ 075 <V extends T> Flow<T> append(V... values); 076 077 /** 078 * Sorts this Flow, forming a new Flow. This is a non-lazy operation; it will fully realize the 079 * values of the Flow. 080 * 081 * @throws ClassCastException 082 * if type <T> does not extend {@link Comparable} 083 */ 084 Flow<T> sort(); 085 086 /** 087 * Zips this Flow together with another flow to form a Flow of {@link Tuple}s. The resulting 088 * flow is the length of the shorter of the two input flows. Zipping flows together is a lazy 089 * operation. 090 * <p> 091 * The elements of this flow become the {@linkplain Tuple#first} value in each Tuple, the elements of the other flow 092 * become the {@linkplain Tuple#second} value in each Tuple. 093 * 094 * @param <X> 095 * type of element stored in the other flow 096 * @param otherFlow 097 * contains elements to match with elements in this flow 098 * @return flow of tuples combining values from this flow with values form the other flow 099 * @since 5.3 100 */ 101 <X> ZippedFlow<T, X> zipWith(Flow<X> otherFlow); 102 103 /** 104 * "Stripes" together a group of flows. The output flow contains the first value from this flow, then the first 105 * value from each of the other flows, in turn, then the second value from this flow, etc. The resulting flow ends 106 * when this or any of the other flows runs out of values. 107 * 108 * @return combined flow 109 */ 110 Flow<T> interleave(Flow<T>... otherFlows); 111}