我正在尝试生成整数对 - 我有一个类配对一个构造函数需要2个整数。以下代码有效,但看起来相当笨重 - 特别是使用mapToObj(Integer :: new)从intStream转换为对象流。
private static List<Pair> success() {
return IntStream.range(0, 10).
mapToObj(Integer::new).flatMap(i -> IntStream.range(12, 15).
mapToObj(j -> new Pair(i, j))).
collect(Collectors.toList());
}
首先,是否有人有更优雅的方式来做这件事?
其次,当我重构提取某些流作为变量时,我收到一个错误:IllegalStateException:stream已经被操作或关闭。这是重构的方法 - 有人知道这是代码的问题吗?
static List<Pair> fail() {
Stream<Integer> outer = IntStream.range(0, 10).mapToObj(Integer::new);
IntStream inner = IntStream.range(12, 15);
Stream<Pair> pairStream = outer.flatMap(i ->
inner.mapToObj(j -> new Pair(i, j)));
return pairStream.collect(Collectors.toList());
}
答案 0 :(得分:3)
通过将mapToObj(Integer::new)
替换为boxed
,可以使其更简洁 - 但除此之外,Java并不简洁:
IntStream.range(0, 10)
.boxed()
.flatMap(i -> IntStream.range(12, 15)
.mapToObj(j -> new Pair(i, j)))
.collect(Collectors.toList());
至于第二个问题:还有其他答案可以解决问题。具体问题是inner
不会被使用一次,而是每次使用外flatMap()
。
这种方式有效:
final IntStream range = IntStream.range(0, 10);
List<Pair> ps = range
.boxed().flatMap(i -> {
final IntStream range1 = IntStream.range(12, 15);
return range1.
mapToObj(j -> new Pair<>(i, j));
}).
collect(Collectors.toList());
答案 1 :(得分:1)
为什么不使用普通for
- 循环?普通for
- 循环将:
static List<Pair> fail() {
List<Pair> pairs = new ArrayList<>(30);
for (int i = 0; i < 10; i++) {
for (int j = 12; j < 15; j++) {
pairs.add(new Pair(i, j));
}
}
return pairs;
}
答案 2 :(得分:0)
如果您的Pair
类接受原始注入,则可以通过这种方式消除不必要的装箱:
private static List<Pair> success() {
return IntStream.range(0, 10).
mapToObj(i -> IntStream.range(12, 15).
mapToObj(j -> new Pair(i, j))).
flatMap(Function.identity()).
collect(Collectors.toList());
}
至于将流提取为变量,您可以改为创建供应商:
private static List<Pair> success() {
Supplier<IntStream> inner = () -> IntStream.range(12, 15);
return IntStream.range(0, 10).
mapToObj(i -> inner.get().
mapToObj(j -> new Pair(i, j))).
flatMap(Function.identity()).
collect(Collectors.toList());
}
虽然我似乎没有必要将流提取到变量中。