在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上发现的大多数信息都指向“更简单”的教程。
答案 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
次重复后截断它。