当前位置: 首页 > 知识库问答 >
问题:

仅用reduce和lambdas解释Java流映射函数

马哲
2023-03-14

我目前正在阅读一本Java8Lambdas的书(相当受欢迎),我对其中一个高级问题的答案中的一些语法感到困惑。

问题提出如下问题:

只使用reduce和lambda表达式编写stream函数'map'的实现。您可以返回列表而不是

public static <I, O> List<O> map(Stream<I> stream, Function<I, O> mapper) {
    return stream.reduce(new ArrayList<O>(), (acc, x) -> {
        // We are copying data from acc to new list instance. It is very inefficient,
        // but contract of Stream.reduce method requires that accumulator function does
        // not mutate its arguments.
        // Stream.collect method could be used to implement more efficient mutable reduction,
        // but this exercise asks to use reduce method.
        List<O> newAcc = new ArrayList<>(acc);
        newAcc.add(mapper.apply(x));
        return newAcc;
    }, (List<O> left, List<O> right) -> {
        // We are copying left to new list to avoid mutating it. 
        List<O> newLeft = new ArrayList<>(left);
        newLeft.addAll(right);
        return newLeft;
    });
}
, (List<O> left, List<O> right) -> {
        // We are copying left to new list to avoid mutating it. 
        List<O> newLeft = new ArrayList<>(left);
        newLeft.addAll(right);
        return newLeft;
    });

到目前为止,Java8 lambdas已经非常简单了,我觉得我似乎理解了书中的所有理论,但也许我误解了什么?我想知道我在这里错过了什么?

共有1个答案

包谭三
2023-03-14

最后一个部分称为组合器,如果是并行的,它就很有用。

它将创建最终需要放在一起的多个中间结果。这正是这个lambda正在做的事情。

您可以先执行下面的代码,它将通过您的函数运行一个顺序的。注意我是如何在组合器中添加system.out.println(“combinating...”)的。

public static void main(String[] args) {
    Stream<Integer> boxed = IntStream.rangeClosed(1, 10).limit(25).boxed();
    List<String> map = map(boxed, String::valueOf);
    System.out.println(map);
}

public static <I, O> List<O> map(Stream<I> stream, Function<I, O> mapper) {
    return stream.reduce(new ArrayList<O>(), (acc, x) -> {
        // We are copying data from acc to new list instance. It is very inefficient,
        // but contract of Stream.reduce method requires that accumulator function does
        // not mutate its arguments.
        // Stream.collect method could be used to implement more efficient mutable reduction,
        // but this exercise asks to use reduce method.
        List<O> newAcc = new ArrayList<>(acc);
        newAcc.add(mapper.apply(x));
        return newAcc;
    }, (List<O> left, List<O> right) -> {
        System.out.println("Combining...");
        // We are copying left to new list to avoid mutating it.
        List<O> newLeft = new ArrayList<>(left);
        newLeft.addAll(right);
        return newLeft;
    });
}
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
public static void main(String[] args) {
    Stream<Integer> boxed = IntStream.rangeClosed(1, 10).parallel().limit(25).boxed();
    List<String> map = map(boxed, String::valueOf);
    System.out.println(map);
}
Combining...
Combining...
Combining...
Combining...
Combining...
Combining...
Combining...
Combining...
Combining...
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
 类似资料:
  • 我不熟悉Java8,不知道如何使用流及其排序方法。如果我有下面的映射,那么如何使用Java8按值对该映射进行排序,从而只获取前10个条目。 我知道在Java 8之前,我们可以按以下链接排序:https://stackoverflow.com/a/109389/4315608

  • 1)做这件事的正确方法是什么?我做错了什么? 2)流是线程安全的吗?我正在多线程环境中工作,所以我是否应该使用返回TRAAD安全集合的收集器?

  • 首先,我有下面的发票清单。每个列表对象都有一个零件号、一个描述、数量和一个价格。 我将其映射到数量上,并将其排序到数量上,得到以下结果: 但是我如何在上进行映射,以便在我的结果中显示在所显示的数量前面?我不能这样做:

  • 我有这个简单的Bean类: 在我的主类中,我在列表中添加了一些信息: 现在我想将图书列表转换为以下形式的地图: 因此,输出(上面的地图)如下所示: 因此,我需要按isbn作为关键字和作者作为值对条目进行分组。一个isbn可以有多个作者。 我尝试如下: 不能更改bean的格式。如果bean有字符串值而不是map,我可以这样做,但是要坚持使用map。 我已经写了传统的java 6/7方式来正确地做这件

  • 我对流图法有点困惑。有一些简单的源代码可以运行: map()签名:Stream map(函数 在我的选择中,我认为赋予文字的功能。stream()。map应该有1个参数,但是string::length没有任何输入参数,只返回int。 它看起来像word流调用字符串中的每个元素“word”。长度(),但我不知道该怎么做?为什么string::length签名不需要与函数签名(R apply(T))

  • 我试图收集一个列表的结果,并将它们组织成一个地图,其中的值是一个地图: 我得到错误,因为对于列表中的不同值是相同的。 映射中包含的值应为: 当我尝试会删除其中一个条目