Skip to content

Commit 704a126

Browse files
committed
init
1 parent c86dbe7 commit 704a126

File tree

2 files changed

+113
-0
lines changed

2 files changed

+113
-0
lines changed

src/main/java/one/util/streamex/EntryStream.java

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -476,6 +476,40 @@ public <KK> EntryStream<KK, V> mapKeys(Function<? super K, ? extends KK> keyMapp
476476
e -> new SimpleImmutableEntry<>(keyMapper.apply(e.getKey()), e.getValue())), context);
477477
}
478478

479+
/**
480+
* Returns an {@code EntryStream} consisting of the entries whose keys are
481+
* modified by applying the given partial function to keys of this {@code EntryStream}
482+
* and removing the keys to which the function is not applicable. The values are left
483+
* unchanged.
484+
*
485+
* <p>
486+
* If the mapping function returns {@link Optional#empty()}, the original
487+
* key will be removed from the resulting {@code EntryStream}. The mapping function
488+
* may not return null.
489+
*
490+
* <p>
491+
* This is an <a href="package-summary.html#StreamOps">intermediate
492+
* operation</a>.
493+
*
494+
* <p>
495+
* The {@code mapKeysPartial()} operation has the effect of applying a
496+
* one-to-zero-or-one transformation to the keys of the {@code EntryStream},
497+
* and then flattening the resulting elements into a new stream.
498+
*
499+
* @param <KK> The element type of keys in the new {@code EntryStream}
500+
* @param keyMapper a <a
501+
* href="package-summary.html#NonInterference">non-interfering </a>,
502+
* <a href="package-summary.html#Statelessness">stateless</a>
503+
* partial function to apply to each key which returns a present optional
504+
* if it's applicable, or an empty optional otherwise
505+
* @return the new stream
506+
* @since 0.8.4
507+
*
508+
*/
509+
public <KK> EntryStream<KK, V> mapKeysPartial(Function<? super K, ? extends Optional<? extends KK>> keyMapper) {
510+
return new EntryStream<>(stream().map(e -> new SimpleImmutableEntry<>((KK) keyMapper.apply(e.getKey()).orElse(null), e.getValue())).filter(e -> e.getKey() != null), context);
511+
}
512+
479513
/**
480514
* Returns an {@code EntryStream} consisting of the entries whose keys are
481515
* left unchanged and values are modified by applying the given function.
@@ -494,6 +528,39 @@ public <VV> EntryStream<K, VV> mapValues(Function<? super V, ? extends VV> value
494528
e -> new SimpleImmutableEntry<>(e.getKey(), valueMapper.apply(e.getValue()))), context);
495529
}
496530

531+
/**
532+
* Returns an {@code EntryStream} consisting of the entries whose values are
533+
* modified by applying the given partial function to values of this {@code EntryStream}
534+
* and removing the values to which the function is not applicable. The keys are left
535+
* unchanged.
536+
*
537+
* <p>
538+
* If the mapping function returns {@link Optional#empty()}, the original
539+
* value will be removed from the resulting {@code EntryStream}. The mapping function
540+
* may not return null.
541+
*
542+
* <p>
543+
* This is an <a href="package-summary.html#StreamOps">intermediate
544+
* operation</a>.
545+
*
546+
* <p>
547+
* The {@code mapValuesPartial()} operation has the effect of applying a
548+
* one-to-zero-or-one transformation to the keys of the {@code EntryStream},
549+
* and then flattening the resulting elements into a new stream.
550+
*
551+
* @param <VV> The element type of keys in the new {@code EntryStream}
552+
* @param valueMapper a <a
553+
* href="package-summary.html#NonInterference">non-interfering </a>,
554+
* <a href="package-summary.html#Statelessness">stateless</a>
555+
* partial function to apply to each value which returns a present optional
556+
* if it's applicable, or an empty optional otherwise
557+
* @return the new stream
558+
* @since 0.8.4
559+
*/
560+
public <VV> EntryStream<K, VV> mapValuesPartial(Function<? super V, ? extends Optional<? extends VV>> valueMapper) {
561+
return new EntryStream<>(stream().map(e -> new SimpleImmutableEntry<>(e.getKey(), (VV) valueMapper.apply(e.getValue()).orElse(null))).filter(e -> e.getValue() != null), context);
562+
}
563+
497564
/**
498565
* Returns a {@link StreamEx} consisting of the results of applying the
499566
* given function to the keys and values of this stream.

src/test/java/one/util/streamex/api/EntryStreamTest.java

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -267,6 +267,29 @@ public void testMapKeys() {
267267
assertEquals(expected, result);
268268
}
269269

270+
@Test
271+
public void testMapKeysPartial() {
272+
Map<Integer, Integer> original = new HashMap<>();
273+
original.put(1, 1);
274+
original.put(2, 2);
275+
original.put(3, 3);
276+
original.put(4, 4);
277+
278+
Map<Integer, Integer> expected = new HashMap<>();
279+
expected.put(1, 2);
280+
expected.put(2, 4);
281+
282+
Map<Integer, Integer> actual = EntryStream.of(original)
283+
.mapKeysPartial(key -> {
284+
if (key % 2 == 0) {
285+
return Optional.of(key / 2);
286+
}
287+
return Optional.empty();
288+
}).toMap();
289+
290+
assertEquals(expected, actual);
291+
}
292+
270293
@Test
271294
public void testMapValues() {
272295
Map<String, String> expected = new HashMap<>();
@@ -277,6 +300,29 @@ public void testMapValues() {
277300
assertEquals(expected, result);
278301
}
279302

303+
@Test
304+
public void testMapValuesPartial() {
305+
Map<Integer, Integer> original = new HashMap<>();
306+
original.put(1, 1);
307+
original.put(2, 2);
308+
original.put(3, 3);
309+
original.put(4, 4);
310+
311+
Map<Integer, Integer> expected = new HashMap<>();
312+
expected.put(2, 1);
313+
expected.put(4, 2);
314+
315+
Map<Integer, Integer> actual = EntryStream.of(original)
316+
.mapValuesPartial(value -> {
317+
if (value % 2 == 0) {
318+
return Optional.of(value / 2);
319+
}
320+
return Optional.empty();
321+
}).toMap();
322+
323+
assertEquals(expected, actual);
324+
}
325+
280326
@Test
281327
public void testMapToValue() {
282328
Map<String, Integer> expected = new HashMap<>();

0 commit comments

Comments
 (0)