gpt4 book ai didi

java - 使用 map().reduce() 初始化链表节点

转载 作者:行者123 更新时间:2023-12-05 03:24:00 25 4
gpt4 key购买 nike

我想使用 Java 流对 Node 类进行初始化。我如何使用 map 和减少流操作来做到这一点?

Node node5 = new Node(5,null);
Node node4 = new Node(4,node5);
Node node3 = new Node(3,node4);
Node node2 = new Node(2,node3);
Node node1 = new Node(1,node2);

我试过这样的东西,它没有编译

Node node = Arrays.stream(new int[]{1,2,3,4,5})
.map((i, n) -> new Node(i, n)
.reduce(null, new SingleList.Node(i, n)));

我想将数组中的每个元素映射到 Node(int i , Node n),然后将其缩减为 Node。我在这里缺少什么?

最佳答案

您可以使用 Stream API 生成链表,特别是 reduce()操作。

但请记住,从本质上讲,这是一种模仿 for 的棘手方法。循环(这将是一个更合适的选择)并且这个流不能并行执行。

为了创建包含所需数量元素的流,无需生成数组然后将其用作流源。相反,我们可以使用 IntStream.range() 创建一个流,需要开始和结束 int值(它仅在 start < end 时有效)或 IntStream.iterate() .

注意 box()需要操作才能转换 IntStream进入对象流,以便访问这种 reduce(identity, accumulator, combiner) 的风格,它允许提供与流中元素类型不同的类型标识。

这种形式的reduce()不适用于 IntStream .

尾节点 应作为reduce()身份 提供。手术。 accumulator 函数负责以相反的顺序(从尾到头)生成链表。作为流管道执行结果返回的节点将是头节点

Combiner 函数,用于组合并行生成的部分结果,抛出 AssertionError因为如果我们允许并行执行,每个线程都将实例化自己的身份(尾节点),这意味着节点将被错误地链接。

int tailValue = 5;
int headValue = 1;

// generating the linked list

Node head = IntStream.range(headValue, tailValue)
.boxed()
.reduce(new Node(tailValue, null),
(Node node, Integer value) -> new Node(node.getValue() - 1, node),
(Node left, Node right) -> {throw new AssertionError("should not be used in parallel");});

// printing the linked list

Node cur = head;
while (cur != null) {
System.out.println(cur);
cur = cur.getNext();
}

输出:

Node { value = 1 }
Node { value = 2 }
Node { value = 3 }
Node { value = 4 }
Node { value = 5 }

A link to the Online Demo

Tried something like this, which does not compile

Node node = Arrays.stream(new int[]{1,2,3,4,5})
.map((i, n) -> new Node(i, n))
.reduce(null, new SingleList.Node(i, n)));

Arrays.stream(new int[]{1,2,3,4,5})将产生 IntStream (不是 Stream )。

操作 map() , 应用于 IntStream , 需要一个 IntUnaryOperator 类型的参数,这是一个接受类型为 int 的单个参数的函数并返回 int

为了将图元流转换为对象流,您应该使用 mapToObj() ,它需要一个 IntFunction (一个接受单个 int 参数并返回一个对象的函数)。

reduce(int identity, IntBinaryOperator combiner) 的形式,可用 IntStream需要原始类型的身份 int ,它的组合器IntBinaryOperator类型的,即需要 int并产生 int .因此,它不会编译。

您的解决方案中还有一个逻辑缺陷 - 您试图为每个 Steam 元素创建一个节点两次:第一次在 map() 中并且比reduce()期间操作,这显然是多余的。

根据文档map()stateless operation它不应该“意识到”之前遇到的元素。这意味着它对生成节点没有帮助,因为它无法提供对下一个节点的引用。


一个假人 Node上面使用的类:

public static class Node {
private int value;
private Node next;

public Node(int value, Node next) {
this.value = value;
this.next = next;
}

public int getValue() {
return value;
}

public Node getNext() {
return next;
}

@Override
public String toString() {
return "Node {" +
" value = " + value + " }";
}
}

关于java - 使用 map().reduce() 初始化链表节点,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/72382410/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com