Skip to content

Commit 94fdefe

Browse files
author
tigraboris
committed
add code
1 parent b61b640 commit 94fdefe

File tree

5 files changed

+171
-5
lines changed

5 files changed

+171
-5
lines changed

trampoline/README.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,15 +24,17 @@ and to interleave the execution of functions without hard coding them together o
2424
Use the Trampoline pattern when
2525

2626
* For implementing tail recursive function. This pattern allows to switch on a stackless operation.
27-
* For to interleaving the execution of two or more functions on the same thread.
27+
* For interleaving the execution of two or more functions on the same thread.
2828

2929
## Known uses(real world examples)
3030
* Trampoline refers to using reflection to avoid using inner classes, for example in event listeners.
3131
The time overhead of a reflection call is traded for the space overhead of an inner class.
3232
Trampolines in Java usually involve the creation of a GenericListener to pass events to an outer class.
3333

34+
3435
## Credits
3536

3637
* [Trampolining: a practical guide for awesome Java Developers](https://medium.com/@johnmcclean/trampolining-a-practical-guide-for-awesome-java-developers-4b657d9c3076)
3738
* [Trampoline in java ](http://mindprod.com/jgloss/trampoline.html)
39+
* [cyclops-react](https://github.com/aol/cyclops-react)
3840

trampoline/src/main/java/com/iluwatar/trampoline/App.java

Lines changed: 0 additions & 4 deletions
This file was deleted.
Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
package com.iluwatar.trampoline;
2+
3+
import java.util.stream.Stream;
4+
5+
/**When get is called on the returned Trampoline, internally it will iterate calling ‘jump’
6+
on the returned Trampoline as long as the concrete instance returned is More,
7+
stopping once the returned instance is Done. Essential we convert looping via recursion into iteration,
8+
the key enabling mechanism is the fact that Trampoline.more is a lazy operation.
9+
Trampoline in cyclops-react extends java.util.Supplier. Calling Trampoline.more we are basically creating
10+
a Supplier that defers the actual recursive call, and having defered the call we can move it outside of the recursive loop.
11+
This means we can define algorithms recursively in Java but execute them iteratively.*/
12+
13+
public interface Trampoline<T> {
14+
T get();
15+
16+
17+
/**
18+
* @return next stage
19+
*/
20+
default Trampoline<T> jump() {
21+
return this;
22+
}
23+
24+
25+
default T result() {
26+
return get();
27+
}
28+
29+
/**
30+
* @return true if complete
31+
*
32+
*/
33+
default boolean complete() {
34+
return true;
35+
}
36+
37+
/**
38+
* Created a completed Trampoline
39+
*
40+
* @param result Completed result
41+
* @return Completed Trampoline
42+
*/
43+
static <T> Trampoline<T> done(final T result) {
44+
return () -> result;
45+
}
46+
47+
48+
/**
49+
* Create a Trampoline that has more work to do
50+
*
51+
* @param trampoline Next stage in Trampoline
52+
* @return Trampoline with more work
53+
*/
54+
static <T> Trampoline<T> more(final Trampoline<Trampoline<T>> trampoline) {
55+
return new Trampoline<T>() {
56+
@Override
57+
public boolean complete() {
58+
return false;
59+
}
60+
61+
@Override
62+
public Trampoline<T> jump() {
63+
return trampoline.result();
64+
}
65+
66+
@Override
67+
public T get() {
68+
return trampoline(this);
69+
}
70+
71+
T trampoline(final Trampoline<T> trampoline) {
72+
73+
return Stream.iterate(trampoline, Trampoline::jump)
74+
.filter(Trampoline::complete)
75+
.findFirst()
76+
.get()
77+
.result();
78+
79+
}
80+
};
81+
}
82+
83+
84+
}
Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
/**
2+
* The MIT License
3+
* Copyright (c) 2014-2016 Ilkka Seppälä
4+
*
5+
* Permission is hereby granted, free of charge, to any person obtaining a copy
6+
* of this software and associated documentation files (the "Software"), to deal
7+
* in the Software without restriction, including without limitation the rights
8+
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
* copies of the Software, and to permit persons to whom the Software is
10+
* furnished to do so, subject to the following conditions:
11+
*
12+
* The above copyright notice and this permission notice shall be included in
13+
* all copies or substantial portions of the Software.
14+
*
15+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21+
* THE SOFTWARE.
22+
*/
23+
24+
package com.iluwatar.trampoline;
25+
26+
27+
import lombok.extern.slf4j.Slf4j;
28+
29+
/**
30+
* <div>
31+
* By representing a computation in one of 2 states
32+
(completed with result, or a reference to the reminder of the computation,
33+
something like the way a java.util.Supplier does)
34+
it is possible to implement algorithms recursively in Java without blowing the stack
35+
and to interleave the execution of functions without hard coding them together or even using threads.
36+
</div>
37+
<div>
38+
Trampoline has 2 state : [done], [ more]
39+
</div>
40+
When get is called on the returned Trampoline, internally it will iterate calling ‘jump’
41+
on the returned Trampoline as long as the concrete instance returned is More,
42+
stopping once the returned instance is Done. Essential we convert looping via recursion into iteration,
43+
the key enabling mechanism is the fact that Trampoline.more is a lazy operation.
44+
Trampoline in cyclops-react extends java.util.Supplier. Calling Trampoline.more we are basically creating
45+
a Supplier that defers the actual recursive call, and having defered the call we can move it outside of the recursive loop.
46+
This means we can define algorithms recursively in Java but execute them iteratively.
47+
*/
48+
49+
@Slf4j
50+
public class TrampolineApp {
51+
public static void main(String[] args) {
52+
log.info("start pattern");
53+
Integer result = loop(10, 1).result();
54+
log.info("result {}" ,result);
55+
56+
}
57+
/**
58+
* Manager for pattern.
59+
* */
60+
public static Trampoline<Integer> loop(int times,int prod){
61+
if(times==0)
62+
return Trampoline.done(prod);
63+
else
64+
return Trampoline.more(()->loop(times-1,prod*times));
65+
}
66+
67+
}
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
package com.iluwatar.trampoline;
2+
3+
import org.junit.Test;
4+
5+
import java.io.IOException;
6+
7+
import static org.junit.Assert.*;
8+
9+
public class TrampolineAppTest {
10+
11+
@Test
12+
public void test()throws IOException{
13+
int result = TrampolineApp.loop(10, 1).result();
14+
assertEquals("Be equal",3628800,result);
15+
}
16+
17+
}

0 commit comments

Comments
 (0)