Skip to content

Commit 8f8bb6e

Browse files
committed
#48: Add default method implementation to Enumerable interface
Fixed #48
1 parent ddd586d commit 8f8bb6e

File tree

14 files changed

+424
-252
lines changed

14 files changed

+424
-252
lines changed

readme.md

Lines changed: 149 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -38,108 +38,210 @@
3838
### Overview
3939

4040
**enumerable4j** is a Ruby's well known [Enumerable](https://ruby-doc.org/core-2.6/Enumerable.html)
41-
ported to `java`.
41+
ported to `java` as interface with set of default methods which simplify typical operations with collections.
4242
```java
4343
/**
44-
* The immutable enumerable collection.
44+
* The iterable with primitive operations witch simplify typical actions like count, map, etc.
4545
*
46-
* The Enumerable provides methods with several traversal and searching features,
47-
* and with the ability to sort. The class must provide a method each, which yields
48-
* successive members of the collection.
49-
*
50-
* This feature is ported from ruby language
46+
* The API is based on Ruby's Enumerable:
5147
* https://ruby-doc.org/core-2.6/Enumerable.html.
5248
*
53-
* @param <T> The type of entities.
49+
* The Enumerable provides methods with several traversal and searching features, and with the
50+
* ability to sort. The class must provide a method each, which yields successive members of the
51+
* collection.
52+
*
53+
* @param <X> The type of entities.
5454
* @since 0.1.0
5555
*/
56-
public interface Enumerable<T> extends Collection<T> {
57-
...
56+
public interface Enumerable<X> extends Collection<X> {
57+
/**
58+
* Passes each element of the collection to the given block.
59+
* @param prd The predicate to match each element.
60+
* @return The true if the block never returns false or nil.
61+
*/
62+
default boolean all(Predicate<T> prd) {
63+
// ...
64+
}
65+
66+
/**
67+
* Passes at least one element of the collection to the given block.
68+
* @param prd The predicate to match at least one element.
69+
* @return The true if the block never returns false or nil.
70+
*/
71+
default boolean any(Predicate<T> prd) {
72+
// ...
73+
}
74+
75+
/**
76+
* Doesn't passes elements of the collection to the given block.
77+
* @param prd The predicate to match none elements.
78+
* @return The true if the block never returns false or nil.
79+
*/
80+
default boolean none(Predicate<T> prd) {
81+
// ...
82+
}
83+
84+
/**
85+
* Returns an enumerable containing all elements of enumerable for which the given function
86+
* returns a true value.
87+
* If no predicate (null) is given, then 'this' is returned instead.
88+
* @param prd The function to match each element.
89+
* @return The enumerable.
90+
*/
91+
default Enumerable<T> select(Predicate<T> prd) {
92+
// ...
93+
}
94+
95+
/**
96+
* Returns an enumerable containing all elements of enumerable for which the given function
97+
* returns a false value.
98+
* If no predicate (null) is given, then 'this' is returned instead.
99+
* @param prd The function to match each element.
100+
* @return The enumerable.
101+
*/
102+
default Enumerable<T> reject(Predicate<T> prd) {
103+
// ...
104+
}
105+
106+
/**
107+
* Returns an enumerable containing first element of enumerable for which the given function
108+
* returns a true value.
109+
* If no predicate (null) is given, or no element found then null is returned instead.
110+
* @param prd The function to match each element.
111+
* @return The first element of enumerable, that matches predicate.
112+
*/
113+
default T find(Predicate<T> prd) {
114+
// ...
115+
}
116+
117+
/**
118+
* Returns an enumerable containing first element of enumerable for which the given function
119+
* returns a true value.
120+
* If no predicate (null) is given, or no element found then alternative is returned instead.
121+
* @param prd The function to match each element.
122+
* @param alt The alternative to return in case of null predicate or no element found.
123+
* @return The first element of enumerable, that matches predicate.
124+
*/
125+
default T find(Predicate<T> prd, T alt) {
126+
// ...
127+
}
128+
129+
/**
130+
* Returns an enumerable containing all elements, on which given function was applied.
131+
* If no function (null) is given, then 'this' is returned instead.
132+
* @param fnc The function to apply to each element.
133+
* @param <Y> The type of target entity.
134+
* @return The enumerable.
135+
*/
136+
default <Y> Enumerable<Y> map(Function<? super T, ? extends Y> fnc) {
137+
// ...
138+
}
139+
140+
/**
141+
* Returns the number of elements that are present in enumerable for which the given
142+
* function return true.
143+
* If no function (null) is given, then 'size' is returned instead.
144+
* @param prd The function to match each element.
145+
* @return Number of elements satisfying the given function.
146+
*/
147+
default long count(Predicate<T> prd) {
148+
// ...
149+
}
150+
}
58151
```
59152
See [more](./src/main/java/io/github/dgroup/enumerable4j/Enumerable.java)
60153

