Java的Stream API中是否有一种方法可以不同于其他方式映射流的第一个元素?
此代码的等效项:
List<Bar> barList = new ArrayList<>();
for (int i=0; i<fooList.size(); i++) {
Foo foo = fooList.get(i);
Foo modifiedFoo = foo.getModifiedFoo();
if (i == 0) {
barList.add(new Bar(modifiedFoo, false));
}else {
barList.add(new Bar(modifiedFoo, true));
}
}
Stream<Bar> = barList.stream();
注意:我已经有了一个流设置,我希望在第一次映射后进行一些操作
fooList.stream()
.map(Foo::getModifiedFoo)
.(May be Some operation here to get different new Bar for first modifiedFoo)
.map(modifiedFoo -> new Bar(modifiedFoo, true));
答案 0 :(得分:7)
我会得到第一个元素,从中创建一个let mix = require('laravel-mix');
/*
|--------------------------------------------------------------------------
| Mix Asset Management
|--------------------------------------------------------------------------
|
| Mix provides a clean, fluent API for defining some Webpack build steps
| for your Laravel application. By default, we are compiling the Sass
| file for the application as well as bundling up all the JS files.
|
*/
mix.sass('resources/assets/sass/app.scss', 'public/css');
mix.js('resources/assets/js/app.js', 'public/js').extract(['angular']);
并应用所需的映射。然后,我将使用列表的其余部分,从中创建一个流并应用不同的映射。然后Stream
溪流。像这样:
concat
另一种方法:
Stream<Bar> first = Stream.of(fooList.get(0))
.map(Foo::getModifiedFoo)
.map(modifiedFoo -> new Bar(modifiedFoo, false));
Stream<Bar> others = fooList.subList(1, fooList.size()).stream()
.map(Foo::getModifiedFoo)
.map(modifiedFoo -> new Bar(modifiedFoo, true));
Stream<Bar> bars = Stream.concat(first, others).flatMap(s -> s);
这种方式很简洁,做得很好。
答案 1 :(得分:1)
使用IntStream迭代索引,然后使用mapToObj为该索引创建一个对象,最后收集到一个列表中:
List<Bar> barList = IntStream.range(0, fooList.size())
.mapToObj(i -> (i == 0 ? new Bar (fooList.get(i), false) :
new Bar(fooList.get(i),true)))
.collect(Collectors.toList());
更可读的是,在循环外进行第一项处理,并使用从1开始的IntStream。
以下是使用简单列表的demo。
答案 2 :(得分:1)
我可以提出两种方法,但我发现你的方式更直。
使用IntStream
,例如:
List<Bar> barList = new ArrayList<>();
IntStream.range(0, fooList.size())
.forEach(i->{
if (i == 0) {
barList.add(new Bar(foo, false));
}else {
barList.add(new Bar(foo, true));
}
}
);
它不是一种真正的功能方法(forEach()
使用而不是Collector
),因为它维护了List的当前索引。
作为替代方案,您可以使用更实用的方法,但我也不会发现它更直:
List<Bar> barList = IntStream.range(0, fooList.size())
.mapToObj(i->{
Foo foo = fooList.get(i);
if (i == 0) {
return new Bar(foo, false);
}
return new Bar(foo, true));
})
.collect(Collectors.toList());
答案 3 :(得分:0)
虽然我认为接受的答案更好,但这是另一种方法。
int[] counter = {-1};
Stream<Bar> barListStream = fooList.stream().map(foo -> {
counter[0]++;
return new Bar(mfoo.getModifiedFoo(), counter[0]>0);
}).collect(Collectors.toList()).stream();