映射流的第一个元素与休息不同

时间:2018-03-23 18:13:41

标签: java-8 java-stream

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));

4 个答案:

答案 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();