RxMemoization { public static <R> Func0<R> memoize(final Func0<R> func0) { return new Func0<R>() { private R value; @Override public R call() { if (null == value) { synchronized (this) { if (null == value) { value = func0.call(); } } } return value; } }; } private  RxMemoization(); static Func0<R> memoize(final Func0<R> func0); static Func1<A, R> memoize(final Func1<A, R> func1); static Func2<A, B, R> memoize(final Func2<A, B, R> func2); static Func3<A, B, C, R> memoize(final Func3<A, B, C, R> func3); static Func4<A, B, C, D, R> memoize(final Func4<A, B, C, D, R> func4); static Func5<A, B, C, D, E, R> memoize(
            final Func5<A, B, C, D, E, R> func5); static Func6<A, B, C, D, E, F, R> memoize(
            final Func6<A, B, C, D, E, F, R> func6); static Func7<A, B, C, D, E, F, G, R> memoize(
            final Func7<A, B, C, D, E, F, G, R> func7); static Func8<A, B, C, D, E, F, G, H, R> memoize(
            final Func8<A, B, C, D, E, F, G, H, R> func8); static Func9<A, B, C, D, E, F, G, H, I, R> memoize(
            final Func9<A, B, C, D, E, F, G, H, I, R> func9); static FuncN<R> memoize(final FuncN<R> funcN);  }
