From 4a1d5a50aeeb04c466550872cfa4fc70fca42692 Mon Sep 17 00:00:00 2001 From: Roel van Dijk Date: Tue, 6 Feb 2024 11:07:10 +0100 Subject: [PATCH] #400 Move ImmutableList from inheritance to composition. --- .../parsingdata/metal/data/ImmutableList.java | 151 ++++++++++++++++-- 1 file changed, 136 insertions(+), 15 deletions(-) diff --git a/core/src/main/java/io/parsingdata/metal/data/ImmutableList.java b/core/src/main/java/io/parsingdata/metal/data/ImmutableList.java index d1d9da2c..53e4ebd4 100644 --- a/core/src/main/java/io/parsingdata/metal/data/ImmutableList.java +++ b/core/src/main/java/io/parsingdata/metal/data/ImmutableList.java @@ -17,22 +17,28 @@ package io.parsingdata.metal.data; import static io.parsingdata.metal.Util.checkNotNull; +import static java.util.Collections.unmodifiableList; -import java.util.Arrays; -import java.util.LinkedList; -import java.util.List; +import java.util.*; import java.util.stream.Collectors; +import java.util.stream.Stream; -public class ImmutableList extends LinkedList { +public class ImmutableList implements List { // extends LinkedList { + + private final List innerList; private Integer hashCode; public ImmutableList() { - super(); + innerList = unmodifiableList(new LinkedList<>()); } public ImmutableList(final LinkedList ts) { - super(ts); + innerList = unmodifiableList(new LinkedList<>(ts)); + } + + public ImmutableList(final ImmutableList ts) { + this(ts.innerList); } public ImmutableList(List collect) { @@ -48,31 +54,92 @@ public static ImmutableList create(final T[] array) { } public ImmutableList addHead(final T head) { - final ImmutableList ts = new ImmutableList<>(this); + final LinkedList ts = new LinkedList<>(innerList); ts.addFirst(head); - return ts; + return new ImmutableList<>(ts); } public ImmutableList addList(final ImmutableList list) { - final ImmutableList ts = new ImmutableList<>(list); - ts.addAll(this); - return ts; + final LinkedList ts = new LinkedList<>(list.innerList); + ts.addAll(this.innerList); + return new ImmutableList<>(ts); } public T head() { - if (isEmpty()) { + if (innerList.isEmpty()) { return null; } - return this.getFirst(); + return innerList.get(0); } public ImmutableList tail() { - return new ImmutableList<>(this.subList(1, size())); + return new ImmutableList<>(innerList.subList(1, innerList.size())); + } + + public boolean isEmpty() { + return innerList.isEmpty(); + } + + public int size() { + return innerList.size(); + } + + public boolean contains(Object value) { + return innerList.contains(value); + } + + public Stream stream() { + return innerList.stream(); + } + + public T get(int index) { + return innerList.get(index); + } + + @Override + public T set(int index, T element) { + throw new UnsupportedOperationException(); + } + + @Override + public void add(int index, T element) { + throw new UnsupportedOperationException(); + } + + @Override + public T remove(int index) { + throw new UnsupportedOperationException(); + } + + @Override + public int indexOf(Object o) { + return innerList.indexOf(o); + } + + @Override + public int lastIndexOf(Object o) { + return innerList.lastIndexOf(o); + } + + @Override + public ListIterator listIterator() { + return innerList.listIterator(); + } + + @Override + public ListIterator listIterator(int index) { + return innerList.listIterator(index); + } + + @Override + public List subList(int fromIndex, int toIndex) { + // make this of type ImmutableList? wrap it? + return innerList.subList(fromIndex, toIndex); } @Override public String toString() { - return isEmpty() ? "" : ">" + head() + tail(); + return innerList.isEmpty() ? "" : ">" + head() + tail(); } @Override @@ -83,4 +150,58 @@ public int hashCode() { return hashCode; } + @Override + public Iterator iterator() { + return innerList.iterator(); + } + + @Override + public Object[] toArray() { + return innerList.toArray(); + } + + @Override + public T1[] toArray(T1[] a) { + return innerList.toArray(a); + } + + @Override + public boolean add(T t) { + throw new UnsupportedOperationException(); + } + + @Override + public boolean remove(Object o) { + throw new UnsupportedOperationException(); + } + + @Override + public boolean containsAll(Collection c) { + return innerList.containsAll(c); + } + + @Override + public boolean addAll(Collection c) { + throw new UnsupportedOperationException(); + } + + @Override + public boolean addAll(int index, Collection c) { + throw new UnsupportedOperationException(); + } + + @Override + public boolean removeAll(Collection c) { + throw new UnsupportedOperationException(); + } + + @Override + public boolean retainAll(Collection c) { + throw new UnsupportedOperationException(); + } + + @Override + public void clear() { + throw new UnsupportedOperationException(); + } }