Моя проблема сводится к уменьшению List
в связанном списке, но выводимые типы из функции уменьшения не кажутся правильными.Java 8 сократите список до связанного списка
Мой список будет выглядеть следующим образом
[0, 1, 2]
Я ожидаю снижения функции, чтобы сделать это на каждом уменьшить шаг
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
Однако функция снижения, кажется, думает, что это не будет работать потому что я думаю, он не считает, что личность - это Узел.
Вот мой код.
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();
}
}
Что я делаю неправильно?
EDIT После принятого ответа, мой код выглядит следующим образом:
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();
}
}
И теперь печатает
Will happen
Will happen
Will happen
Node{value=2, next=Node{value=1, next=Node{value=0, next=null}}}
Я до сих пор не знаю, почему Java не могу сказать, что третий аргумент функции сокращения не нужен, и он никогда не будет вызван, но это вопрос на другой день.
Второй Редактировать
Можно просто создать новый метод для уменьшения операций, как это потому, что третий аргумент для снижения может быть просто функция, которая ничего не делает.
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));
}
Почему бы не использовать ' собирать' вместо 'сокращения'? 'collect' более подходит для создания коллекции из потока. – Eran
@Eran Мне не понравилось, что мне потребовалось реализовать 3 метода – michaelsnowden
@michaelsnowden Попробуйте запустить «Стрим» параллельно, тогда вам понадобится объединитель. – Flown