Skip to content

Instantly share code, notes, and snippets.

@clementi
Last active November 2, 2018 22:31
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save clementi/040afa3dcdcb948a089ffb0901596790 to your computer and use it in GitHub Desktop.
Save clementi/040afa3dcdcb948a089ffb0901596790 to your computer and use it in GitHub Desktop.
Recursive Linked List in Java. Adapted from the Haskell solution at https://exercism.io/my/solutions/63511eb9ae984d599e05bc9c635c405f
package com.tenfactorial.collections;
import java.util.ArrayList;
import java.util.List;
public class EmptyList<T> extends LinkedList<T> {
@Override
public T datum() {
return null;
}
@Override
public boolean isNil() {
return true;
}
@Override
public LinkedList<T> next() {
return null;
}
@Override
public LinkedList<T> reverse() {
return LinkedList.createNil();
}
@Override
public List<T> toList() {
return new ArrayList<>();
}
}
package com.tenfactorial.collections;
import java.util.List;
public abstract class LinkedList<T> {
public abstract T datum();
public abstract boolean isNil();
public abstract LinkedList<T> next();
public abstract LinkedList<T> reverse();
public abstract List<T> toList();
static <T> LinkedList<T> create(T datum, LinkedList<T> tail) {
return new ListNode<>(datum, tail);
}
static <T> LinkedList<T> fromList(List<T> list) {
if (list.isEmpty()) {
return createNil();
}
return new ListNode<>(list.get(0), fromList(list.subList(1, list.size())));
}
static <T> LinkedList<T> createNil() {
return new EmptyList<>();
}
}
package com.tenfactorial.collections;
import java.util.ArrayList;
import java.util.List;
public class ListNode<T> extends LinkedList<T> {
private final T datum;
private LinkedList<T> tail;
ListNode(T datum, LinkedList<T> tail) {
this.datum = datum;
this.tail = tail;
}
@Override
public T datum() {
return this.datum;
}
@Override
public boolean isNil() {
return false;
}
@Override
public LinkedList<T> next() {
return this.tail;
}
@Override
public LinkedList<T> reverse() {
return rev(this, new EmptyList<>());
}
private static <T> LinkedList<T> rev(LinkedList<T> list, LinkedList<T> acc) {
if (list.isNil()) {
return acc;
}
return rev(list.next(), LinkedList.create(list.datum(), acc));
}
@Override
public List<T> toList() {
List<T> list = new ArrayList<>();
list.add(this.datum);
list.addAll(this.tail.toList());
return list;
}
}
package com.tenfactorial.collections;
import java.util.Arrays;
import static java.lang.System.*;
public class Main {
public static void main(String[] args) {
LinkedList<Integer> xs = LinkedList.create(5, LinkedList.createNil());
LinkedList<Integer> ys = LinkedList.create(3, LinkedList.create(7, LinkedList.createNil()));
out.println(xs.toList());
out.println(ys.toList());
LinkedList<Integer> zs = ListNode.fromList(Arrays.asList(1, 3, 6, -1, 9, 0, 13, 4));
out.println(zs.toList());
out.println(length(zs));
LinkedList<Integer> reversedZs = zs.reverse();
out.println(reversedZs.toList());
LinkedList<Integer> ws = LinkedList.create(11, ys);
out.println(ws.toList());
out.println(sum(ws));
}
private static <T> int length(LinkedList<T> list) {
if (list.isNil()) {
return 0;
}
return 1 + length(list.next());
}
private static int sum(LinkedList<Integer> list) {
if (list.isNil()) {
return 0;
}
return list.datum() + sum(list.next());
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment