Java8 中 flatMap() 的使用
Usage of flatMap() in Java8
我有一个 Artist
class 如下:
class Artist {
private final String name;
private final String origin;
private Stream<Artist> members;
public Artist(String name, String origin) {
this.name = name;
this.origin = origin;
this.members = null;
}
public Artist(String name, String origin,Stream<Artist> members) {
this.name = name;
this.origin = origin;
this.members = members;
}
public String getName() {
return name;
}
public String getOrigin() {
return origin;
}
public Stream<Artist> getMembers() {
return members;
}
@Override
public String toString() {
return name;
}
}
现在我们创建一个艺术家列表,其中艺术家的名字是一个乐队或一个实体。对于单个实体 "members"
属性保持 null.Now 列表如下:
List<Artist> artists = Arrays.asList(
new Artist("Fossils","Kolkata", Stream.of(new Artist("Rupam Islam","Kolkata"), new Artist("Deep","Kolkata"),new Artist("Allan","Kolkata"), new Artist("Chandramouli","Kolkata"),new Artist("Tanmoy","Kolkata"))),
new Artist("Linkin Park","California",Stream.of(new Artist("Chester Bennington","California"),new Artist("Dave Farrell","California"), new Artist("Mike Shinoda","California"),new Artist("Rob Bourdon","California"),new Artist("Brad Delson","California"))),
new Artist("Cactus","Kolkata",Stream.of(new Artist("Sidhartha Sankar","Kolkata"),new Artist("Dibyendu Mukherjee","Kolkata"), new Artist("Ritaprabha","Kolkata"),new Artist("Sudipto","Kolkata"),new Artist("Mainak","Kolkata"))),
new Artist("Backstreet Boys","Florida",Stream.of(new Artist("A. J. McLean","Florida"),new Artist("Howie D.","Florida"),new Artist("Nick Carter","Florida"), new Artist("Kevin Richardson","Florida"), new Artist("Brian Littrell","Florida"))),
new Artist("Prohori","Kolkata",Stream.of(new Artist("Pritam","Kolkata"))));
我们不希望有来自 "Kolkata" 的单个实体。使用外部迭代我们可以得到以下解决方案:
int totalMembers = 0;
for (Artist artist : artists) {
if(artist.getOrigin().equals("Kolkata") {
Stream<Artist> members = artist.getMembers();
totalMembers += members.count();
}
}
在 Lambda 表达式的帮助下使用 stream()
和 flatMap()
进行内部迭代的解决方案是什么?
我想到了一个解决方案,但可能不正确。
int totalMember = artists.stream()
.filter(d -> d.getOrigin().equals("Kolkata"))
.flatMap(e -> e.getMembers())
.map(f -> 1).reduce(0, (a, b) -> a + b);
将 LongStream
中的流计数相加:
long totalMember = artists.stream()
.filter(d -> d.getOrigin().equals("Kolkata"))
.map(Artist::getMembers)
.filter(m -> m != null)
.mapToInt(Stream::count)
.sum();
您的解决方案将给出预期的输出,即 11。您也可以使用 :
int totalMembers = (int) artists.stream()
.flatMap(d->d.getMembers())
.filter(d->d.getOrigin().equals("Kolkata"))
.count();
两种解决方案的区别在于我在 filtering
之前有 flattened
列表,并使用 long count();
而不是 reduce()
。
后来的解决方案是,它检查 Stream<Artist> members
中的 origin
而不是 artists
中的 origin
。希望这有帮助。
如果有人可以讨论优化的解决方案,我将不胜感激。
您的外部循环计算拥有来自 Kolkata
的乐队的成员数量。如果你真的想要那个:
long result = artists.stream().filter(a -> a.getOrigin().equals("Kolkata"))
.filter(a -> a.getMembers() != null)
.flatMap(a -> a.getMembers())
.count();
也检查这个解决方案。也可能发生这样的情况,即组成特定地区乐队的乐队成员可能不是来自同一地区。所以确切的解决方案是:
long totalMember = artists.stream().filter(a -> a.getOrigin().equals("Kolkata"))
.flatMap(a -> a.getMembers())
.filter(a -> a.getOrigin().equals("Kolkata"))
.count();
我有一个 Artist
class 如下:
class Artist {
private final String name;
private final String origin;
private Stream<Artist> members;
public Artist(String name, String origin) {
this.name = name;
this.origin = origin;
this.members = null;
}
public Artist(String name, String origin,Stream<Artist> members) {
this.name = name;
this.origin = origin;
this.members = members;
}
public String getName() {
return name;
}
public String getOrigin() {
return origin;
}
public Stream<Artist> getMembers() {
return members;
}
@Override
public String toString() {
return name;
}
}
现在我们创建一个艺术家列表,其中艺术家的名字是一个乐队或一个实体。对于单个实体 "members"
属性保持 null.Now 列表如下:
List<Artist> artists = Arrays.asList(
new Artist("Fossils","Kolkata", Stream.of(new Artist("Rupam Islam","Kolkata"), new Artist("Deep","Kolkata"),new Artist("Allan","Kolkata"), new Artist("Chandramouli","Kolkata"),new Artist("Tanmoy","Kolkata"))),
new Artist("Linkin Park","California",Stream.of(new Artist("Chester Bennington","California"),new Artist("Dave Farrell","California"), new Artist("Mike Shinoda","California"),new Artist("Rob Bourdon","California"),new Artist("Brad Delson","California"))),
new Artist("Cactus","Kolkata",Stream.of(new Artist("Sidhartha Sankar","Kolkata"),new Artist("Dibyendu Mukherjee","Kolkata"), new Artist("Ritaprabha","Kolkata"),new Artist("Sudipto","Kolkata"),new Artist("Mainak","Kolkata"))),
new Artist("Backstreet Boys","Florida",Stream.of(new Artist("A. J. McLean","Florida"),new Artist("Howie D.","Florida"),new Artist("Nick Carter","Florida"), new Artist("Kevin Richardson","Florida"), new Artist("Brian Littrell","Florida"))),
new Artist("Prohori","Kolkata",Stream.of(new Artist("Pritam","Kolkata"))));
我们不希望有来自 "Kolkata" 的单个实体。使用外部迭代我们可以得到以下解决方案:
int totalMembers = 0;
for (Artist artist : artists) {
if(artist.getOrigin().equals("Kolkata") {
Stream<Artist> members = artist.getMembers();
totalMembers += members.count();
}
}
在 Lambda 表达式的帮助下使用 stream()
和 flatMap()
进行内部迭代的解决方案是什么?
我想到了一个解决方案,但可能不正确。
int totalMember = artists.stream()
.filter(d -> d.getOrigin().equals("Kolkata"))
.flatMap(e -> e.getMembers())
.map(f -> 1).reduce(0, (a, b) -> a + b);
将 LongStream
中的流计数相加:
long totalMember = artists.stream()
.filter(d -> d.getOrigin().equals("Kolkata"))
.map(Artist::getMembers)
.filter(m -> m != null)
.mapToInt(Stream::count)
.sum();
您的解决方案将给出预期的输出,即 11。您也可以使用 :
int totalMembers = (int) artists.stream()
.flatMap(d->d.getMembers())
.filter(d->d.getOrigin().equals("Kolkata"))
.count();
两种解决方案的区别在于我在 filtering
之前有 flattened
列表,并使用 long count();
而不是 reduce()
。
后来的解决方案是,它检查 Stream<Artist> members
中的 origin
而不是 artists
中的 origin
。希望这有帮助。
如果有人可以讨论优化的解决方案,我将不胜感激。
您的外部循环计算拥有来自 Kolkata
的乐队的成员数量。如果你真的想要那个:
long result = artists.stream().filter(a -> a.getOrigin().equals("Kolkata"))
.filter(a -> a.getMembers() != null)
.flatMap(a -> a.getMembers())
.count();
也检查这个解决方案。也可能发生这样的情况,即组成特定地区乐队的乐队成员可能不是来自同一地区。所以确切的解决方案是:
long totalMember = artists.stream().filter(a -> a.getOrigin().equals("Kolkata"))
.flatMap(a -> a.getMembers())
.filter(a -> a.getOrigin().equals("Kolkata"))
.count();