Skip to content

Commit e08b34d

Browse files
Merge pull request #15 from SimonHarmonicMinor/issue#14-release-1.1
Issue#14 release 1.1
2 parents c549dcf + 4c670e8 commit e08b34d

32 files changed

+2338
-325
lines changed

.travis.yml

+4-1
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,13 @@
11
language: java
22

3+
git:
4+
depth: false
5+
36
addons:
47
sonarcloud:
58
organization: simonharmonicminor
69
token:
710
secure: WeqLn+kxvsbuN6yLGqu1U9r7aZvBkOKv7W/1Pf2dvgrTPcPvLHThrKsAbK8qfWkuoG3Y9FbmzPGH3KfiN+yszIN6OxQl6B85FrlZ/sVGUNrW9idCpohX+WncI4zT32oObZTPcQ2kq1AQQfrI0dmZ5ihqltlV/GbBEhYenXwWmNAPNJXlzR2TaF2ApOzLXjdiX/z6jmU/hZCdxxHkPyxjW0Nm1AzwNWq7s+vsI+plOJDaF9skj+7exKKJ0lxFq/hiyBEazt3HZy87OsxJ/9DhYCKwV4FmQu3cBjkWXXl3334bdF5tELyeHMxJzrpX8XXIKZke2Bu+7uES+vCkVyceavnKBEoPeiBC4CdTyuHordrg11dsrSuS63XLFap0gdbWzVi9gacjdmjoqHnjO69AJ0F4yZvHJGwPlLn5zpq4Qa41aWa5BiU7R8hOzRfqSR4xgeiDemhPJhWYsIfLQ1c4id7kYJUfX/3olq9ffDCXVKXe4UHm5cqaq91u865WdNnn1FQP4coy3D4z3thsmBnRn/Z9bH/IaP4cscOxZsXffSHHjOyLzkkYIOIMW08Bwq5WhrTk4+hHnONcSAkXPt0JYQnG1Tw7nUOQ3borNFqGxw4AUEHisnofBfYpW7ggRyj8xx7JZQI7teLPbhuvaXeFfjL9xvsI+LdOaWclZsN5Qeg=
811

912
script:
10-
- mvn clean org.jacoco:jacoco-maven-plugin:prepare-agent package org.jacoco:jacoco-maven-plugin:report sonar:sonar -Dsonar.projectKey=SimonHarmonicMinor_Java-Useful-Utils
13+
- mvn clean org.jacoco:jacoco-maven-plugin:prepare-agent package org.jacoco:jacoco-maven-plugin:report sonar:sonar -Dsonar.java.binaries=target/classes -Dsonar.projectKey=SimonHarmonicMinor_Java-Useful-Utils

README.md

+27-7
Original file line numberDiff line numberDiff line change
@@ -15,12 +15,12 @@ Maven:
1515
<dependency>
1616
<groupId>com.github.simonharmonicminor</groupId>
1717
<artifactId>java-useful-utils</artifactId>
18-
<version>1.0</version>
18+
<version>1.1</version>
1919
</dependency>
2020
```
2121
Gradle:
2222
```groovy
23-
implementation 'com.github.simonharmonicminor:java-useful-utils:1.0'
23+
implementation 'com.github.simonharmonicminor:java-useful-utils:1.1'
2424
```
2525

2626
### Status
@@ -29,7 +29,7 @@ implementation 'com.github.simonharmonicminor:java-useful-utils:1.0'
2929
[![Coverage](https://sonarcloud.io/api/project_badges/measure?project=SimonHarmonicMinor_Java-Useful-Utils&metric=coverage)](https://sonarcloud.io/dashboard?id=SimonHarmonicMinor_Java-Useful-Utils)
3030

3131
### Usage
32-
The library contains of three big parts.
32+
The library consists of three big parts.
3333
* [Measurement](#measurement)
3434
* [Monads](#monads) (functional style programming)
3535
* [Collections](#collections)
@@ -60,7 +60,8 @@ assert exec.getMeasureUnit() == MeasureUnit.MILLIS;
6060
```
6161

6262
Simple, right? If you need to measure something in different
63-
units, just call the appropriate method (`inMillis()` in this case).
63+
units, just call the appropriate method
64+
(`inMillis()`, `inNanos()` or `inSeconds()`).
6465

