Skip to content

Commit f7d1641

Browse files
map 惰性求值
1 parent 154bf42 commit f7d1641

5 files changed

Lines changed: 87 additions & 57 deletions

File tree

src/main/java/functional/Accumulate.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
*
77
* accumulate 累加操作
88
*/
9-
public interface Accumulate <T>{
9+
public interface Accumulate <T,U>{
1010

11-
T apply(T t1, T t2);
11+
T apply(T t1, U t2);
1212
}

src/main/java/stream/Stream.java

Lines changed: 38 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package stream;
22

3+
import functional.Accumulate;
34
import functional.ForEach;
45
import functional.Map;
56
import functional.NextItem;
@@ -19,37 +20,8 @@ public class Stream <T> implements StreamInterface<T>{
1920

2021
private boolean isEnd;
2122

22-
/**
23-
* 是否被求值过
24-
* */
25-
private boolean evaled;
26-
2723
private NextItem<T> eval;
2824

29-
public T getHead() {
30-
return head;
31-
}
32-
33-
public void setHead(T head) {
34-
this.head = head;
35-
}
36-
37-
public Stream<T> getTail() {
38-
return tail;
39-
}
40-
41-
public void setTail(Stream<T> tail) {
42-
this.tail = tail;
43-
}
44-
45-
public NextItem<T> getEval() {
46-
return eval;
47-
}
48-
49-
public void setEval(NextItem<T> eval) {
50-
this.eval = eval;
51-
}
52-
5325
//====================================构造函数===============================
5426

5527
public Stream() {
@@ -72,19 +44,29 @@ public Stream(boolean isEnd) {
7244

7345
@Override
7446
public <R> Stream<R> map(Map<R,T> mapper){
75-
return map(mapper,this);
47+
Stream<R> lazy = new Stream<>(()-> map(mapper,this));
48+
return lazy;
7649
}
7750

7851
@Override
7952
public Stream<T> filter(Predicate<T> predicate){
80-
8153
return new Stream<>();
8254
}
8355

56+
@Override
57+
public Stream<T> limit(int n) {
58+
return limit(n,this);
59+
}
60+
8461
@Override
8562
public void forEach(ForEach<T> forEach){
8663
}
8764

65+
@Override
66+
public <R> R reduce(R initVal,Accumulate<R,T> accumulator) {
67+
return reduce(initVal,accumulator,this.eval.apply());
68+
}
69+
8870
//=====================================私有方法=====================================
8971

9072
private <R> Stream<R> map(Map<R,T> mapper,Stream<T> stream){
@@ -93,24 +75,38 @@ private <R> Stream<R> map(Map<R,T> mapper,Stream<T> stream){
9375
}
9476

9577
R head = mapper.apply(stream.head);
96-
Stream tail = new Stream<>(
97-
()-> map(mapper,stream.force()
98-
));
78+
Stream<R> tail = new Stream<>(
79+
()-> map(mapper,stream.force())
80+
);
81+
return new Stream<>(head, tail);
82+
}
9983

84+
private Stream<T> limit(int n, Stream<T> stream){
85+
if(n <= 0){
86+
return StreamInterface.makeEmptyStream();
87+
}
10088

101-
Stream newStream = new Stream(
102-
head,
103-
tail
104-
);
105-
return newStream;
89+
T head = stream.head;
90+
91+
Stream<T> tail = limit(n-1,stream.force());
92+
93+
return new Stream<>(head,tail);
10694
}
10795

108-
private void delay(NextItem<T> nextItem){
96+
private <R> R reduce(R initVal,Accumulate<R,T> accumulator,Stream<T> stream){
97+
if(isEmptyStream(stream)){
98+
return initVal;
99+
}
109100

101+
T head = stream.head;
102+
R tail = reduce(initVal,accumulator,stream.force());
103+
104+
return accumulator.apply(tail,head);
110105
}
111106

112-
private Stream force(){
113-
return this.tail.eval.apply();
107+
private Stream<T> force(){
108+
Stream<T> eval = this.tail.eval.apply();
109+
return eval;
114110
}
115111

116112
private static boolean isEmptyStream(Stream stream){

src/main/java/stream/StreamInterface.java

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package stream;
22

3+
import functional.Accumulate;
34
import functional.ForEach;
45
import functional.Map;
56
import functional.Predicate;
@@ -10,12 +11,37 @@
1011
*/
1112
public interface StreamInterface<T> {
1213

14+
/**
15+
* 映射
16+
* */
1317
<R> Stream<R> map(Map<R,T> mapper);
1418

19+
/**
20+
* 过滤
21+
* */
1522
Stream<T> filter(Predicate<T> predicate);
1623

24+
/**
25+
* 截断
26+
* */
27+
Stream<T> limit(int n);
28+
29+
/**
30+
* 遍历
31+
* 终止操作
32+
* */
1733
void forEach(ForEach<T> forEach);
1834

35+
/**
36+
* 浓缩
37+
* 终止操作
38+
* */
39+
<R> R reduce(R initVal,Accumulate<R,T> accumulator);
40+
41+
/**
42+
* 返回空的 stream
43+
* @return 空stream
44+
* */
1945
static <T> Stream<T> makeEmptyStream(){
2046
return new Stream<>(true);
2147
}

src/test/java/TestJDKStream.java

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,7 @@
11
import java.util.ArrayList;
2+
import java.util.Arrays;
3+
import java.util.Optional;
4+
import java.util.stream.Collectors;
25
import java.util.stream.Stream;
36

47
/**
@@ -8,7 +11,14 @@
811
public class TestJDKStream {
912

1013
public static void main(String[] args){
11-
Stream<Integer> stream = new ArrayList<Integer>().stream();
12-
stream.map(item->item-1).filter(item->item==0);
14+
Stream<Integer> stream = Stream.of(1,2,3,4,5);
15+
// stream = stream.map(TestJDKStream::square);
16+
// Stream<Integer> zero = square.limit(2);
17+
Optional<Integer> aa = stream.reduce((a,b)-> a+b);
18+
System.out.println(aa);
19+
}
20+
21+
private static Integer square(int num){
22+
return num * num;
1323
}
1424
}

src/test/java/TestStream.java

Lines changed: 9 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -10,17 +10,15 @@ public class TestStream {
1010
public static void main(String[] args){
1111
Stream<Integer> stream = StreamGenerator.getIntegerStream(10);
1212

13-
Stream<Integer> fiveStream = stream.map(item-> item * 5);
13+
Stream<Integer> squareStream = stream.map(TestStream::square);
1414

15-
Stream stream1 = fiveStream.getTail().getEval().apply();
16-
fiveStream.setTail(stream1);
17-
Stream stream2 = stream1.getTail().getEval().apply();
18-
stream1.setTail(stream2);
19-
Stream stream3= stream2.getTail().getEval().apply();
20-
stream2.setTail(stream3);
21-
Stream stream4 = stream3.getTail().getEval().apply();
22-
stream3.setTail(stream4);
23-
Stream stream5 = stream4.getTail().getEval().apply();
24-
stream4.setTail(stream5);
15+
// Stream<Integer> three = stream.limit(3);
16+
17+
Integer sum = squareStream.reduce(0,(result,item)-> result + item);
18+
System.out.println(sum);
19+
}
20+
21+
private static Integer square(int num){
22+
return num * 3;
2523
}
2624
}

0 commit comments

Comments
 (0)