MethodHandles.IteratedLoop(MethodHandle, MethodHandle, MethodHandle) Method
Definition
Important
Some information relates to prerelease product that may be substantially modified before it’s released. Microsoft makes no warranties, express or implied, with respect to the information provided here.
Constructs a loop that ranges over the values produced by an Iterator<T>
.
[Android.Runtime.Register("iteratedLoop", "(Ljava/lang/invoke/MethodHandle;Ljava/lang/invoke/MethodHandle;Ljava/lang/invoke/MethodHandle;)Ljava/lang/invoke/MethodHandle;", "", ApiSince=33)]
public static Java.Lang.Invoke.MethodHandle? IteratedLoop (Java.Lang.Invoke.MethodHandle? iterator, Java.Lang.Invoke.MethodHandle? init, Java.Lang.Invoke.MethodHandle? body);
[<Android.Runtime.Register("iteratedLoop", "(Ljava/lang/invoke/MethodHandle;Ljava/lang/invoke/MethodHandle;Ljava/lang/invoke/MethodHandle;)Ljava/lang/invoke/MethodHandle;", "", ApiSince=33)>]
static member IteratedLoop : Java.Lang.Invoke.MethodHandle * Java.Lang.Invoke.MethodHandle * Java.Lang.Invoke.MethodHandle -> Java.Lang.Invoke.MethodHandle
Parameters
- iterator
- MethodHandle
an optional handle to return the iterator to start the loop.
If non-null
, the handle must return java.util.Iterator
or a subtype.
See above for other constraints.
- init
- MethodHandle
optional initializer, providing the initial value of the loop variable.
May be null
, implying a default initial value. See above for other constraints.
- body
- MethodHandle
body of the loop, which may not be null
.
It controls the loop parameters and result type in the standard case (see above for details).
It must accept its own return type (if non-void) plus a T
parameter (for the iterated values),
and may accept any number of additional types.
See above for other constraints.
Returns
a method handle embodying the iteration loop functionality.
- Attributes
Remarks
Constructs a loop that ranges over the values produced by an Iterator<T>
. This is a convenience wrapper for the #loop(MethodHandle[][]) generic loop combinator.
The iterator itself will be determined by the evaluation of the iterator
handle. Each value it produces will be stored in a loop iteration variable of type T
.
If the body
handle returns a non-void
type V
, a leading loop iteration variable of that type is also present. This variable is initialized using the optional init
handle, or to the #empty default value of type V
if that handle is null
.
In each iteration, the iteration variables are passed to an invocation of the body
handle. A non-void
value returned from the body (of type V
) updates the leading iteration variable. The result of the loop handle execution will be the final V
value of that variable (or void
if there is no V
variable).
The following rules hold for the argument handles:<ul> <li>The body
handle must not be null
; its type must be of the form (V T A...)V
, where V
is non-void
, or else (T A...)void
. (In the void
case, we assign the type void
to the name V
, and we will write (V T A...)V
with the understanding that a void
type V
is quietly dropped from the parameter list, leaving (T A...)V
.) <li>The parameter list (V T A...)
of the body contributes to a list of types called the <em>internal parameter list</em>. It will constrain the parameter lists of the other loop parts. <li>As a special case, if the body contributes only V
and T
types, with no additional A
types, then the internal parameter list is extended by the argument types A...
of the iterator
handle; if it is null
the single type Iterable
is added and constitutes the A...
list. <li>If the iteration variable types (V T)
are dropped from the internal parameter list, the resulting shorter list (A...)
is called the <em>external parameter list</em>. <li>The body return type V
, if non-void
, determines the type of an additional state variable of the loop. The body must both accept a leading parameter and return a value of this type V
. <li>If init
is non-null
, it must have return type V
. Its parameter list (of some form <c>(A*)</c>) must be effectively identical to the external parameter list (A...)
. <li>If init
is null
, the loop variable will be initialized to its #empty default value. <li>If the iterator
handle is non-null
, it must have the return type java.util.Iterator
or a subtype thereof. The iterator it produces when the loop is executed will be assumed to yield values which can be converted to type T
. <li>The parameter list of an iterator
that is non-null
(of some form (A*)
) must be effectively identical to the external parameter list (A...)
. <li>If iterator
is null
it defaults to a method handle which behaves like java.lang.Iterable#iterator()
. In that case, the internal parameter list (V T A...)
must have at least one A
type, and the default iterator handle parameter is adjusted to accept the leading A
type, as if by the MethodHandle#asType asType
conversion method. The leading A
type must be Iterable
or a subtype thereof. This conversion step, done at loop construction time, must not throw a WrongMethodTypeException
. </ul>
The type T
may be either a primitive or reference. Since type Iterator<T>
is erased in the method handle representation to the raw type Iterator
, the iteratedLoop
combinator adjusts the leading argument type for body
to Object
as if by the MethodHandle#asType asType
conversion method. Therefore, if an iterator of the wrong type appears as the loop is executed, runtime exceptions may occur as the result of dynamic conversions performed by MethodHandle#asType(MethodType)
.
The resulting loop handle's result type and parameter signature are determined as follows:<ul> <li>The loop handle's result type is the result type V
of the body. <li>The loop handle's parameter types are the types (A...)
, from the external parameter list. </ul>
Here is pseudocode for the resulting loop handle. In the code, V
/v
represent the type / value of the loop variable as well as the result type of the loop; T
/t
, that of the elements of the structure the loop iterates over, and A...
/a...
represent arguments passed to the loop. <blockquote>
{@code
Iterator<T> iterator(A...); // defaults to Iterable::iterator
V init(A...);
V body(V,T,A...);
V iteratedLoop(A... a...) {
Iterator<T> it = iterator(a...);
V v = init(a...);
while (it.hasNext()) {
T t = it.next();
v = body(v, t, a...);
}
return v;
}
}
</blockquote>
Added in 9.
Portions of this page are modifications based on work created and shared by the Android Open Source Project and used according to terms described in the Creative Commons 2.5 Attribution License.