Java 8 reduce list to linkedlist

michaelsnowden

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?

EDIT After the accepted answer, my code looks like this:

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;
        }

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

    static Node reverse(List<Integer> list) {
        return list.stream()
                .reduce(null, (n, i) -> {
                    System.out.println("Will happen"); // to demonstrate that this is called
                    return new Node(i, n);
                }, (n1, n2) -> {
                    System.out.println("Won't happen"); // and this never is
                    return new Node(n1.value, n2);
                });
    }

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

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

And it now prints

Will happen
Will happen
Will happen
Node{value=2, next=Node{value=1, next=Node{value=0, next=null}}}

I still don't know why Java can't tell that third argument to the reduce function is unnecessary and it will never get called, but that's a question for another day.

Second Edit

It's possible to just create a new method for reduce operations like this because the third argument to reduce can just be a function that does nothing.

static <T, U> U reduce(Stream<T> stream, U identity, BiFunction<U, ? super T, U> accumulator) {
    return stream.reduce(identity, accumulator, (a, b) -> null);
}

static Node reverse(List<Integer> list) {
    return reduce(list.stream(), null, (n, i) -> new Node(i, n));
}
CoronA

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)); // could be anything
    }

Edit: To make it work with parallelStream:

    public static Node merge(Node n1, Node n2) {
        if (n1 == null) {
            return n2;
        } else {
            return new Node(n1.value, merge(n1.next, n2));
        }
    }

    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) -> merge(n1, n2)); // combining two Nodes
    }

Collected from the Internet

Please contact [email protected] to delete if infringement.

edited at
0

Comments

0 comments
Login to comment

Related

From Dev

Java 8 reduce list to linkedlist

From Java

Reduce the size of list with Java 8 stream

From Dev

Reduce the size of list with Java 8 stream

From Java

Reduce elements in a java list using Java8 streams

From Dev

Java 8 streams reduce and combine List items to Map

From Dev

Grouping list of objects and reduce subgroups into different objects in Java 8

From Dev

Java8: Reduce list of elements like sql group by

From Dev

How to reduce on groups and return a sorted list with the Java 8 Stream API

From Dev

How to create a list of String from a list of Object using reduce in Java 8?

From Dev

How to create a list of String from a list of Object using reduce in Java 8?

From Dev

java 8 reduce with parallelStream and stream

From Dev

Java 8 collect vs reduce

From Java

Is there a Java LinkedList method to use as a ring list?

From Dev

Java LinkedList: uses both List and Queue interface?

From Dev

Java 8/JDK8 Stream's functions Map/Reduce To group List<String> into Map<String, List<String>>

From Dev

reduce() operation on stream seems to be modifying the source of data (list) Stream API Java 8

From Dev

Cleaner map reduce with Java 8 and a HashMap

From Java

Java 8 Streams - collect vs reduce

From Dev

Java 8 reduce BinaryOperator what is used for?

From Dev

Reduce from array of integers to double in java 8

From Dev

Java 8 compiler bug with Stream and reduce

From Dev

java 8 reduce accumulator return type

From Dev

How to reference the result of reduce() operation in Java 8?

From Dev

Java 8 Map Reduce on HashMap as lambda

From Dev

Best way of chaining reduce with Java 8

From Dev

java8 reduce with useless combiner

From Dev

How to reduce list to map with Java functional API

From Dev

Java - return a reference to a specific place in a linkedlist with list iterator

From Dev

Java - return a reference to a specific place in a linkedlist with list iterator

Related Related

  1. 1

    Java 8 reduce list to linkedlist

  2. 2

    Reduce the size of list with Java 8 stream

  3. 3

    Reduce the size of list with Java 8 stream

  4. 4

    Reduce elements in a java list using Java8 streams

  5. 5

    Java 8 streams reduce and combine List items to Map

  6. 6

    Grouping list of objects and reduce subgroups into different objects in Java 8

  7. 7

    Java8: Reduce list of elements like sql group by

  8. 8

    How to reduce on groups and return a sorted list with the Java 8 Stream API

  9. 9

    How to create a list of String from a list of Object using reduce in Java 8?

  10. 10

    How to create a list of String from a list of Object using reduce in Java 8?

  11. 11

    java 8 reduce with parallelStream and stream

  12. 12

    Java 8 collect vs reduce

  13. 13

    Is there a Java LinkedList method to use as a ring list?

  14. 14

    Java LinkedList: uses both List and Queue interface?

  15. 15

    Java 8/JDK8 Stream's functions Map/Reduce To group List<String> into Map<String, List<String>>

  16. 16

    reduce() operation on stream seems to be modifying the source of data (list) Stream API Java 8

  17. 17

    Cleaner map reduce with Java 8 and a HashMap

  18. 18

    Java 8 Streams - collect vs reduce

  19. 19

    Java 8 reduce BinaryOperator what is used for?

  20. 20

    Reduce from array of integers to double in java 8

  21. 21

    Java 8 compiler bug with Stream and reduce

  22. 22

    java 8 reduce accumulator return type

  23. 23

    How to reference the result of reduce() operation in Java 8?

  24. 24

    Java 8 Map Reduce on HashMap as lambda

  25. 25

    Best way of chaining reduce with Java 8

  26. 26

    java8 reduce with useless combiner

  27. 27

    How to reduce list to map with Java functional API

  28. 28

    Java - return a reference to a specific place in a linkedlist with list iterator

  29. 29

    Java - return a reference to a specific place in a linkedlist with list iterator

HotTag

Archive