Skip to content

Commit a7b3a1b

Browse files
committed
Parallel Stream now works
1 parent ce82a50 commit a7b3a1b

File tree

4 files changed

+147
-54
lines changed

4 files changed

+147
-54
lines changed

.gitignore

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,4 +3,5 @@ build/
33
dist/
44
java_stream.egg-info/
55
main.py
6-
parallel_test.py
6+
parallel_test.py
7+
performance.py

stream/parallelstream.py

Lines changed: 29 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -39,9 +39,8 @@ def _iterator(iterable):
3939
return
4040

4141
@staticmethod
42-
def cloneSplit(iterable, count):
43-
it = ParallelUtils._iterator(iterable)
44-
return [it for _ in range(count)]
42+
def sameSplit(iterable, count):
43+
return [ParallelUtils._iterator(iterable) for _ in range(count)]
4544

4645
@staticmethod
4746
def split(iterable, count):
@@ -67,7 +66,7 @@ class ParallelStream(Stream):
6766
def __init__(self, iterable):
6867

6968
self.__streams = [StreamThread(Stream(it))
70-
for it in ParallelUtils.split(iterable, self.PROCESS)]
69+
for it in ParallelUtils.sameSplit(iterable, self.PROCESS)]
7170

7271
for _stream in self.__streams:
7372
_stream.start()
@@ -117,6 +116,9 @@ def forEach(self, function):
117116
for _stream in self.__streams:
118117
_stream.forEach(function)
119118

119+
for _stream in self.__streams:
120+
_stream.join()
121+
120122
return self
121123

122124
def anyMatch(self, predicate):
@@ -127,8 +129,8 @@ def anyMatch(self, predicate):
127129
for _stream in self.__streams:
128130
_stream.join()
129131

130-
results = [_stream.getResult().get()
131-
for _stream in self.__streams if _stream.getResult().isPresent()]
132+
results = [_stream.getResult()
133+
for _stream in self.__streams]
132134

133135
return Stream(results).anyMatch(lambda x: x)
134136

@@ -140,8 +142,8 @@ def allMatch(self, predicate):
140142
for _stream in self.__streams:
141143
_stream.join()
142144

143-
results = [_stream.getResult().get()
144-
for _stream in self.__streams if _stream.getResult().isPresent()]
145+
results = [_stream.getResult()
146+
for _stream in self.__streams]
145147

146148
return Stream(results).allMatch(lambda x: x)
147149

@@ -153,10 +155,10 @@ def noneMatch(self, predicate):
153155
for _stream in self.__streams:
154156
_stream.join()
155157

156-
results = [_stream.getResult().get()
157-
for _stream in self.__streams if _stream.getResult().isPresent()]
158+
results = [_stream.getResult()
159+
for _stream in self.__streams]
158160

159-
return Stream(results).noneMatch(lambda x: x)
161+
return Stream(results).allMatch(lambda x: x)
160162

161163
def findAny(self):
162164

@@ -210,18 +212,18 @@ def max(self, comparator=None):
210212

211213
return Stream(results).max(comparator)
212214

213-
def sum(self, comparator=None):
215+
def sum(self):
214216

215217
for _stream in self.__streams:
216-
_stream.sum(comparator)
218+
_stream.sum()
217219

218220
for _stream in self.__streams:
219221
_stream.join()
220222

221223
results = [_stream.getResult().get()
222224
for _stream in self.__streams if _stream.getResult().isPresent()]
223225

224-
return Stream(results).sum(comparator)
226+
return Stream(results).sum()
225227

226228
def count(self):
227229

@@ -277,8 +279,19 @@ def toSet(self):
277279
def get(self):
278280
return self.__streams
279281

282+
def terminate(self):
283+
for _stream in self.__streams:
284+
_stream.terminate()
285+
280286
def __eq__(self, other):
281-
return self.toSet() == other.toSet()
287+
return self.toSet() == set(other)
282288

283289
def __iter__(self):
284-
return iter(self.toList())
290+
291+
def _iter(iters):
292+
for it in iters:
293+
for elem in it:
294+
yield elem
295+
self.terminate()
296+
297+
return _iter(self.__streams)