6566
And what if you need to measure code block from one point to another?
6667
Well, `Profiler` is what you need.
@@ -152,6 +153,25 @@ catch (Exception e) {
152153
}
153154
```
154155
156+
If you need the exception that led to the error, you can use
157+
`orElseGet` variation.
158+
159+
```java
160+
Try.of(() -> Integer.parseInt(getStringValue))
161+
.map(x -> 2 % x)
162+
.orElseGet(reason -> {
163+
log.error("Something went wrong", reason);
164+
return 0;
165+
})
166+
```
167+
168+
`reason` has the type of `Throwable` and it's the instance of that very
169+
exception that broke the chain.
170+
For instance, if `Integer.parseInt` threw an exception,
171+
the `reason` would be the type of `NumberFormatException`.
172+
On the other hand, if `x == 0` in the `map` callback,
173+
the reason would be the type of `ArithmeticException`.
174+
155175
###### Lazy
156176

157177
The name of the monad defines its purpose.
@@ -212,7 +232,7 @@ on every `add` call.
212232
213233
JUU library provides new collections, which interfaces
214234
do not inherits from java native Collections.
215-
Here is the schema ![schema](./juu1.0.png)
235+
Here is the scheme ![scheme](./juu1.1.png)
216236
217237
The recommended way to instantiate immutable collections is to use `Immutable` class.
218238
```java
@@ -266,8 +286,8 @@ ImmutableMap<String, Integer> map =
266286
267287
You can user Stream API with immutable collections as well,
268288
but `ImmutableList` and `ImmutableSet` provides kotlin-like methods:
269-
`map`, `flatMap`, `filter`, `sorted`, `min`, `max` and `zip` (for lists).
270-
`ImmutableList` also has indexed methods:
289+
`map`, `flatMap`, `filter`, `min`, `max` and `zip` (for lists).
290+
`ImmutableList` also has `sorted`, `zipWith`, `zipWithNext` and indexed methods
271291
`mapIndexed`, `flatMapIndexed`, `filterIndexed`.
272292
273293
```java

juu1.0.png

-85.6 KB
Binary file not shown.

juu1.1.png

111 KB
Loading

pom.xml

+1-1
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66

77
<groupId>com.github.simonharmonicminor</groupId>
88
<artifactId>java-useful-utils</artifactId>
9-
<version>1.0</version>
9+
<version>1.1</version>
1010
<packaging>jar</packaging>
1111

1212
<name>Java Useful Utils</name>

src/main/java/com/github/simonharmonicminor/juu/collection/immutable/Immutable.java

+24-22
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,6 @@ public class Immutable {
2424
new ImmutableHashSet<>(Collections.emptyList());
2525
private static final ImmutableHashMap<?, ?> EMPTY_HASH_MAP =
2626
new ImmutableHashMap<>(Collections.emptyMap());
27-
private static final ImmutableTreeSet<?> EMPTY_TREE_SET =
28-
ImmutableTreeSet.of(Collections.emptyList(), null);
2927

3028
/**
3129
* Suppresses default constructor, ensuring non-instantiability.
@@ -56,16 +54,6 @@ public static <T> ImmutableSet<T> emptySet() {
5654
return (ImmutableSet<T>) EMPTY_HASH_SET;
5755
}
5856

59-
@SuppressWarnings("unchecked")
60-
static <T> ImmutableTreeSet<T> emptyTreeSet() {
61-
return (ImmutableTreeSet<T>) EMPTY_TREE_SET;
62-
}
63-
64-
@SuppressWarnings("unchecked")
65-
static <T> ImmutableHashSet<T> emptyHashSet() {
66-
return (ImmutableHashSet<T>) EMPTY_HASH_SET;
67-
}
68-
6957
/**
7058
* Returns empty map. Does not create the new one, returns the same instance every time
7159
*
@@ -78,6 +66,13 @@ public static <K, V> ImmutableMap<K, V> emptyMap() {
7866
return (ImmutableMap<K, V>) EMPTY_HASH_MAP;
7967
}
8068

69+
70+
private static <T> ImmutableList<T> listOf(Iterable<T> elements, boolean needsCloning) {
71+
Objects.requireNonNull(elements);
72+
if (!elements.iterator().hasNext()) return emptyList();
73+
return new ImmutableArrayList<>(elements, needsCloning);
74+
}
75+
8176
/**
8277
* Creates new immutable list from given elements. If array is empty, returns {@link
8378
* Immutable#emptyList()}. This is the preferred way of creating immutable lists, unless you need
@@ -90,9 +85,7 @@ public static <K, V> ImmutableMap<K, V> emptyMap() {
9085
*/
9186
@SafeVarargs
9287
public static <T> ImmutableList<T> listOf(T... elements) {
93-
Objects.requireNonNull(elements);
94-
if (elements.length == 0) return emptyList();
95-
return new ImmutableArrayList<>(Arrays.stream(elements).collect(Collectors.toList()));
88+
return listOf(Arrays.stream(elements).collect(Collectors.toList()), false);
9689
}
9790

9891
/**
@@ -106,9 +99,17 @@ public static <T> ImmutableList<T> listOf(T... elements) {
10699
* @throws NullPointerException if {@code elements} is null
107100
*/
108101
public static <T> ImmutableList<T> listOf(Iterable<T> elements) {
102+
return listOf(elements, true);
103+
}
104+
105+
static <T> ImmutableList<T> listOfWithoutCloning(Iterable<T> elements) {
106+
return listOf(elements, false);
107+
}
108+
109+
private static <T> ImmutableSet<T> setOf(Iterable<T> elements, boolean needsCloning) {
109110
Objects.requireNonNull(elements);
110-
if (!elements.iterator().hasNext()) return emptyList();
111-
return new ImmutableArrayList<>(elements);
111+
if (!elements.iterator().hasNext()) return emptySet();
112+
return new ImmutableHashSet<>(elements, needsCloning);
112113
}
113114

114115
/**
@@ -124,8 +125,7 @@ public static <T> ImmutableList<T> listOf(Iterable<T> elements) {
124125
@SafeVarargs
125126
public static <T> ImmutableSet<T> setOf(T... elements) {
126127
Objects.requireNonNull(elements);
127-
if (elements.length == 0) return emptySet();
128-
return new ImmutableHashSet<>(Arrays.stream(elements).collect(Collectors.toSet()));
128+
return setOf(Arrays.stream(elements).collect(Collectors.toSet()), false);
129129
}
130130

131131
/**
@@ -139,9 +139,11 @@ public static <T> ImmutableSet<T> setOf(T... elements) {
139139
* @throws NullPointerException if {@code elements} is null
140140
*/
141141
public static <T> ImmutableSet<T> setOf(Iterable<T> elements) {
142-
Objects.requireNonNull(elements);
143-
if (!elements.iterator().hasNext()) return emptySet();
144-
return new ImmutableHashSet<>(elements);
142+
return setOf(elements, true);
143+
}
144+
145+
static <T> ImmutableSet<T> setOfWithoutCloning(Iterable<T> elements) {
146+
return setOf(elements, false);
145147
}
146148

147149
public static <K, V> ImmutableMap<K, V> mapOf(Map<K, V> map) {

src/main/java/com/github/simonharmonicminor/juu/collection/immutable/ImmutableArrayList.java

+15-19
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
import java.util.function.*;
88
import java.util.stream.Stream;
99

10+
import static com.github.simonharmonicminor.juu.collection.immutable.Immutable.listOfWithoutCloning;
1011
import static com.github.simonharmonicminor.juu.collection.immutable.Immutable.setOf;
1112
import static com.github.simonharmonicminor.juu.collection.immutable.ImmutableCollectionUtils.listEquals;
1213
import static com.github.simonharmonicminor.juu.collection.immutable.ImmutableCollectionUtils.listToString;
@@ -44,11 +45,6 @@ public ImmutableArrayList(Iterable<T> iterable) {
4445
}
4546
}
4647

47-
private static <R> ImmutableList<R> newImmutableList(List<R> list) {
48-
if (list.isEmpty()) return Immutable.emptyList();
49-
return new ImmutableArrayList<>(list, false);
50-
}
51-
5248
private int normalizeIndex(int index) {
5349
return index >= 0 ? index : size() + index;
5450
}
@@ -111,7 +107,7 @@ public ImmutableList<T> slice(int fromIndex, int toIndex, int stepSize) {
111107
newArrayList.add(get(fromNorm));
112108
fromNorm = nextValueFunc.apply(fromNorm);
113109
}
114-
return newImmutableList(newArrayList);
110+
return listOfWithoutCloning(newArrayList);
115111
}
116112

117113
@Override
@@ -135,7 +131,7 @@ public ImmutableList<T> concatWith(Iterable<T> iterable) {
135131
for (T t : iterable) {
136132
copy.add(t);
137133
}
138-
return newImmutableList(copy);
134+
return listOfWithoutCloning(copy);
139135
}
140136

141137
private static <R> R getValByIndex(ImmutableList<R> immutableList, int index) {
@@ -153,7 +149,7 @@ public <R> ImmutableList<Pair<T, R>> zipWith(ImmutableList<R> list) {
153149
R right = getValByIndex(list, i);
154150
newArrayList.add(Pair.of(left, right));
155151
}
156-
return newImmutableList(newArrayList);
152+
return listOfWithoutCloning(newArrayList);
157153
}
158154

159155
@Override
@@ -162,7 +158,7 @@ public ImmutableList<Pair<T, T>> zipWithNext() {
162158
for (int i = 0; i < size() - 1; i++) {
163159
newArrayList.add(Pair.of(get(i), get(i + 1)));
164160
}
165-
return newImmutableList(newArrayList);
161+
return listOfWithoutCloning(newArrayList);
166162
}
167163

168164
@Override
@@ -172,7 +168,7 @@ public <R> ImmutableList<R> map(Function<? super T, ? extends R> mapper) {
172168
for (T t : arrayList) {
173169
newList.add(mapper.apply(t));
174170
}
175-
return newImmutableList(newList);
171+
return listOfWithoutCloning(newList);
176172
}
177173

178174
@Override
@@ -182,7 +178,7 @@ public <R> ImmutableList<R> mapIndexed(BiFunction<Integer, ? super T, ? extends
182178
for (int i = 0; i < arrayList.size(); i++) {
183179
newList.add(mapper.apply(i, arrayList.get(i)));
184180
}
185-
return newImmutableList(newList);
181+
return listOfWithoutCloning(newList);
186182
}
187183

188184
@Override
@@ -193,7 +189,7 @@ public <R> ImmutableList<R> flatMap(Function<? super T, ? extends Iterable<R>> m
193189
ImmutableArrayList<R> listElement = new ImmutableArrayList<>(mapper.apply(t));
194190
newList.addAll(listElement.arrayList);
195191
}
196-
return newImmutableList(newList);
192+
return listOfWithoutCloning(newList);
197193
}
198194

199195
@Override
@@ -206,7 +202,7 @@ public <R> ImmutableList<R> flatMapIndexed(
206202
new ImmutableArrayList<>(mapper.apply(i, arrayList.get(i)));
207203
newList.addAll(listElement.arrayList);
208204
}
209-
return newImmutableList(newList);
205+
return listOfWithoutCloning(newList);
210206
}
211207

212208
@Override
@@ -216,7 +212,7 @@ public ImmutableList<T> filter(Predicate<? super T> predicate) {
216212
for (T t : arrayList) {
217213
if (predicate.test(t)) newList.add(t);
218214
}
219-
return newImmutableList(newList);
215+
return listOfWithoutCloning(newList);
220216
}
221217

222218
@Override
@@ -226,7 +222,7 @@ public ImmutableList<T> filterIndexed(BiPredicate<Integer, ? super T> predicate)
226222
for (int i = 0; i < arrayList.size(); i++) {
227223
if (predicate.test(i, arrayList.get(i))) newList.add(arrayList.get(i));
228224
}
229-
return newImmutableList(newList);
225+
return listOfWithoutCloning(newList);
230226
}
231227

232228
@Override
@@ -242,7 +238,7 @@ public ImmutableList<T> sorted(Comparator<? super T> comparator) {
242238
Objects.requireNonNull(comparator);
243239
ArrayList<T> copy = new ArrayList<>(arrayList);
244240
copy.sort(comparator);
245-
return newImmutableList(copy);
241+
return listOfWithoutCloning(copy);
246242
}
247243

248244
@Override
@@ -253,7 +249,7 @@ public ImmutableList<T> limit(int size) {
253249
for (int i = 0; i < Math.min(size(), size); i++) {
254250
newList.add(arrayList.get(i));
255251
}
256-
return newImmutableList(newList);
252+
return listOfWithoutCloning(newList);
257253
}
258254

259255
@Override
@@ -264,7 +260,7 @@ public ImmutableList<T> skip(int size) {
264260
for (int i = Math.min(size, size()); i < arrayList.size(); i++) {
265261
newList.add(arrayList.get(i));
266262
}
267-
return newImmutableList(newList);
263+
return listOfWithoutCloning(newList);
268264
}
269265

270266
@Override
@@ -305,7 +301,7 @@ public Stream<T> stream() {
305301

306302
@Override
307303
public Iterator<T> iterator() {
308-
return arrayList.iterator();
304+
return new UnmodifiableIterator<>(arrayList.iterator());
309305
}
310306

311307
@Override

src/main/java/com/github/simonharmonicminor/juu/collection/immutable/ImmutableCollectionUtils.java

+9
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,10 @@
33
import com.github.simonharmonicminor.juu.monad.Try;
44

55
import java.util.Objects;
6+
import java.util.Optional;
67
import java.util.function.BiConsumer;
78
import java.util.function.Consumer;
9+
import java.util.function.Supplier;
810
import java.util.stream.Collectors;
911

1012
class ImmutableCollectionUtils {
@@ -82,4 +84,11 @@ static boolean mapEquals(ImmutableMap<?, ?> current, Object other) {
8284
return true;
8385
}).orElse(false);
8486
}
87+
88+
static <T> Optional<T> tryGetElement(Supplier<T> supplier) {
89+
Objects.requireNonNull(supplier);
90+
return Try.of(supplier::get)
91+
.map(Optional::ofNullable)
92+
.orElse(Optional.empty());
93+
}
8594
}

0 commit comments

Comments
 (0)