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

Java 使用流API返回一定数量的枚举值,java,enums,java-8,java-stream,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 {

使用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;
        }
    }
}
我想做一些类似的事情,并返回以下列表:

[值_1,值_1,值_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;
}
List createEnumList(){
列表=新的ArrayList();
对于(Y:Y.values()){
for(int i=0;i

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

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

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

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

List<Y> createEnumList() {
    return EnumSet.allOf(Y.class).stream()
        .flatMap(y->Collections.nCopies(y.getI(), y).stream())
        .collect(Collectors.toList());
}
List createEnumList(){
返回EnumSet.allOf(Y.class).stream()
.flatMap(y->Collections.nCopies(y.getI(),y.stream())
.collect(Collectors.toList());
}
我会做这项工作的。

你可以做

return Stream.of(Y.values())
             .flatMap(y -> Stream.generate(() -> y).limit(y.getI()))
             .collect(Collectors.toList())
但这是否比“旧式”的方式更具可读性还是个意见问题

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

您可以这样做

return Stream.of(Y.values())
             .flatMap(y -> Stream.generate(() -> y).limit(y.getI()))
             .collect(Collectors.toList())
但这是否比“旧式”的方式更具可读性还是个意见问题

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

您随时可以这样做

List<Y> createEnumList() {
    return Stream.of(Y.values())
                 .flatMap(y -> IntStream.range(0, y.getI()).mapToObj(i -> y))
                 .collect(toList());
}
List createEnumList(){
返回流.of(Y.values())
.flatMap(y->IntStream.range(0,y.getI()).mapToObj(i->y))
.collect(toList());
}
虽然你的要求有点奇怪

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

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

您随时可以这样做

List<Y> createEnumList() {
    return Stream.of(Y.values())
                 .flatMap(y -> IntStream.range(0, y.getI()).mapToObj(i -> y))
                 .collect(toList());
}
List createEnumList(){
返回流.of(Y.values())
.flatMap(y->IntStream.range(0,y.getI()).mapToObj(i->y))
.collect(toList());
}
虽然你的要求有点奇怪

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


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

我不明白这段代码的目的…你可以用流来做,是的,但不是用“更少的代码”我不明白这段代码的目的…你可以用流来做,是的,但不是用“更少的代码”我知道这看起来很奇怪,但这是我想要做的。顺便说一下,除非我导入了错误的
toList()
方法,否则您的代码将返回
List
。@Magnilex它是
java.util.stream.Collectors.toList的静态导入。它应该像预期的那样返回一个
列表
(我已经用IntelliJ对它进行了测试,也许你正在使用Eclipse及其有缺陷的Java8编译器)。你是正确的。事实上,我发现Eclispe现在有相当好的Java8支持,但这是一个令人沮丧的问题。另一个想法获胜的例子。我知道这看起来很奇怪,但这正是我想要做的。顺便说一下,除非我导入了错误的
toList()
方法,否则您的代码将返回
List
。@Magnilex它是
java.util.stream.Collectors.toList的静态导入。它应该像预期的那样返回一个
列表
(我已经用IntelliJ对它进行了测试,也许你正在使用Eclipse及其有缺陷的Java8编译器)。你是正确的。事实上,我发现Eclispe现在有相当好的Java8支持,但这是一个令人沮丧的问题。创意胜出的另一个案例。