/** * Create a Mutable variable, which can be mutated inside a Closure * * e.g. * <pre>{@code * MutableInt num = MutableInt.of(20); * * Stream.of(1,2,3,4).map(i->i*10).peek(i-> num.mutate(n->n+i)).foreach(System.out::println); * * System.out.println(num.getValue()); * //prints 120 * } </pre> * * @param var Initial value of Mutable * @return New Mutable instance */ public static MutableInt of(final int var) { return new MutableInt( var); }
/** * A BiFunction capable of retrying on failure using an exponential backoff strategy * * @param times Number of times to retry * @param backoffStartTime Wait time before first retry * @return BiFunction with a retry strategy */ public FluentBiFunction<T1, T2, R> retry(final int times, final int backoffStartTime) { return FluentFunctions.of((t1, t2) -> { int count = times; final MutableInt sleep = MutableInt.of(backoffStartTime); Throwable exception = null; while (count-- > 0) { try { return fn.apply(t1, t2); } catch (final Throwable e) { exception = e; } ExceptionSoftener.softenRunnable(() -> Thread.sleep(sleep.get())); sleep.mutate(s -> s * 2); } throw ExceptionSoftener.throwSoftenedException(exception); }); }
@Override public Integer get() { return getAsInt(); }
@Test public void testClosedVarHashCodeFalse() { assertThat(new MutableInt(10).hashCode(),not(equalTo(new MutableInt(20).hashCode()))); } int value = 0;
@Test public void testSet() { assertThat(new MutableInt().set(1000).getAsInt(),is(1000)); }
@Test public void testClosedVar() { assertThat(new MutableInt(10).getAsInt(),equalTo(10)); } @Test
@Override public void accept(final int value) { set(value); } }
@Test public void externalMapOutput(){ value = 200; MutableInt ext = MutableInt.fromExternal(()->value,v->this.value=v) .mapOutput(s->s*2); assertThat(ext.get(),equalTo(400)); } }
@Test public void externalMapInput(){ value = 0; MutableInt ext = MutableInt.fromExternal(()->value,v->this.value=v) .mapInput(s->s+10); ext.set(50); assertThat(value,equalTo(60)); }
@Test public void externalGet(){ value = 100; MutableInt ext = MutableInt.fromExternal(()->value,v->this.value=v); assertThat(ext.get(),equalTo(100)); } @Test
@Test public void externalSet(){ value = 0; MutableInt ext = MutableInt.fromExternal(()->value,v->this.value=v); ext.set(10); assertThat(value,equalTo(10)); }
@Override public R get() { return fn.apply(host.get()); }
@Test public void externalMapOutputToObj(){ value = 200; Mutable<Integer> ext = MutableInt.fromExternal(()->value,v->this.value=v) .mapOutputToObj(s->s*2); assertThat(ext.get(),equalTo(400)); } @Test
@Test public void externalMapInputObj(){ value = 0; Mutable<Integer> ext = MutableInt.fromExternal(()->value,v->this.value=v) .mapInputToObj(s->s+10); ext.set(50); assertThat(value,equalTo(60)); }
@Test public void inClosure2(){ MutableInt myInt = new MutableInt(0); BiFunction<Integer,Integer,MutableInt> fn = (i,j)-> myInt.set(i*j); fn.apply(10,20); assertThat(myInt.getAsInt(), is(200)); }
@Override public Mutable<T1> set(final T1 value) { host.set(fn.apply(value)); return this; }
@Test public void testClosedVarHashCode() { assertThat(new MutableInt(10).hashCode(),equalTo(new MutableInt(10).hashCode())); } @Test
@Override public R get() { return fn.apply(host.get()); }
/** * A Function capable of retrying on failure using an exponential backoff strategy * * @param times Number of times to retry * @param backoffStartTime Wait time before first retry * @return Function with a retry strategy */ public FluentFunction<T, R> retry(final int times, final int backoffStartTime) { return FluentFunctions.of(t -> { int count = times; final MutableInt sleep = MutableInt.of(backoffStartTime); Throwable exception = null; while (count-- > 0) { try { return fn.apply(t); } catch (final Throwable e) { exception = e; } ExceptionSoftener.softenRunnable(() -> Thread.sleep(sleep.get())); sleep.mutate(s -> s * 2); } throw ExceptionSoftener.throwSoftenedException(exception); }); }