github.com/searKing/golang/go@v1.2.74/container/stream/op/find/op.go (about) 1 // Copyright 2020 The searKing Author. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 package find 6 7 import ( 8 "context" 9 10 "github.com/searKing/golang/go/container/stream/op/terminal" 11 "github.com/searKing/golang/go/util/function/predicate" 12 "github.com/searKing/golang/go/util/object" 13 "github.com/searKing/golang/go/util/optional" 14 "github.com/searKing/golang/go/util/spliterator" 15 ) 16 17 /** 18 * A short-circuiting {@code TerminalOp} that searches for an element in a 19 * stream pipeline, and terminates when it finds one. Implements both 20 * find-first (find the first element in the encounter order) and find-any 21 * (find any element, may not be the first in encounter order.) 22 * 23 * @param <T> the output type of the stream pipeline 24 * @param <O> the result type of the find operation, typically an optional 25 * type 26 */ 27 type FindOp struct { 28 terminal.TODOOperation 29 mustFindFirst bool 30 sinkSupplier func() *FindSink 31 32 presentPredicate predicate.Predicater 33 } 34 35 /** 36 * Constructs a {@code Operation}. 37 * 38 * @param mustFindFirst if true, must find the first element in 39 * encounter order, otherwise can find any element 40 * @param shape stream shape of elements to search 41 * @param emptyValue result value corresponding to "found nothing" 42 * @param presentPredicate {@code Predicate} on result value 43 * corresponding to "found something" 44 * @param sinkSupplier supplier for a {@code TerminalSink} implementing 45 * the matching functionality 46 */ 47 func NewFindOp(mustFindFirst bool, presentPredicate predicate.Predicater, sinkSupplier func() *FindSink) *FindOp { 48 findOp := &FindOp{ 49 mustFindFirst: mustFindFirst, 50 presentPredicate: presentPredicate, 51 sinkSupplier: sinkSupplier, 52 } 53 findOp.SetDerived(findOp) 54 return findOp 55 } 56 57 func NewFindOp2(mustFindFirst bool, presentPredicate predicate.Predicater) *FindOp { 58 object.RequireNonNil(presentPredicate) 59 return NewFindOp(mustFindFirst, presentPredicate, func() *FindSink { 60 return NewFindSink() 61 }) 62 } 63 64 func (op FindOp) MakeSink() *FindSink { 65 object.RequireNonNull(op.sinkSupplier) 66 return op.sinkSupplier() 67 } 68 69 func (op FindOp) EvaluateParallel(ctx context.Context, spliterator spliterator.Spliterator) optional.Optional { 70 return terminal.WrapAndCopyInto(ctx, op.MakeSink(), spliterator).Get() 71 } 72 73 func (op FindOp) EvaluateSequential(ctx context.Context, spliterator spliterator.Spliterator) optional.Optional { 74 return (&FindTask{}).WithSpliterator(op, spliterator).Invoke(ctx).Get() 75 }