From 9bcb0c4b1b66c0ee2845dc765c1674f42d410b2f Mon Sep 17 00:00:00 2001 From: mbarriola <85458535+mbarriola@users.noreply.github.com> Date: Thu, 2 Sep 2021 06:55:08 -0400 Subject: [PATCH] Bael 5073 guide to multi map (#11179) * Commit source code to branch * BAEL-5065 improvement of groupBy with complex key * Source code for Guide to Stream::mapMulti --- .../java_16_features/mapmulti/Album.java | 49 +++++++ .../java_16_features/mapmulti/Artist.java | 50 +++++++ .../mapmulti/JavaStreamMapMultiUnitTest.java | 134 ++++++++++++++++++ 3 files changed, 233 insertions(+) create mode 100644 core-java-modules/core-java-16/src/main/java/com/baeldung/java_16_features/mapmulti/Album.java create mode 100644 core-java-modules/core-java-16/src/main/java/com/baeldung/java_16_features/mapmulti/Artist.java create mode 100644 core-java-modules/core-java-16/src/test/java/com/baeldung/java_16_features/mapmulti/JavaStreamMapMultiUnitTest.java diff --git a/core-java-modules/core-java-16/src/main/java/com/baeldung/java_16_features/mapmulti/Album.java b/core-java-modules/core-java-16/src/main/java/com/baeldung/java_16_features/mapmulti/Album.java new file mode 100644 index 0000000000..fa7ec02307 --- /dev/null +++ b/core-java-modules/core-java-16/src/main/java/com/baeldung/java_16_features/mapmulti/Album.java @@ -0,0 +1,49 @@ +package com.baeldung.java_16_features.mapmulti; + +import java.util.List; +import java.util.function.Consumer; +import java.util.stream.Collectors; + +import org.apache.commons.lang3.tuple.ImmutablePair; +import org.apache.commons.lang3.tuple.Pair; + +public class Album { + + private String albumName; + private int albumCost; + private List artists; + + Album(String name, int albumCost, List artists) { + this.albumName = name; + this.artists = artists; + this.albumCost = albumCost; + } + + public void artistAlbumPairsToMajorLabels(Consumer> consumer) { + + for (Artist artist : artists) { + if (artist.isAssociatedMajorLabels()) { + String concatLabels = artist.getMajorLabels() + .stream() + .collect(Collectors.joining(",")); + consumer.accept(new ImmutablePair<>(artist.getName() + ":" + albumName, concatLabels)); + } + } + } + + public String getAlbumName() { + return albumName; + } + + public int getAlbumCost() { + return albumCost; + } + + List getArtists() { + return artists; + } + + public String toString() { + return albumName; + } +} diff --git a/core-java-modules/core-java-16/src/main/java/com/baeldung/java_16_features/mapmulti/Artist.java b/core-java-modules/core-java-16/src/main/java/com/baeldung/java_16_features/mapmulti/Artist.java new file mode 100644 index 0000000000..b3b9b7aa10 --- /dev/null +++ b/core-java-modules/core-java-16/src/main/java/com/baeldung/java_16_features/mapmulti/Artist.java @@ -0,0 +1,50 @@ +package com.baeldung.java_16_features.mapmulti; + +import java.util.List; +import java.util.Objects; + +public class Artist { + + private final String name; + private boolean associatedMajorLabels; + private List majorLabels; + + Artist(String name, boolean associatedMajorLabels, List majorLabels) { + this.name = name; + this.associatedMajorLabels = associatedMajorLabels; + this.majorLabels = majorLabels; + } + + public String getName() { + return name; + } + + public boolean isAssociatedMajorLabels() { + return associatedMajorLabels; + } + + public List getMajorLabels() { + return majorLabels; + } + + @Override + public int hashCode() { + return Objects.hash(name); + } + + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + Artist other = (Artist) obj; + return Objects.equals(name, other.name); + } + + public String toString() { + return name; + } +} diff --git a/core-java-modules/core-java-16/src/test/java/com/baeldung/java_16_features/mapmulti/JavaStreamMapMultiUnitTest.java b/core-java-modules/core-java-16/src/test/java/com/baeldung/java_16_features/mapmulti/JavaStreamMapMultiUnitTest.java new file mode 100644 index 0000000000..0ab1a95ed0 --- /dev/null +++ b/core-java-modules/core-java-16/src/test/java/com/baeldung/java_16_features/mapmulti/JavaStreamMapMultiUnitTest.java @@ -0,0 +1,134 @@ +package com.baeldung.java_16_features.mapmulti; + +import static java.util.stream.Collectors.toList; +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.offset; +import static org.junit.jupiter.api.Assertions.assertTrue; + +import java.util.Arrays; +import java.util.List; + +import org.apache.commons.lang3.tuple.ImmutablePair; +import org.apache.commons.lang3.tuple.Pair; +import org.junit.jupiter.api.Test; + +public class JavaStreamMapMultiUnitTest { + + private static final List albums = Arrays.asList(new Album("album1", 10, Arrays.asList(new Artist("bob", true, Arrays.asList("label1", "label3")), new Artist("tom", true, Arrays.asList("label2", "label3")))), + new Album("album2", 20, Arrays.asList(new Artist("bill", true, Arrays.asList("label2", "label3")), new Artist("tom", true, Arrays.asList("label2", "label4"))))); + + @Test + public void givenAListOfintegers_whenMapMulti_thenGetListOfOfEvenDoublesPlusPercentage() { + + List integers = Arrays.asList(1, 2, 3, 4, 5); + double percentage = .01; + List evenDoubles = integers.stream() + . mapMulti((integer, consumer) -> { + if (integer % 2 == 0) { + consumer.accept((double) integer * (1 + percentage)); + } + }) + .collect(toList()); + + assertThat(evenDoubles).containsAll(Arrays.asList(2.02D, 4.04D)); + } + + @Test + public void givenAListOfintegers_whenFilterMap_thenGetListOfOfEvenDoublesPlusPercentage() { + + List integers = Arrays.asList(1, 2, 3, 4, 5); + double percentage = .01; + List evenDoubles = integers.stream() + .filter(integer -> integer % 2 == 0) + . map(integer -> ((double) integer * (1 + percentage))) + .collect(toList()); + + assertThat(evenDoubles).containsAll(Arrays.asList(2.02D, 4.04D)); + } + + @Test + public void givenAListOfintegers_whenMapMultiToDouble_thenGetSumOfEvenNumbersAfterApplyPercentage() { + + List integers = Arrays.asList(1, 2, 3, 4, 5, 6, 7); + double percentage = .01; + double sum = integers.stream() + .mapMultiToDouble((integer, consumer) -> { + if (integer % 2 == 0) { + consumer.accept(integer * (1 + percentage)); + } + }) + .sum(); + + assertThat(sum).isEqualTo(12.12, offset(0.001d)); + } + + @Test + public void givenAListOfAlbums_whenFlatMap_thenGetListOfArtistAlbumPairs() { + + List> artistAlbum = albums.stream() + .flatMap(album -> album.getArtists() + .stream() + .map(artist -> new ImmutablePair(artist.getName(), album.getAlbumName()))) + .collect(toList()); + + assertThat(artistAlbum).contains(new ImmutablePair("bob", "album1"), new ImmutablePair("tom", "album1"), new ImmutablePair("bill", "album2"), new ImmutablePair("tom", "album2")); + } + + @Test + public void givenAListOfAlbums_whenMapMulti_thenGetListOfPairsOfArtistAlbum() { + + List> artistAlbum = albums.stream() + .> mapMulti((album, consumer) -> { + for (Artist artist : album.getArtists()) { + consumer.accept(new ImmutablePair(artist.getName(), album.getAlbumName())); + } + }) + .collect(toList()); + + assertThat(artistAlbum).contains(new ImmutablePair("bob", "album1"), new ImmutablePair("tom", "album1"), + new ImmutablePair("bill", "album2"), new ImmutablePair("tom", "album2")); + } + + @Test + public void givenAListOfAlbums_whenFlatMap_thenGetListOfArtistAlbumjPairsBelowGivenCost() { + + int upperCost = 9; + List> artistAlbum = albums.stream() + .flatMap(album -> album.getArtists() + .stream() + .filter(artist -> upperCost > album.getAlbumCost()) + .map(artist -> new ImmutablePair(artist.getName(), album.getAlbumName()))) + .collect(toList()); + + assertTrue(artistAlbum.isEmpty()); + } + + @Test + public void givenAListOfAlbums_whenMapMulti_thenGetListOfArtistAlbumPairsBelowGivenCost() { + + int upperCost = 9; + List> artistAlbum = albums.stream() + .> mapMulti((album, consumer) -> { + if (album.getAlbumCost() < upperCost) { + for (Artist artist : album.getArtists()) { + consumer.accept(new ImmutablePair(artist.getName(), album.getAlbumName())); + } + } + }) + .collect(toList()); + + assertTrue(artistAlbum.isEmpty()); + } + + @Test + public void givenAListOfAlbums_whenMapMulti_thenGetPairsOfArtistMajorLabelsUsingMethodReference() { + + List> artistLabels = albums.stream() + .mapMulti(Album::artistAlbumPairsToMajorLabels) + .collect(toList()); + + assertThat(artistLabels).contains(new ImmutablePair("bob:album1", "label1,label3"), new ImmutablePair("tom:album1", "label2,label3"), + new ImmutablePair("bill:album2", "label2,label3"), new ImmutablePair("tom:album2", "label2,label4")); + } +} \ No newline at end of file