首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用Java8 Streams从另外两个列表创建对象列表

使用Java8 Streams从另外两个列表创建对象列表
EN

Stack Overflow用户
提问于 2014-04-08 17:44:21
回答 3查看 42.2K关注 0票数 17

我有以下Java6和Java8代码:

代码语言:javascript
复制
List<ObjectType1> lst1 = // a list of ObjectType1 objects
List<ObjectType2> lst2 = // a list of ObjectType1 objects, same size of lst1

List<ObjectType3> lst3 = new ArrayLis<ObjectType3>(lst1.size());
for(int i=0; i < lst1.size(); i++){
  lst3.add(new ObjectType3(lst1.get(i).getAVal(), lst2.get(i).getAnotherVal()));
}

在Java8中,有没有办法使用Lambda以更简洁的方式处理前面的for?

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2014-04-08 17:47:12

一个Stream绑定到一个给定的iterable/Collection,所以你不能真正并行地“迭代”两个集合。

一种解决方法是创建一个索引流,但它不一定比for循环有所改善。流版本可能如下所示:

代码语言:javascript
复制
List<ObjectType3> lst3 = IntStream.range(0, lst1.size())
         .mapToObj(i -> new ObjectType3(lst1.get(i).getAVal(), lst2.get(i).getAnotherVal()))
         .collect(toList());
票数 29
EN

Stack Overflow用户

发布于 2014-04-08 19:43:07

您可以创建一个将两个集合转换为新集合的方法,如下所示:

代码语言:javascript
复制
public <T, U, R> Collection<R> singleCollectionOf(final Collection<T> collectionA, final Collection<U> collectionB, final Supplier<Collection<R>> supplier, final BiFunction<T, U, R> mapper) {
    if (Objects.requireNonNull(collectionA).size() != Objects.requireNonNull(collectionB).size()) {
        throw new IllegalArgumentException();
    }
    Objects.requireNonNull(supplier);
    Objects.requireNonNull(mapper);
    Iterator<T> iteratorA = collectionA.iterator();
    Iterator<U> iteratorB = collectionB.iterator();
    Collection<R> returnCollection = supplier.get();
    while (iteratorA.hasNext() && iteratorB.hasNext()) {
        returnCollection.add(mapper.apply(iteratorA.next(), iteratorB.next()));
    }
    return returnCollection;
}

这里最重要的部分是,它将把获得的iteratorA.next()iteratorB.next()映射到一个新对象中。

名字是这样的:

代码语言:javascript
复制
List<Integer> list1 = IntStream.range(0, 10).boxed().collect(Collectors.toList());
List<Integer> list2 = IntStream.range(0, 10).map(n -> n * n + 1).boxed().collect(Collectors.toList());
singleCollectionOf(list1, list2, ArrayList::new, Pair::new).stream().forEach(System.out::println);

在您的示例中,它将是:

代码语言:javascript
复制
List<ObjectType3> lst3 = singleCollectionOf(lst1, lst2, ArrayList::new, ObjectType3::new);

其中,例如,Pair::new是lamdda (t, u) -> new Pair(t, u)的简写。

票数 5
EN

Stack Overflow用户

发布于 2017-02-08 12:05:41

我还没有找到将一个流更新到另一个流的方法,然而,我使用Map完成了一个类似的壮举。:)

代码语言:javascript
复制
    Map<Integer, String> result = new HashMap<>();
    for(int index = 100; index > 0; index--){
        result.put(index, String.valueOf(index));
    }
    result.keySet().stream()
            .filter(key -> key%3 == 0)
            .sorted()
            .forEach(key -> result.put(key, "Fizz"));

    result.keySet().stream()
            .filter(key -> key%5 == 0)
            .sorted()
            .forEach(key -> result.put(key, "Buzz"));

    result.keySet().stream()
            .filter(key -> key%3 == 0 && key%5 == 0)
            .sorted()
            .forEach(key -> result.put(key, "FizzBuzz"));

    result.keySet().stream().forEach(key -> System.out.println(result.get(key)));
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/22933296

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档