michaelsnowden michaelsnowden - 5 months ago 20
Java Question

Java 8 reduce list to linkedlist

My problem basically boils down to reducing a

List
into a linked list, but the inferred types from the reduce function don't seem right.

My list will look like this

[0, 1, 2]


I expect the reduce function to do this at each reduce step

null // identity (a Node)
Node(0, null) // Node a = null, int b = 0
Node(1, Node(0, null)) // Node a = Node(0, null), int b = 1
Node(2, Node(1, Node(0, null))) // Node a = Node(1, Node(0, null)), int b = 2


However, the reduce function seems to think that this won't work because I guess it doesn't think the identity is a Node.

Here is my code.

import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.IntStream;

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

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

static Node reverse(List<Integer> list) {
return list.stream()
.reduce(null, (a, b) -> new Node(b, a)); // error: thinks a is an integer
}

void run() {
List<Integer> list = IntStream.range(0, 3)
.boxed()
.collect(Collectors.toList());
Node reversed = reverse(list);
}

public static void main(String[] args) {
new Example().run();
}
}


What am I doing wrong?

Answer

You can use the other reduce operator, doing

    static Node reverse(List<Integer> list) {
      return list.stream()
        .reduce(
          (Node) null, //the empty element
          (n, i) -> new Node(i, n) , //combining a Node and an Integer
          (n1, n2) -> new Node(n1.value, n2)); // combining two Nodes
}