stream/stream.py

Lines changed: 64 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ def of(*elements):
5454
:param *T elements: the elements of the new stream
5555
:return: the new stream
5656
'''
57-
return Stream(list(elements))
57+
return Stream(iter(list(elements)))
5858

5959
@staticmethod
6060
def ofNullable(elem):
@@ -97,6 +97,10 @@ def concat(*streams):
9797
'''
9898
return Stream(IteratorUtils.concat(*streams))
9999

100+
"""
101+
Already Implemented Method
102+
"""
103+
100104
@staticmethod
101105
def randint(lower, upper):
102106
'''
@@ -108,6 +112,55 @@ def randint(lower, upper):
108112
'''
109113
return Stream.generate(lambda: random.randint(lower, upper))
110114

115+
@staticmethod
116+
def integers():
117+
'''
118+
Returns an infinite stream of integer from 0 to infinity
119+
120+
:return: the infinite stream
121+
'''
122+
return Stream.iterate(0, lambda i: i + 1)
123+
124+
@staticmethod
125+
def odds():
126+
'''
127+
Returns an infinite stream of odds number from 0 to infinity
128+
129+
:return: the infinite stream
130+
'''
131+
return Stream.iterate(1, lambda i: i + 2)
132+
133+
@staticmethod
134+
def evens():
135+
'''
136+
Returns an infinite stream of evens number from 0 to infinity
137+
138+
:return: the infinite stream
139+
'''
140+
return Stream.iterate(0, lambda i: i + 2)
141+
142+
@staticmethod
143+
def primes():
144+
'''
145+
Returns an infinite stream of primes number from 2 to infinity
146+
147+
:return: the infinite stream
148+
'''
149+
def prime_generator():
150+
yield 2
151+
primes = [2]
152+
actual = 1
153+
while True:
154+
actual += 2
155+
for prime in primes:
156+
if actual % prime == 0:
157+
break
158+
else:
159+
primes.append(actual)
160+
yield actual
161+
162+
return Stream(prime_generator())
163+
111164
"""
112165
Normal Methods
113166
"""
@@ -249,7 +302,7 @@ def noneMatch(self, predicate):
249302
:param Predicate predicate: predicate to apply to elements of this stream
250303
:return: True if either no elements of the stream match the provided predicate or the stream is empty, otherwise False
251304
'''
252-
return len(self.__iterable) == 0 or not self.anyMatch(predicate)
305+
return not self.anyMatch(predicate)
253306

254307
def findFirst(self):
255308
'''
@@ -292,7 +345,11 @@ def min(self, comparator=None):
292345
:param Comparator comparator: Comparator to compare elements of this stream - if null default comparator is used
293346
:return: an Optional describing the minimum element of this stream, or an empty Optional if the stream is empty
294347
'''
295-
return Optional.ofNullable(min(self.__iterable, key=cmp_to_key(comparator))) if comparator is not None else Optional.ofNullable(min(self.__iterable))
348+
elements = list(self.__iterable)
349+
if len(elements) == 0:
350+
return Optional.empty()
351+
352+
return Optional.ofNullable(min(elements, key=cmp_to_key(comparator), default=None)) if comparator is not None else Optional.ofNullable(min(elements, default=None))
296353

297354
def max(self, comparator=None):
298355
'''
@@ -301,7 +358,10 @@ def max(self, comparator=None):
301358
:param Comparator comparator: Comparator to compare elements of this stream - if null default comparator is used
302359
:return: an Optional describing the maximum element of this stream, or an empty Optional if the stream is empty
303360
'''
304-
return Optional.ofNullable(max(self.__iterable, key=cmp_to_key(comparator))) if comparator is not None else Optional.ofNullable(max(self.__iterable))
361+
elements = list(self.__iterable)
362+
if len(elements) == 0:
363+
return Optional.empty()
364+
return Optional.ofNullable(max(elements, key=cmp_to_key(comparator))) if comparator is not None else Optional.ofNullable(max(elements))
305365

306366
def sum(self):
307367
'''

0 commit comments

Comments
 (0)