Sdílet prostřednictvím


MethodHandles.IteratedLoop(MethodHandle, MethodHandle, MethodHandle) Method

Definition

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.

Java documentation for java.lang.invoke.MethodHandles.iteratedLoop(java.lang.invoke.MethodHandle, java.lang.invoke.MethodHandle, java.lang.invoke.MethodHandle).

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.

Applies to