使用流API返回一定数量的枚举值

时间:2015-04-10 13:03:11

标签: java enums java-8 java-stream

在Java 8中使用流API,下面的createObjects()将返回一行中X个对象的列表。

public class StreamObjectCreator {

    public List<X> createObjects(Integer... s) {
        return Arrays.stream(s).map(X::new).collect(Collectors.toList());
    }

    private static class X {
        int s;
        public X(int s) {
            this.s = s;
        }
    }
}

现在,请考虑以下枚举Y

private static enum Y {

    VALUE_1(2), VALUE_2(1);

    private int i;

    private Y(int i) {
        this.i = i;
    }

    public int getI() {
        return i;
    }

}

我想做类似的事情并返回以下列表:

  

[VALUE_1,VALUE_1,VALUE_2]

换句话说,i出现每个枚举值。

使用“旧”Java方式,可以像这样实现。

List<Y> createEnumList() {
    List<Y> list = new ArrayList<Y>();
    for (Y y : Y.values()) {
        for (int i = 0; i < y.getI(); i++) {
            list.add(y);
        }
    }
    return list;
}

使用流API或一些lambda表达式可以用更少的样板代码完成吗?我在流API上玩了一段时间没有成功,Google上发现的大多数信息都指向“更简单”的教程。

3 个答案:

答案 0 :(得分:7)

我无法想象一个真实的用例,但

List<Y> createEnumList() {
    return EnumSet.allOf(Y.class).stream()
        .flatMap(y->Collections.nCopies(y.getI(), y).stream())
        .collect(Collectors.toList());
}

将完成这项工作。

答案 1 :(得分:4)

你可以随时

List<Y> createEnumList() {
    return Stream.of(Y.values())
                 .flatMap(y -> IntStream.range(0, y.getI()).mapToObj(i -> y))
                 .collect(toList());
}

虽然您的要求有点奇怪。

Stream.of将创建一个Stream<Y>,您可以从中将每个Y实例映射到包含此实例n的流,n为getId()值。然后将此Stream<Stream<Y>>展平,以便您返回Stream<Y>

最后,您在列表中收集管道的内容。

答案 2 :(得分:2)

你可以做到

return Stream.of(Y.values())
             .flatMap(y -> Stream.generate(() -> y).limit(y.getI()))
             .collect(Collectors.toList())

但这是一个意见问题,这是否比旧式&#34;更具可读性?方式...

Stream.generate(() -> y).limit(y.getI())

创建一个潜在无限的y值流,然后在i次重复后截断它。