6
6
import com .bestvike .linq .exception .ExceptionArgument ;
7
7
import com .bestvike .linq .exception .ThrowHelper ;
8
8
import com .bestvike .tuple .Tuple2 ;
9
+ import com .bestvike .tuple .Tuple3 ;
9
10
10
11
/**
11
12
* Created by 许崇雷 on 2018-05-09.
@@ -14,42 +15,105 @@ public final class Zip {
14
15
private Zip () {
15
16
}
16
17
18
+ public static <TFirst , TSecond , TResult > IEnumerable <TResult > zip (IEnumerable <TFirst > first , IEnumerable <TSecond > second , Func2 <TFirst , TSecond , TResult > resultSelector ) {
19
+ if (first == null )
20
+ ThrowHelper .throwArgumentNullException (ExceptionArgument .first );
21
+ if (second == null )
22
+ ThrowHelper .throwArgumentNullException (ExceptionArgument .second );
23
+ if (resultSelector == null )
24
+ ThrowHelper .throwArgumentNullException (ExceptionArgument .resultSelector );
25
+
26
+ return new ZipIterator <>(first , second , resultSelector );
27
+ }
28
+
17
29
public static <TFirst , TSecond > IEnumerable <Tuple2 <TFirst , TSecond >> zip (IEnumerable <TFirst > first , IEnumerable <TSecond > second ) {
18
30
if (first == null )
19
31
ThrowHelper .throwArgumentNullException (ExceptionArgument .first );
20
32
if (second == null )
21
33
ThrowHelper .throwArgumentNullException (ExceptionArgument .second );
22
34
23
- return new ZipIterator <>(first , second );
35
+ return new ZipIterator2 <>(first , second );
24
36
}
25
37
26
- public static <TFirst , TSecond , TResult > IEnumerable <TResult > zip (IEnumerable <TFirst > first , IEnumerable <TSecond > second , Func2 < TFirst , TSecond , TResult > resultSelector ) {
38
+ public static <TFirst , TSecond , TThird > IEnumerable <Tuple3 < TFirst , TSecond , TThird >> zip (IEnumerable <TFirst > first , IEnumerable <TSecond > second , IEnumerable < TThird > third ) {
27
39
if (first == null )
28
40
ThrowHelper .throwArgumentNullException (ExceptionArgument .first );
29
41
if (second == null )
30
42
ThrowHelper .throwArgumentNullException (ExceptionArgument .second );
31
- if (resultSelector == null )
32
- ThrowHelper .throwArgumentNullException (ExceptionArgument .resultSelector );
43
+ if (third == null )
44
+ ThrowHelper .throwArgumentNullException (ExceptionArgument .third );
45
+
46
+ return new ZipIterator3 <>(first , second , third );
47
+ }
48
+ }
49
+
50
+
51
+ final class ZipIterator <TFirst , TSecond , TResult > extends AbstractIterator <TResult > {
52
+ private final IEnumerable <TFirst > first ;
53
+ private final IEnumerable <TSecond > second ;
54
+ private final Func2 <TFirst , TSecond , TResult > resultSelector ;
55
+ private IEnumerator <TFirst > firstEnumerator ;
56
+ private IEnumerator <TSecond > secondEnumerator ;
57
+
58
+ ZipIterator (IEnumerable <TFirst > first , IEnumerable <TSecond > second , Func2 <TFirst , TSecond , TResult > resultSelector ) {
59
+ this .first = first ;
60
+ this .second = second ;
61
+ this .resultSelector = resultSelector ;
62
+ }
63
+
64
+ @ Override
65
+ public AbstractIterator <TResult > clone () {
66
+ return new ZipIterator <>(this .first , this .second , this .resultSelector );
67
+ }
68
+
69
+ @ Override
70
+ public boolean moveNext () {
71
+ switch (this .state ) {
72
+ case 1 :
73
+ this .firstEnumerator = this .first .enumerator ();
74
+ this .secondEnumerator = this .second .enumerator ();
75
+ this .state = 2 ;
76
+ case 2 :
77
+ if (this .firstEnumerator .moveNext () && this .secondEnumerator .moveNext ()) {
78
+ this .current = this .resultSelector .apply (this .firstEnumerator .current (), this .secondEnumerator .current ());
79
+ return true ;
80
+ }
81
+ this .close ();
82
+ return false ;
83
+ default :
84
+ return false ;
85
+ }
86
+ }
33
87
34
- return new ZipIterator2 <>(first , second , resultSelector );
88
+ @ Override
89
+ public void close () {
90
+ if (this .firstEnumerator != null ) {
91
+ this .firstEnumerator .close ();
92
+ this .firstEnumerator = null ;
93
+ }
94
+ if (this .secondEnumerator != null ) {
95
+ this .secondEnumerator .close ();
96
+ this .secondEnumerator = null ;
97
+ }
98
+ super .close ();
35
99
}
36
100
}
37
101
38
102
39
- final class ZipIterator <TFirst , TSecond > extends AbstractIterator <Tuple2 <TFirst , TSecond >> {
103
+ final class ZipIterator2 <TFirst , TSecond > extends AbstractIterator <Tuple2 <TFirst , TSecond >> {
40
104
private final IEnumerable <TFirst > first ;
41
105
private final IEnumerable <TSecond > second ;
42
106
private IEnumerator <TFirst > firstEnumerator ;
43
107
private IEnumerator <TSecond > secondEnumerator ;
44
108
45
- ZipIterator (IEnumerable <TFirst > first , IEnumerable <TSecond > second ) {
109
+ ZipIterator2 (IEnumerable <TFirst > first , IEnumerable <TSecond > second ) {
46
110
this .first = first ;
47
111
this .second = second ;
48
112
}
49
113
50
114
@ Override
51
115
public AbstractIterator <Tuple2 <TFirst , TSecond >> clone () {
52
- return new ZipIterator <>(this .first , this .second );
116
+ return new ZipIterator2 <>(this .first , this .second );
53
117
}
54
118
55
119
@ Override
@@ -86,22 +150,23 @@ public void close() {
86
150
}
87
151
88
152
89
- final class ZipIterator2 <TFirst , TSecond , TResult > extends AbstractIterator <TResult > {
153
+ final class ZipIterator3 <TFirst , TSecond , TThird > extends AbstractIterator <Tuple3 < TFirst , TSecond , TThird > > {
90
154
private final IEnumerable <TFirst > first ;
91
155
private final IEnumerable <TSecond > second ;
92
- private final Func2 < TFirst , TSecond , TResult > resultSelector ;
156
+ private final IEnumerable < TThird > third ;
93
157
private IEnumerator <TFirst > firstEnumerator ;
94
158
private IEnumerator <TSecond > secondEnumerator ;
159
+ private IEnumerator <TThird > thirdEnumerator ;
95
160
96
- ZipIterator2 (IEnumerable <TFirst > first , IEnumerable <TSecond > second , Func2 < TFirst , TSecond , TResult > resultSelector ) {
161
+ ZipIterator3 (IEnumerable <TFirst > first , IEnumerable <TSecond > second , IEnumerable < TThird > third ) {
97
162
this .first = first ;
98
163
this .second = second ;
99
- this .resultSelector = resultSelector ;
164
+ this .third = third ;
100
165
}
101
166
102
167
@ Override
103
- public AbstractIterator <TResult > clone () {
104
- return new ZipIterator2 <>(this .first , this .second , this .resultSelector );
168
+ public AbstractIterator <Tuple3 < TFirst , TSecond , TThird > > clone () {
169
+ return new ZipIterator3 <>(this .first , this .second , this .third );
105
170
}
106
171
107
172
@ Override
@@ -110,10 +175,11 @@ public boolean moveNext() {
110
175
case 1 :
111
176
this .firstEnumerator = this .first .enumerator ();
112
177
this .secondEnumerator = this .second .enumerator ();
178
+ this .thirdEnumerator = this .third .enumerator ();
113
179
this .state = 2 ;
114
180
case 2 :
115
- if (this .firstEnumerator .moveNext () && this .secondEnumerator .moveNext ()) {
116
- this .current = this .resultSelector . apply ( this .firstEnumerator .current (), this .secondEnumerator .current ());
181
+ if (this .firstEnumerator .moveNext () && this .secondEnumerator .moveNext () && this . thirdEnumerator . moveNext () ) {
182
+ this .current = new Tuple3 <>( this .firstEnumerator . current (), this .secondEnumerator .current (), this .thirdEnumerator .current ());
117
183
return true ;
118
184
}
119
185
this .close ();
@@ -133,6 +199,10 @@ public void close() {
133
199
this .secondEnumerator .close ();
134
200
this .secondEnumerator = null ;
135
201
}
202
+ if (this .thirdEnumerator != null ) {
203
+ this .thirdEnumerator .close ();
204
+ this .thirdEnumerator = null ;
205
+ }
136
206
super .close ();
137
207
}
138
208
}
0 commit comments