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
This commit is contained in:
mbarriola 2021-09-02 06:55:08 -04:00 committed by GitHub
parent b757f86b73
commit 9bcb0c4b1b
3 changed files with 233 additions and 0 deletions

View File

@ -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<Artist> artists;
Album(String name, int albumCost, List<Artist> artists) {
this.albumName = name;
this.artists = artists;
this.albumCost = albumCost;
}
public void artistAlbumPairsToMajorLabels(Consumer<Pair<String, String>> 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<Artist> getArtists() {
return artists;
}
public String toString() {
return albumName;
}
}

View File

@ -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<String> majorLabels;
Artist(String name, boolean associatedMajorLabels, List<String> majorLabels) {
this.name = name;
this.associatedMajorLabels = associatedMajorLabels;
this.majorLabels = majorLabels;
}
public String getName() {
return name;
}
public boolean isAssociatedMajorLabels() {
return associatedMajorLabels;
}
public List<String> 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;
}
}

View File

@ -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<Album> 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<Integer> integers = Arrays.asList(1, 2, 3, 4, 5);
double percentage = .01;
List<Double> evenDoubles = integers.stream()
.<Double> 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<Integer> integers = Arrays.asList(1, 2, 3, 4, 5);
double percentage = .01;
List<Double> evenDoubles = integers.stream()
.filter(integer -> integer % 2 == 0)
.<Double> map(integer -> ((double) integer * (1 + percentage)))
.collect(toList());
assertThat(evenDoubles).containsAll(Arrays.asList(2.02D, 4.04D));
}
@Test
public void givenAListOfintegers_whenMapMultiToDouble_thenGetSumOfEvenNumbersAfterApplyPercentage() {
List<Integer> 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<Pair<String, String>> artistAlbum = albums.stream()
.flatMap(album -> album.getArtists()
.stream()
.map(artist -> new ImmutablePair<String, String>(artist.getName(), album.getAlbumName())))
.collect(toList());
assertThat(artistAlbum).contains(new ImmutablePair<String, String>("bob", "album1"), new ImmutablePair<String,
String>("tom", "album1"), new ImmutablePair<String, String>("bill", "album2"), new ImmutablePair<String, String>("tom", "album2"));
}
@Test
public void givenAListOfAlbums_whenMapMulti_thenGetListOfPairsOfArtistAlbum() {
List<Pair<String, String>> artistAlbum = albums.stream()
.<Pair<String, String>> mapMulti((album, consumer) -> {
for (Artist artist : album.getArtists()) {
consumer.accept(new ImmutablePair<String, String>(artist.getName(), album.getAlbumName()));
}
})
.collect(toList());
assertThat(artistAlbum).contains(new ImmutablePair<String, String>("bob", "album1"), new ImmutablePair<String, String>("tom", "album1"),
new ImmutablePair<String, String>("bill", "album2"), new ImmutablePair<String, String>("tom", "album2"));
}
@Test
public void givenAListOfAlbums_whenFlatMap_thenGetListOfArtistAlbumjPairsBelowGivenCost() {
int upperCost = 9;
List<Pair<String, String>> artistAlbum = albums.stream()
.flatMap(album -> album.getArtists()
.stream()
.filter(artist -> upperCost > album.getAlbumCost())
.map(artist -> new ImmutablePair<String, String>(artist.getName(), album.getAlbumName())))
.collect(toList());
assertTrue(artistAlbum.isEmpty());
}
@Test
public void givenAListOfAlbums_whenMapMulti_thenGetListOfArtistAlbumPairsBelowGivenCost() {
int upperCost = 9;
List<Pair<String, String>> artistAlbum = albums.stream()
.<Pair<String, String>> mapMulti((album, consumer) -> {
if (album.getAlbumCost() < upperCost) {
for (Artist artist : album.getArtists()) {
consumer.accept(new ImmutablePair<String, String>(artist.getName(), album.getAlbumName()));
}
}
})
.collect(toList());
assertTrue(artistAlbum.isEmpty());
}
@Test
public void givenAListOfAlbums_whenMapMulti_thenGetPairsOfArtistMajorLabelsUsingMethodReference() {
List<Pair<String, String>> artistLabels = albums.stream()
.mapMulti(Album::artistAlbumPairsToMajorLabels)
.collect(toList());
assertThat(artistLabels).contains(new ImmutablePair<String, String>("bob:album1", "label1,label3"), new ImmutablePair<String, String>("tom:album1", "label2,label3"),
new ImmutablePair<String, String>("bill:album2", "label2,label3"), new ImmutablePair<String, String>("tom:album2", "label2,label4"));
}
}