61154
### How to use
62155

63-
Get the latest version [here](https://github.com/dgroup/enumerable4j/releases):
64-
65-
```xml
66-
67-
<dependency>
68-
<groupId>io.github.dgroup</groupId>
69-
<artifactId>enumerable4j</artifactId>
70-
<version>${version}</version>
71-
</dependency>
72-
```
73-
74-
Java version required: 1.8+.
75-
76-
enumerable4j (MIT) | Java 8 | [cactoos](https://github.com/yegor256/cactoos) (MIT) | [eclipse-collections]() (EDL)
77-
|------ | ------ | ------ |------ |
78-
`.all(...)` | `.stream().allMatch(...);` | `new And<>(...,...).value()`| tbd |
79-
`.any(...)` | `.stream().anyMatch(...);` | `new Or<>(...,...).value()`| tbd |
80-
`.none(...)` | `.stream().noneMatch(...);` | `new And<>(...,...).value()`| tbd |
81-
`.select(...)` | `.stream().filter(...).collect(Collectors.toList())` | `new Filtered<>(...,...)` | tbd |
82-
`.reject(...)` | `.stream().filter((...).negate()).collect(Collectors.toList())` | `new Filtered<>(...,...)` | tbd |
83-
`.map(...)` | `.stream().map(...).collect(Collectors.toList())` | `new Mapped<>(...,...)` | tbd |
84-
`.count(...)` | `.stream().filter(...).count()` | `-` | tbd |
85-
`.find(...)` | `.stream().filter(...).findFirst().orElse(...)` | `-` | tbd |
156+
1. Get the latest version [here](https://github.com/dgroup/enumerable4j/releases):
157+
```xml
158+
<dependency>
159+
<groupId>io.github.dgroup</groupId>
160+
<artifactId>enumerable4j</artifactId>
161+
<version>${version}</version>
162+
</dependency>
163+
```
164+
2. Assign the [Enumerable](./src/main/java/io/github/dgroup/enumerable4j/Enumerable.java) interface with default methods to your own collection
165+
```java
166+
/**
167+
* The collection or iterable which you implemented in your project for some purposes.
168+
* You would like to extend the api in order to make it much more
169+
*/
170+
public class YourOwnCollection<X> extends Collection<X> implements Enumerable<X> {
171+
//
172+
}
173+
```
174+
You may (but not required) override the default implementations of methods from [Enumerable](./src/main/java/io/github/dgroup/enumerable4j/Enumerable.java) if needed.
175+
176+
3. Java version required: 1.8+.
177+
4. Comparing matrix with other libs:
178+
179+
enumerable4j (MIT) | Java 8 | [cactoos](https://github.com/yegor256/cactoos) (MIT) | [eclipse-collections]() (EDL)
180+
|------ | ------ | ------ |------ |
181+
`.all(...)` | `.stream().allMatch(...);` | `new And<>(...,...).value()`| tbd |
182+
`.any(...)` | `.stream().anyMatch(...);` | `new Or<>(...,...).value()`| tbd |
183+
`.none(...)` | `.stream().noneMatch(...);` | `new And<>(...,...).value()`| tbd |
184+
`.select(...)` | `.stream().filter(...).collect(Collectors.toList())` | `new Filtered<>(...,...)` | tbd |
185+
`.reject(...)` | `.stream().filter((...).negate()).collect(Collectors.toList())` | `new Filtered<>(...,...)` | tbd |
186+
`.map(...)` | `.stream().map(...).collect(Collectors.toList())` | `new Mapped<>(...,...)` | tbd |
187+
`.count(...)` | `.stream().filter(...).count()` | `-` | tbd |
188+
`.find(...)` | `.stream().filter(...).findFirst().orElse(...)` | `-` | tbd |
86189

87190
#### .all
88191

89192
```java
90-
Enumerable<Integer> src = new EnumerableOf<>(1, 2, 3); // [java.util.Collection] => [1, 2, 3]
91-
boolean allPositive = src.all(v -> v > 0); // true
193+
YourOwnCollection<Integer> src = ... // with elements [1, 2, 3]
194+
boolean allPositive = src.all(v -> v > 0); // true
92195
```
93196

94197
#### .any
95198

96199
```java
97-
Enumerable<Integer> src = new EnumerableOf<>(-1, 0, 1); // [java.util.Collection] => [-1, 0, 1]
98-
boolean oneIsPositive = src.any(v -> v > 0); // true
200+
YourOwnCollection<Integer> src = ... // with elements [-1, 0, 1]
201+
boolean oneIsPositive = src.any(v -> v > 0); // true
99202
```
100203

101204
#### .none
102205

103206
```java
104-
Enumerable<Integer> src = new EnumerableOf<>(-2, -1, 0); // [java.util.Collection] => [-2, -1, 0]
105-
boolean noneIsPositive = src.none(v -> v > 0); // true
207+
YourOwnCollection<Integer> src = ... // with elements [-2, -1, 0]
208+
boolean noneIsPositive = src.none(v -> v > 0); // true
106209
```
107210

108211
#### .select
109212

110213
```java
111-
Enumerable<Integer> src = new EnumerableOf<>(-1, 1, 2); // [java.util.Collection] => [-1, 1, 2]
214+
YourOwnCollection<Integer> src = ... // with elements [-1, 1, 2]
112215
Enumerable<Integer> positive = src.select(v -> v > 0); // [1, 2]
113216
```
114217

115218
#### .reject
116219

117220
```java
118-
Enumerable<Integer> src = new EnumerableOf<>(-1, 1, 2); // [java.util.Collection] => [-1, 1, 2]
221+
YourOwnCollection<Integer> src = ... // with elements [-1, 1, 2]
119222
Enumerable<Integer> negative = src.reject(v -> v > 0); // [-1]
120223
```
121224

122225
#### .map
123226

124227
```java
125-
Enumerable<Integer> src = new EnumerableOf<>(0, 1, 2); // [java.util.Collection] => [0, 1, 2]
228+
YourOwnCollection<Integer> src = ... // with elements [0, 1, 2]
126229
Enumerable<Integer> positive = src.map(v -> v + 1); // [1, 2, 3]
127230
```
128231

129232
#### .count
130233

131234
```java
132-
Enumerable<Integer> src = new EnumerableOf<>(-1, 0, 1); // [java.util.Collection] => [-1, 0, 1]
133-
long countNegative = src.count(val -> val < 0); // 1
134-
long count = src.count(null); // 3
235+
YourOwnCollection<Integer> src = ... // with elements [-1, 0, 1]
236+
long countNegative = src.count(val -> val < 0); // 1
135237
```
136238

137239
#### .find
138240

139241
```java
140-
Enumerable<Integer> src = new EnumerableOf<>(-1, 0, 1); // [java.util.Collection] => [-1, 0, 1]
242+
YourOwnCollection<Integer> src = ... // with elements [-1, 0, 1]
141243
Integer first = src.find(val -> val > 0); // 1
142-
Integer altFind = src.find(val -> val == 10, 777); // 777
244+
Integer alternative = src.find(val -> val > 5, 50); // 50
143245
```
144246

145247
### How to contribute?
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
/*
2+
* MIT License
3+
*
4+
* Copyright (c) 2019-2021 Yurii Dubinka
5+
*
6+
* Permission is hereby granted, free of charge, to any person obtaining a copy
7+
* of this software and associated documentation files (the "Software"),
8+
* to deal in the Software without restriction, including without limitation
9+
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
10+
* and/or sell copies of the Software, and to permit persons to whom
11+
* the Software is furnished to do so, subject to the following conditions:
12+
*
13+
* The above copyright notice and this permission notice shall be included
14+
* in all copies or substantial portions of the Software.
15+
*
16+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18+
* FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE
19+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
21+
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE
22+
* OR OTHER DEALINGS IN THE SOFTWARE.
23+
*/
24+
package io.github.dgroup.enumerable4j;
25+
26+
import java.util.Collections;
27+
import org.cactoos.list.ListEnvelope;
28+
29+
/**
30+
* The empty enumerable.
31+
*
32+
* @param <X> The type of entities.
33+
* @since 0.1.0
34+
*/
35+
public class Empty<X> extends ListEnvelope<X> implements Enumerable<X> {
36+
/**
37+
* Ctor.
38+
*/
39+
public Empty() {
40+
super(Collections.emptyList());
41+
}
42+
}

0 commit comments

Comments
 (0)