我目前正在阅读一本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已经非常简单了,我觉得我似乎理解了书中的所有理论,但也许我误解了什么?我想知道我在这里错过了什么?
最后一个部分称为组合器,如果流
是并行的,它就很有用。
它将创建最终需要放在一起的多个中间结果。这正是这个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))
我试图收集一个列表的结果,并将它们组织成一个地图,其中的值是一个地图: 我得到错误,因为对于列表中的不同值是相同的。 映射中包含的值应为: 当我尝试会删除其中一个条目