@Test public void testMemoize() { final AtomicInteger count = new AtomicInteger(0); final Func0<MyObject> memoized = RxMemoization.memoize(new Func0<MyObject>() { @Override public MyObject call() { count.incrementAndGet(); return INSTANCE; } }); final int threadCount = 10000; final int maxDelay = 100; Iterable<Observable<Long>> observableList = Observable.range(0, threadCount) .map(new Func1<Integer, Observable<Long>>() { @Override public Observable<Long> call(final Integer integer) { return Observable .timer((long)(Math.random() * maxDelay), TimeUnit.MILLISECONDS) .doOnNext(new Action1<Long>() { @Override public void call(Long aLong) { memoized.call(); memoized.call(); memoized.call(); memoized.call(); memoized.call(); } }).doOnCompleted(new Action0() { @Override public void call() { System.out.println("Test-" + integer); } }).subscribeOn(Schedulers.newThread()); } }).toList().toBlocking().first(); Observable.merge(observableList).toBlocking().forEach(new Action1<Long>() { @Override public void call(Long o) { } }); Assert.assertEquals(1, count.get()); }
@Test public void testMemoizeN() { final AtomicInteger count = new AtomicInteger(0); FuncN<MyObject> memoized = RxMemoization.memoize(new FuncN<MyObject>() { @Override public MyObject call(Object... args) { count.incrementAndGet(); return INSTANCES.get(args.length); } }); Assert.assertEquals(INSTANCES.get(0), memoized.call()); Assert.assertEquals(INSTANCES.get(0), memoized.call()); Assert.assertEquals(INSTANCES.get(0), memoized.call()); Assert.assertEquals(INSTANCES.get(1), memoized.call(0)); Assert.assertEquals(INSTANCES.get(1), memoized.call(0)); Assert.assertEquals(INSTANCES.get(1), memoized.call(0)); Assert.assertEquals(INSTANCES.get(5), memoized.call(0, 0, 0, 0, 0)); Assert.assertEquals(INSTANCES.get(5), memoized.call(0, 0, 0, 0, 0)); Assert.assertEquals(INSTANCES.get(5), memoized.call(0, 0, 0, 0, 0)); Assert.assertEquals(INSTANCES.get(12), memoized.call(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); Assert.assertEquals(INSTANCES.get(12), memoized.call(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); Assert.assertEquals(INSTANCES.get(12), memoized.call(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); Assert.assertEquals(INSTANCES.get(0), memoized.call()); Assert.assertEquals(INSTANCES.get(0), memoized.call()); Assert.assertEquals(INSTANCES.get(0), memoized.call()); Assert.assertEquals(4, count.get()); }
@Test public void testMemoize1() { final AtomicInteger count = new AtomicInteger(0); Func1<Integer, MyObject> memoized = RxMemoization.memoize(new Func1<Integer, MyObject>() { @Override public MyObject call(Integer integer) { count.incrementAndGet(); return INSTANCES.get(integer); } }); Assert.assertEquals(INSTANCES.get(0), memoized.call(0)); Assert.assertEquals(INSTANCES.get(0), memoized.call(0)); Assert.assertEquals(INSTANCES.get(0), memoized.call(0)); Assert.assertEquals(INSTANCES.get(1), memoized.call(1)); Assert.assertEquals(INSTANCES.get(1), memoized.call(1)); Assert.assertEquals(INSTANCES.get(1), memoized.call(1)); Assert.assertEquals(INSTANCES.get(30), memoized.call(30)); Assert.assertEquals(INSTANCES.get(30), memoized.call(30)); Assert.assertEquals(INSTANCES.get(30), memoized.call(30)); Assert.assertEquals(INSTANCES.get(0), memoized.call(0)); Assert.assertEquals(INSTANCES.get(0), memoized.call(0)); Assert.assertEquals(INSTANCES.get(0), memoized.call(0)); Assert.assertEquals(3, count.get()); }
@Test public void testMemoize2() { final AtomicInteger count = new AtomicInteger(0); Func2<Integer, Integer, MyObject> memoized = RxMemoization .memoize(new Func2<Integer, Integer, MyObject>() { @Override public MyObject call(Integer integer, Integer integer2) { count.incrementAndGet(); return INSTANCES.get(integer + integer2); } }); Assert.assertEquals(INSTANCES.get(0), memoized.call(0, 0)); Assert.assertEquals(INSTANCES.get(0), memoized.call(0, 0)); Assert.assertEquals(INSTANCES.get(0), memoized.call(0, 0)); Assert.assertEquals(INSTANCES.get(1), memoized.call(0, 1)); Assert.assertEquals(INSTANCES.get(1), memoized.call(0, 1)); Assert.assertEquals(INSTANCES.get(1), memoized.call(0, 1)); Assert.assertEquals(INSTANCES.get(30), memoized.call(15, 15)); Assert.assertEquals(INSTANCES.get(30), memoized.call(15, 15)); Assert.assertEquals(INSTANCES.get(30), memoized.call(15, 15)); Assert.assertEquals(INSTANCES.get(0), memoized.call(0, 0)); Assert.assertEquals(INSTANCES.get(0), memoized.call(0, 0)); Assert.assertEquals(INSTANCES.get(0), memoized.call(0, 0)); Assert.assertEquals(3, count.get()); }
@Test public void testMemoize3() { final AtomicInteger count = new AtomicInteger(0); Func3<Integer, Integer, Integer, MyObject> memoized = RxMemoization .memoize(new Func3<Integer, Integer, Integer, MyObject>() { @Override public MyObject call(Integer integer, Integer integer2, Integer integer3) { count.incrementAndGet(); return INSTANCES.get(integer + integer2 + integer3); } }); Assert.assertEquals(INSTANCES.get(0), memoized.call(0, 0, 0)); Assert.assertEquals(INSTANCES.get(0), memoized.call(0, 0, 0)); Assert.assertEquals(INSTANCES.get(0), memoized.call(0, 0, 0)); Assert.assertEquals(INSTANCES.get(1), memoized.call(0, 0, 1)); Assert.assertEquals(INSTANCES.get(1), memoized.call(0, 0, 1)); Assert.assertEquals(INSTANCES.get(1), memoized.call(0, 0, 1)); Assert.assertEquals(INSTANCES.get(30), memoized.call(0, 15, 15)); Assert.assertEquals(INSTANCES.get(30), memoized.call(0, 15, 15)); Assert.assertEquals(INSTANCES.get(30), memoized.call(0, 15, 15)); Assert.assertEquals(INSTANCES.get(0), memoized.call(0, 0, 0)); Assert.assertEquals(INSTANCES.get(0), memoized.call(0, 0, 0)); Assert.assertEquals(INSTANCES.get(0), memoized.call(0, 0, 0)); Assert.assertEquals(3, count.get()); }
@Test public void testMemoize4() { final AtomicInteger count = new AtomicInteger(0); Func4<Integer, Integer, Integer, Integer, MyObject> memoized = RxMemoization .memoize(new Func4<Integer, Integer, Integer, Integer, MyObject>() { @Override public MyObject call(Integer integer, Integer integer2, Integer integer3, Integer integer4) { count.incrementAndGet(); return INSTANCES.get(integer + integer2 + integer3 + integer4); } }); Assert.assertEquals(INSTANCES.get(0), memoized.call(0, 0, 0, 0)); Assert.assertEquals(INSTANCES.get(0), memoized.call(0, 0, 0, 0)); Assert.assertEquals(INSTANCES.get(0), memoized.call(0, 0, 0, 0)); Assert.assertEquals(INSTANCES.get(1), memoized.call(0, 0, 0, 1)); Assert.assertEquals(INSTANCES.get(1), memoized.call(0, 0, 0, 1)); Assert.assertEquals(INSTANCES.get(1), memoized.call(0, 0, 0, 1)); Assert.assertEquals(INSTANCES.get(30), memoized.call(0, 15, 0, 15)); Assert.assertEquals(INSTANCES.get(30), memoized.call(0, 15, 0, 15)); Assert.assertEquals(INSTANCES.get(30), memoized.call(0, 15, 0, 15)); Assert.assertEquals(INSTANCES.get(0), memoized.call(0, 0, 0, 0)); Assert.assertEquals(INSTANCES.get(0), memoized.call(0, 0, 0, 0)); Assert.assertEquals(INSTANCES.get(0), memoized.call(0, 0, 0, 0)); Assert.assertEquals(3, count.get()); }
@Test public void testMemoize5() { final AtomicInteger count = new AtomicInteger(0); Func5<Integer, Integer, Integer, Integer, Integer, MyObject> memoized = RxMemoization .memoize(new Func5<Integer, Integer, Integer, Integer, Integer, MyObject>() { @Override public MyObject call(Integer integer, Integer integer2, Integer integer3, Integer integer4, Integer integer5) { count.incrementAndGet(); return INSTANCES.get(integer + integer2 + integer3 + integer4 + integer5); } }); Assert.assertEquals(INSTANCES.get(0), memoized.call(0, 0, 0, 0, 0)); Assert.assertEquals(INSTANCES.get(0), memoized.call(0, 0, 0, 0, 0)); Assert.assertEquals(INSTANCES.get(0), memoized.call(0, 0, 0, 0, 0)); Assert.assertEquals(INSTANCES.get(1), memoized.call(0, 0, 0, 0, 1)); Assert.assertEquals(INSTANCES.get(1), memoized.call(0, 0, 0, 0, 1)); Assert.assertEquals(INSTANCES.get(1), memoized.call(0, 0, 0, 0, 1)); Assert.assertEquals(INSTANCES.get(30), memoized.call(0, 15, 0, 0, 15)); Assert.assertEquals(INSTANCES.get(30), memoized.call(0, 15, 0, 0, 15)); Assert.assertEquals(INSTANCES.get(30), memoized.call(0, 15, 0, 0, 15)); Assert.assertEquals(INSTANCES.get(0), memoized.call(0, 0, 0, 0, 0)); Assert.assertEquals(INSTANCES.get(0), memoized.call(0, 0, 0, 0, 0)); Assert.assertEquals(INSTANCES.get(0), memoized.call(0, 0, 0, 0, 0)); Assert.assertEquals(3, count.get()); }
@Test public void testMemoize6() { final AtomicInteger count = new AtomicInteger(0); Func6<Integer, Integer, Integer, Integer, Integer, Integer, MyObject> memoized = RxMemoization .memoize(new Func6<Integer, Integer, Integer, Integer, Integer, Integer, MyObject>() { @Override public MyObject call(Integer integer, Integer integer2, Integer integer3, Integer integer4, Integer integer5, Integer integer6) { count.incrementAndGet(); return INSTANCES.get(integer + integer2 + integer3 + integer4 + integer5 + integer6); } }); Assert.assertEquals(INSTANCES.get(0), memoized.call(0, 0, 0, 0, 0, 0)); Assert.assertEquals(INSTANCES.get(0), memoized.call(0, 0, 0, 0, 0, 0)); Assert.assertEquals(INSTANCES.get(0), memoized.call(0, 0, 0, 0, 0, 0)); Assert.assertEquals(INSTANCES.get(1), memoized.call(0, 0, 0, 0, 0, 1)); Assert.assertEquals(INSTANCES.get(1), memoized.call(0, 0, 0, 0, 0, 1)); Assert.assertEquals(INSTANCES.get(1), memoized.call(0, 0, 0, 0, 0, 1)); Assert.assertEquals(INSTANCES.get(30), memoized.call(0, 15, 0, 0, 0, 15)); Assert.assertEquals(INSTANCES.get(30), memoized.call(0, 15, 0, 0, 0, 15)); Assert.assertEquals(INSTANCES.get(30), memoized.call(0, 15, 0, 0, 0, 15)); Assert.assertEquals(INSTANCES.get(0), memoized.call(0, 0, 0, 0, 0, 0)); Assert.assertEquals(INSTANCES.get(0), memoized.call(0, 0, 0, 0, 0, 0)); Assert.assertEquals(INSTANCES.get(0), memoized.call(0, 0, 0, 0, 0, 0)); Assert.assertEquals(3, count.get()); }
@Test public void testMemoize7() { final AtomicInteger count = new AtomicInteger(0); Func7<Integer, Integer, Integer, Integer, Integer, Integer, Integer, MyObject> memoized = RxMemoization .memoize(new Func7<Integer, Integer, Integer, Integer, Integer, Integer, Integer, MyObject>() { @Override public MyObject call(Integer integer, Integer integer2, Integer integer3, Integer integer4, Integer integer5, Integer integer6, Integer integer7) { count.incrementAndGet(); return INSTANCES.get(integer + integer2 + integer3 + integer4 + integer5 + integer6 + integer7); } }); Assert.assertEquals(INSTANCES.get(0), memoized.call(0, 0, 0, 0, 0, 0, 0)); Assert.assertEquals(INSTANCES.get(0), memoized.call(0, 0, 0, 0, 0, 0, 0)); Assert.assertEquals(INSTANCES.get(0), memoized.call(0, 0, 0, 0, 0, 0, 0)); Assert.assertEquals(INSTANCES.get(1), memoized.call(0, 0, 0, 0, 0, 0, 1)); Assert.assertEquals(INSTANCES.get(1), memoized.call(0, 0, 0, 0, 0, 0, 1)); Assert.assertEquals(INSTANCES.get(1), memoized.call(0, 0, 0, 0, 0, 0, 1)); Assert.assertEquals(INSTANCES.get(30), memoized.call(0, 0, 15, 0, 0, 0, 15)); Assert.assertEquals(INSTANCES.get(30), memoized.call(0, 0, 15, 0, 0, 0, 15)); Assert.assertEquals(INSTANCES.get(30), memoized.call(0, 0, 15, 0, 0, 0, 15)); Assert.assertEquals(INSTANCES.get(0), memoized.call(0, 0, 0, 0, 0, 0, 0)); Assert.assertEquals(INSTANCES.get(0), memoized.call(0, 0, 0, 0, 0, 0, 0)); Assert.assertEquals(INSTANCES.get(0), memoized.call(0, 0, 0, 0, 0, 0, 0)); Assert.assertEquals(3, count.get()); }
@Test public void testMemoize8() { final AtomicInteger count = new AtomicInteger(0); Func8<Integer, Integer, Integer, Integer, Integer, Integer, Integer, Integer, MyObject> memoized = RxMemoization .memoize(new Func8<Integer, Integer, Integer, Integer, Integer, Integer, Integer, Integer, MyObject>() { @Override public MyObject call(Integer integer, Integer integer2, Integer integer3, Integer integer4, Integer integer5, Integer integer6, Integer integer7, Integer integer8) { count.incrementAndGet(); return INSTANCES.get(integer + integer2 + integer3 + integer4 + integer5 + integer6 + integer7 + integer8); } }); Assert.assertEquals(INSTANCES.get(0), memoized.call(0, 0, 0, 0, 0, 0, 0, 0)); Assert.assertEquals(INSTANCES.get(0), memoized.call(0, 0, 0, 0, 0, 0, 0, 0)); Assert.assertEquals(INSTANCES.get(0), memoized.call(0, 0, 0, 0, 0, 0, 0, 0)); Assert.assertEquals(INSTANCES.get(1), memoized.call(0, 0, 0, 0, 0, 0, 0, 1)); Assert.assertEquals(INSTANCES.get(1), memoized.call(0, 0, 0, 0, 0, 0, 0, 1)); Assert.assertEquals(INSTANCES.get(1), memoized.call(0, 0, 0, 0, 0, 0, 0, 1)); Assert.assertEquals(INSTANCES.get(45), memoized.call(15, 0, 15, 0, 0, 0, 0, 15)); Assert.assertEquals(INSTANCES.get(45), memoized.call(0, 15, 15, 0, 0, 0, 0, 15)); Assert.assertEquals(INSTANCES.get(30), memoized.call(0, 0, 15, 0, 0, 0, 0, 15)); Assert.assertEquals(INSTANCES.get(0), memoized.call(0, 0, 0, 0, 0, 0, 0, 0)); Assert.assertEquals(INSTANCES.get(0), memoized.call(0, 0, 0, 0, 0, 0, 0, 0)); Assert.assertEquals(INSTANCES.get(0), memoized.call(0, 0, 0, 0, 0, 0, 0, 0)); Assert.assertEquals(5, count.get()); }
@Test public void testMemoize9() { final AtomicInteger count = new AtomicInteger(0); Func9<Integer, Integer, Integer, Integer, Integer, Integer, Integer, Integer, Integer, MyObject> memoized = RxMemoization .memoize(new Func9<Integer, Integer, Integer, Integer, Integer, Integer, Integer, Integer, Integer, MyObject>() { @Override public MyObject call(Integer integer, Integer integer2, Integer integer3, Integer integer4, Integer integer5, Integer integer6, Integer integer7, Integer integer8, Integer integer9) { count.incrementAndGet(); return INSTANCES.get(integer + integer2 + integer3 + integer4 + integer5 + integer6 + integer7 + integer8 + integer9); } }); Assert.assertEquals(INSTANCES.get(0), memoized.call(0, 0, 0, 0, 0, 0, 0, 0, 0)); Assert.assertEquals(INSTANCES.get(0), memoized.call(0, 0, 0, 0, 0, 0, 0, 0, 0)); Assert.assertEquals(INSTANCES.get(0), memoized.call(0, 0, 0, 0, 0, 0, 0, 0, 0)); Assert.assertEquals(INSTANCES.get(1), memoized.call(0, 0, 0, 0, 0, 0, 0, 0, 1)); Assert.assertEquals(INSTANCES.get(1), memoized.call(0, 0, 0, 0, 0, 0, 0, 0, 1)); Assert.assertEquals(INSTANCES.get(1), memoized.call(0, 0, 0, 0, 0, 0, 0, 0, 1)); Assert.assertEquals(INSTANCES.get(30), memoized.call(15, 0, 0, 0, 0, 0, 0, 0, 15)); Assert.assertEquals(INSTANCES.get(30), memoized.call(0, 15, 0, 0, 0, 0, 0, 0, 15)); Assert.assertEquals(INSTANCES.get(30), memoized.call(0, 0, 15, 0, 0, 0, 0, 0, 15)); Assert.assertEquals(INSTANCES.get(0), memoized.call(0, 0, 0, 0, 0, 0, 0, 0, 0)); Assert.assertEquals(INSTANCES.get(0), memoized.call(0, 0, 0, 0, 0, 0, 0, 0, 0)); Assert.assertEquals(INSTANCES.get(0), memoized.call(0, 0, 0, 0, 0, 0, 0, 0, 0)); Assert.assertEquals(5, count.get()); }