1 import java.util.Comparator; 2 import java.util.function.*; 3 4 public final class FList<T> { 5 6 public final T head; 7 public final FList<T> tail; 8 public final int length; 9 public final boolean isEmpty; 10 11 private FList() { 12 head = null; 13 tail = null; 14 isEmpty = true; 15 length = 0; 16 } 17 18 private FList(T i, FList<T> n) { 19 head = i; 20 tail = n; 21 isEmpty = false; 22 length = n.length + 1; 23 } 24 25 public FList<T> add(T item) { 26 return new FList<>(item, this); 27 } 28 29 @SuppressWarnings("unchecked") 30 public FList<T> reverse() { 31 return foldLeft(nil, (x, y) -> x.add(y)); 32 } 33 34 public <U> U foldLeft(U i, BiFunction<U, T, U> f) { 35 return isEmpty ? i : tail.foldLeft(f.apply(i, head), f); 36 } 37 38 public <U> U foldRight(U i, BiFunction<U, T, U> f) { 39 return isEmpty ? i : f.apply(tail.foldRight(i, f), head); 40 } 41 42 @SuppressWarnings("unchecked") 43 public FList<T> filter(Predicate<T> p) { 44 return foldRight(nil, (x, y) -> p.test(y) ? x.add(y) : x); 45 } 46 47 public FList<T> remove(Predicate<T> p) { 48 return filter(p.negate()); 49 } 50 51 public boolean exist(Predicate<T> p) { 52 return !isEmpty && (p.test(head) || tail.exist(p)); 53 } 54 55 public boolean forAll(Predicate<T> p) { 56 return !exist(p.negate()); 57 } 58 59 // x+0 can avoid " Unboxing possibly null value " 60 public int count(Predicate<T> p) { 61 return foldLeft(0, (x, y) -> p.test(y) ? x + 1 : x + 0); 62 } 63 64 public FList<T> merge(FList<T> other) { 65 return other == null || other.isEmpty ? this : other.foldRight(this, (x, y) -> x.add(y)); 66 } 67 68 public FList<T> sort(Comparator<T> c) { 69 return length > 20 ? msort(c) : isort(c); 70 } 71 72 @SuppressWarnings("unchecked") 73 private FList<T> isort(Comparator<T> c) { 74 return isEmpty ? nil : ins(c, head, tail.isort(c)); 75 } 76 77 //not error,just get sublist not change Original FList 78 public FList<T> drop(int n) { 79 return n <= 0 || isEmpty ? this : tail.drop(n - 1); 80 } 81 82 public void foreach(Consumer<T> a) { 83 if (!isEmpty) { 84 a.accept(head); 85 tail.foreach(a); 86 } 87 } 88 89 @SuppressWarnings("unchecked") 90 public <R> FList<R> map(Function<T, R> map) { 91 return foldRight(nil, (x, y) -> x.add(map.apply(y))); 92 } 93 94 public T reduce(T i, BinaryOperator<T> f) { 95 return isEmpty ? i : tail.reduce(f.apply(i, head), f); 96 } 97 98 public static final FList nil = new FList<>(); 99 100 @SuppressWarnings("unchecked") 101 public static <T> FList<T> of(T... args) { 102 return a2f(args, args.length - 1); 103 } 104 105 @SuppressWarnings("unchecked") 106 private static <T> FList<T> a2f(T[] a, int i) { 107 return i < 0 ? nil : new FList<>(a[i], a2f(a, i - 1)); 108 } 109 110 private static <T> FList<T> ins(Comparator<T> c, T h, FList<T> t) { 111 return t.isEmpty || c.compare(h, t.head) > -1 ? t.add(h) : ins(c, h, t.tail).add(t.head); 112 } 113 114 public static <T> FList<T> generate(FList<T> r, Function<FList<T>, T> f, int m) { 115 return m == 1 ? r : generate(new FList<>(f.apply(r), r), f, m - 1); 116 } 117 118 @SuppressWarnings({"unchecked", "empty-statement"}) 119 public static <T> FList<T> iterate(T s, UnaryOperator<T> f, int m) { 120 121 FList<T> n; 122 for (n = FList.of(s); m > 1; m--, s = f.apply(s), n = n.add(s)); 123 return n; 124 } 125 126 private static <T> Couple<FList<T>, FList<T>> split(FList<T> x, FList<T> y, int n) { 127 if (x.isEmpty || n == 0) 128 return Tuple.of(x, y); 129 return split(x.tail, y.add(x.head), n - 1); 130 } 131 132 private static <T> FList<T> merge(FList<T> x, FList<T> y, Comparator<T> c) { 133 if (x.isEmpty) 134 return y; 135 if (y.isEmpty) 136 return x; 137 return c.compare(x.head, y.head) > -1 ? merge(x.tail, y, c).add(x.head) : merge(x, y.tail, c).add(y.head); 138 } 139 140 @SuppressWarnings("unchecked") 141 private FList<T> msort(Comparator<T> c) { 142 int n = length / 2; 143 if (n == 0) 144 return this; 145 else { 146 Couple<FList<T>, FList<T>> p = split(this, nil, n); 147 return merge(p._1.msort(c), p._2.msort(c), c); 148 } 149 } 150 }