カウンタ付きの Consumer

Stream ラムダ式の実行中のカウンタ - Oboe吹きプログラマの黙示録 の続き、、、
Throwable を捕捉できる Consumer 以下を継承するようにして、
yipuran-core/ThrowableConsumer.java at master · yipuran/yipuran-core · GitHub
3要素の Consumer 、トリプル Consumer を以下のように用意すれば、
カウンタ付きの Consumer もまとめることができる。

triple Consumer

import java.io.Serializable;
import java.util.Objects;
/**
 * triple Consumer
 */
@FunctionalInterface
public interface TriConsumer<T, U, V> extends Serializable{
   void accept(T t, U u, V v);

   default TriConsumer<T, U, V> andThen(TriConsumer<? super T, ? super U, ? super V> after){
      Objects.requireNonNull(after);
      return (t, u, v)->{
         accept(t, u, v);
         after.accept(t, u, v);
      };
   }
}

カウンタ付きの Consumer

import java.util.Objects;
import java.util.concurrent.atomic.AtomicLong;
import java.util.function.BiConsumer;
import java.util.function.Consumer;
import org.yipuran.function.ThrowableConsumer;
/**
 * カウンタ付き Consumer.
 */
public interface CountConsumer<T> extends ThrowableConsumer<T>{

   default CountConsumer<T> andThen(CountConsumer<? super T> after){
      Objects.requireNonNull(after);
      return t->{
         accept(t);
         after.accept(t);
      };
   }

   public static <T> Consumer<T> of(BiConsumer<T, Long> biconsumer){
      AtomicLong c = new AtomicLong(1);
      return t->{
         try{
            biconsumer.accept(t, c.getAndIncrement());
         }catch(Exception ex){
            throw new RuntimeException(ex);
         }
      };
   }

   public static <T> Consumer<T> of(BiConsumer<T, Long> biconsumer, TriConsumer<T, Long, Throwable> onCatch){
      AtomicLong c = new AtomicLong(1);
      return t->{
         try{
            biconsumer.accept(t, c.getAndIncrement());
         }catch(Throwable ex){
            onCatch.accept(t, c.get(), ex);
         }
      };
   }
}

使用方法、、、

CountConsumer.of((t, c)->{
   // t : 要素
   // c : long カウンタ
   // TODO

});
CountConsumer.of((t, c)->{
   // t : 要素
   // c : long カウンタ
   // TODO

}, (t, c, x)->{
   // t : 要素
   // c : long カウンタ
   // x : 例外 Throwable
   // TODO

});

BiConsumer, BiPredicate, BiFunction 、、、各々カウンタ付きを
そのうち、、yipuran-core に入れようかと思う。。