Java8中flatMap()的用法

问题描述 投票:2回答:4

我的Artist课程如下:

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。现在列表如下:

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"))));

我们希望没有来自“加尔各答”的单个实体。 使用外部迭代,我们可以有以下解决方案:

int totalMembers = 0;
for (Artist artist : artists) {
    if(artist.getOrigin().equals("Kolkata") {
        Stream<Artist> members = artist.getMembers();
        totalMembers += members.count();
    }
} 

在Lambda-Expression的帮助下使用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);
java-8 java-stream flatmap
4个回答
3
投票

您的外部循环会计算拥有来自Kolkata的乐队的成员数量。 如果您确实想要:

long result = artists.stream().filter(a -> a.getOrigin().equals("Kolkata"))
            .filter(a -> a.getMembers() != null)
            .flatMap(a -> a.getMembers())
            .count();

1
投票

您的解决方案将给出预期的输出,即11 。 您也可以使用:

int totalMembers = (int) artists.stream()
                                .flatMap(d->d.getMembers())
                                .filter(d->d.getOrigin().equals("Kolkata"))
                                .count();

两种解决方案之间的区别在于,在filtering列表之前我先将其展flattened ,并使用了long count(); 而不是reduce() 。 以后有什么解决方案确实是,它会检查originStream<Artist> members ,而不是originartists 。 希望能有所帮助。 如果有人可以讨论优化的解决方案,我将不胜感激。


0
投票

LongStream中的流计数LongStream

long totalMember = artists.stream()
                          .filter(d -> d.getOrigin().equals("Kolkata"))
                          .map(Artist::getMembers)
                          .filter(m -> m != null)
                          .mapToInt(Stream::count)
                          .sum();

0
投票

也检查此解决方案。 也可能发生的情况是,组成特定位置的乐队的乐队成员可能不是来自同一位置。 因此,确切的解决方案将是:

long totalMember = artists.stream().filter(a -> a.getOrigin().equals("Kolkata"))
                            .flatMap(a -> a.getMembers())
                            .filter(a -> a.getOrigin().equals("Kolkata"))
                            .count();
© www.soinside.com 2019 - 2024. All rights reserved.