在Java8中使用flatMap()

时间:2017-02-20 13:17:30

标签: java-8 java-stream flatmap

我有一个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"))));

我们希望没有来自&#34;加尔各答&#34;的单一实体。使用外部迭代我们可以有以下解决方案:

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

4 个答案:

答案 0 :(得分:3)

您的外部循环会计算频段来自from mpl_toolkits.mplot3d import Axes3D import matplotlib.pyplot as plt import numpy as np fig = plt.figure() ax = fig.add_subplot(111, projection='3d') x, y = np.random.rand(2, 100) * 4 hist, xedges, yedges = np.histogram2d(x, y, bins=4, range=[[0, 4], [0, 4]]) # Construct arrays for the anchor positions of the 16 bars. # Note: np.meshgrid gives arrays in (ny, nx) so we use 'F' to flatten xpos, # ypos in column-major order. For numpy >= 1.7, we could instead call meshgrid # with indexing='ij'. xpos, ypos = np.meshgrid(xedges[:-1] + 0.25, yedges[:-1] + 0.25) xpos = xpos.flatten('F') ypos = ypos.flatten('F') # z position set to zero zpos = np.zeros_like(xpos) # Construct arrays with the dimensions for the 16 bars. dx = 0.5 * np.ones_like(zpos) dy = dx.copy() dz = hist.flatten() # Create a random second histogram dz2 = dz * np.random.rand(16) # Set z position to the values of the first histogram zpos2 = dz ax.bar3d(xpos, ypos, zpos, dx, dy, dz, color='b', zsort='average', alpha=0.7) ax.bar3d(xpos, ypos, zpos2, dx, dy, dz2, color='r', zsort='average', alpha=0.7) plt.show() 的成员数。如果你真的想要那个:

Kolkata

答案 1 :(得分:1)

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

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

两个解决方案之间的差异是我flattened之前的列表filtering并使用long count();而不是reduce()。 以后的解决方案是做什么的,它检查来自origin的{​​{1}}而不是Stream<Artist> members的{​​{1}}。希望这有帮助。 如果有人能讨论优化的解决方案,我将不胜感激。

答案 2 :(得分:0)

Sum the counts of the streams in an LongStream:

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

答案 3 :(得分:0)

也检查此解决方案。也可能发生形成特定地点的乐队的乐队成员可能不是来自同一地点。所以确切的解决方案是:

long totalMember = artists.stream().filter(a -> a.getOrigin().equals("Kolkata"))
                            .flatMap(a -> a.getMembers())
                            .filter(a -> a.getOrigin().equals("Kolkata"))
                            .count();
相关问题