我正在尝试生成整数对-我有一个类对,其中一个构造函数接受2个整数。以下代码可以工作,但看起来相当笨拙-特别是使用mapToObj( intStream::new)将整数转换为对象流。
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());
}发布于 2015-08-05 01:28:59
用boxed替换mapToObj(Integer::new)可以让它更简洁一些--但除此之外,boxed并不是那么简洁:
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());发布于 2015-08-05 01:00:41
为什么不使用普通的for-loops?普通for-loops将:
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;
}发布于 2015-08-05 13:56:10
如果您的Pair类接受原语int,则可以通过以下方式消除不必要的装箱:
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());
}尽管我似乎没有必要将流提取到变量中。
https://stackoverflow.com/questions/31814641
复制相似问题