diff --git a/classpath/java/lang/IndexOutOfBoundsException.java b/classpath/java/lang/IndexOutOfBoundsException.java new file mode 100644 index 0000000000..4110743c12 --- /dev/null +++ b/classpath/java/lang/IndexOutOfBoundsException.java @@ -0,0 +1,19 @@ +package java.lang; + +public class IndexOutOfBoundsException extends RuntimeException { + public IndexOutOfBoundsException(String message, Throwable cause) { + super(message, cause); + } + + public IndexOutOfBoundsException(String message) { + this(message, null); + } + + public IndexOutOfBoundsException(Throwable cause) { + this(null, cause); + } + + public IndexOutOfBoundsException() { + this(null, null); + } +} diff --git a/classpath/java/lang/UnsupportedOperationException.java b/classpath/java/lang/UnsupportedOperationException.java new file mode 100644 index 0000000000..29acff4929 --- /dev/null +++ b/classpath/java/lang/UnsupportedOperationException.java @@ -0,0 +1,19 @@ +package java.lang; + +public class UnsupportedOperationException extends RuntimeException { + public UnsupportedOperationException(String message, Throwable cause) { + super(message, cause); + } + + public UnsupportedOperationException(String message) { + this(message, null); + } + + public UnsupportedOperationException(Throwable cause) { + this(null, cause); + } + + public UnsupportedOperationException() { + this(null, null); + } +} diff --git a/classpath/java/util/ArrayList.java b/classpath/java/util/ArrayList.java new file mode 100644 index 0000000000..60121ee9b7 --- /dev/null +++ b/classpath/java/util/ArrayList.java @@ -0,0 +1,95 @@ +package java.util; + +public class ArrayList implements List { + private Object[] array; + private int size; + + public ArrayList(int capacity) { + if (capacity != 0) { + array = new Object[capacity]; + } + } + + public ArrayList() { + this(0); + } + + private void resize() { + if (array == null || size >= array.length - 1) { + resize(array == null ? 16 : array.length * 2); + } else if (size <= array.length / 3) { + resize(array.length / 2); + } + } + + private void resize(int capacity) { + Object[] newArray = null; + if (capacity != 0) { + if (array != null && array.length == capacity) { + return; + } + + newArray = new Object[capacity]; + if (array != null) { + System.arraycopy(array, 0, newArray, 0, size); + } + } + array = newArray; + } + + private static boolean equal(Object a, Object b) { + return (a == null && b == null) || (a != null && a.equals(b)); + } + + public int size() { + return size; + } + + public boolean add(T element) { + resize(); + array[size++] = element; + return true; + } + + public T get(int index) { + if (index >= 0 && index < size) { + return (T) array[index]; + } else { + throw new IndexOutOfBoundsException(index + " not in [0, " + size + ")"); + } + } + + public T remove(int index) { + T v = get(index); + + if (index == size - 1) { + array[index] = null; + } else { + System.arraycopy(array, index + 1, array, index, size - index); + } + + -- size; + resize(); + + return v; + } + + public boolean remove(T element) { + for (int i = 0; i < size; ++i) { + if (equal(element, array[i])) { + remove(i); + return true; + } + } + return false; + } + + public void clear() { + array = null; + size = 0; + } + + public Iterator iterator() { + return new Collections.ArrayListIterator(this); + } +} diff --git a/classpath/java/util/Arrays.java b/classpath/java/util/Arrays.java new file mode 100644 index 0000000000..b1ca3f103d --- /dev/null +++ b/classpath/java/util/Arrays.java @@ -0,0 +1,37 @@ +package java.util; + +public class Arrays { + private Arrays() { } + + public static List asList(final T ... array) { + return new List() { + public int size() { + return array.length; + } + + public boolean add(T element) { + throw new UnsupportedOperationException(); + } + + public T get(int index) { + return array[index]; + } + + public T remove(int index) { + throw new UnsupportedOperationException(); + } + + public boolean remove(T element) { + throw new UnsupportedOperationException(); + } + + public void clear() { + throw new UnsupportedOperationException(); + } + + public Iterator iterator() { + return new Collections.ArrayListIterator(this); + } + }; + } +} diff --git a/classpath/java/util/Collections.java b/classpath/java/util/Collections.java new file mode 100644 index 0000000000..e7f7352c1f --- /dev/null +++ b/classpath/java/util/Collections.java @@ -0,0 +1,114 @@ +package java.util; + +public class Collections { + private Collections() { } + + static class IteratorEnumeration implements Enumeration { + private final Iterator it; + + public IteratorEnumeration(Iterator it) { + this.it = it; + } + + public T nextElement() { + return it.next(); + } + + public boolean hasMoreElements() { + return it.hasNext(); + } + } + + static class SynchronizedCollection implements Collection { + private final Object lock; + private final Collection collection; + + public SynchronizedCollection(Object lock, Collection collection) { + this.lock = lock; + this.collection = collection; + } + + public synchronized int size() { + synchronized (lock) { return collection.size(); } + } + + public synchronized boolean add(T e) { + synchronized (lock) { return collection.add(e); } + } + + public synchronized boolean remove(T e) { + synchronized (lock) { return collection.remove(e); } + } + + public synchronized void clear() { + synchronized (lock) { collection.clear(); } + } + + public Iterator iterator() { + return new SynchronizedIterator(lock, collection.iterator()); + } + } + + static class SynchronizedSet + extends SynchronizedCollection + implements Set + { + public SynchronizedSet(Object lock, Set set) { + super(lock, set); + } + } + + static class SynchronizedIterator implements Iterator { + private final Object lock; + private final Iterator it; + + public SynchronizedIterator(Object lock, Iterator it) { + this.lock = lock; + this.it = it; + } + + public T next() { + synchronized (lock) { return it.next(); } + } + + public boolean hasNext() { + synchronized (lock) { return it.hasNext(); } + } + + public void remove() { + synchronized (lock) { it.remove(); } + } + } + + static class ArrayListIterator implements Iterator { + private final List list; + private boolean canRemove = false; + private int index = -1; + + public ArrayListIterator(List list) { + this.list = list; + } + + public T next() { + if (hasNext()) { + canRemove = true; + return list.get(++index); + } else { + throw new NoSuchElementException(); + } + } + + public boolean hasNext() { + return index + 1 < list.size(); + } + + public void remove() { + if (canRemove) { + canRemove = false; + list.remove(index--); + } else { + throw new IllegalStateException(); + } + } + } +} diff --git a/classpath/java/util/Enumeration.java b/classpath/java/util/Enumeration.java new file mode 100644 index 0000000000..26399b5f43 --- /dev/null +++ b/classpath/java/util/Enumeration.java @@ -0,0 +1,7 @@ +package java.util; + +public interface Enumeration { + public T nextElement(); + + public boolean hasMoreElements(); +} diff --git a/classpath/java/util/Hashtable.java b/classpath/java/util/Hashtable.java new file mode 100644 index 0000000000..5dd443ceaf --- /dev/null +++ b/classpath/java/util/Hashtable.java @@ -0,0 +1,54 @@ +package java.util; + +public class Hashtable implements Map { + private final HashMap map; + + public Hashtable(int capacity) { + map = new HashMap(capacity); + } + + public Hashtable() { + this(0); + } + + public synchronized int size() { + return map.size(); + } + + public synchronized V get(K key) { + return map.get(key); + } + + public synchronized V put(K key, V value) { + return map.put(key, value); + } + + public synchronized V remove(K key) { + return map.remove(key); + } + + public synchronized void clear() { + map.clear(); + } + + public Enumeration keys() { + return new Collections.IteratorEnumeration(keySet().iterator()); + } + + public Enumeration elements() { + return new Collections.IteratorEnumeration(values().iterator()); + } + + public Set> entrySet() { + return new Collections.SynchronizedSet(this, map.entrySet()); + } + + public Set keySet() { + return new Collections.SynchronizedSet(this, map.keySet()); + } + + public Collection values() { + return new Collections.SynchronizedCollection(this, map.values()); + } + +} diff --git a/classpath/java/util/LinkedList.java b/classpath/java/util/LinkedList.java new file mode 100644 index 0000000000..7fc1bd7e2c --- /dev/null +++ b/classpath/java/util/LinkedList.java @@ -0,0 +1,140 @@ +package java.util; + +public class LinkedList implements List { + private Cell front; + private Cell rear; + private int size; + + private Cell find(int index) { + int i = 0; + for (Cell c = front; c != null; c = c.next) { + if (i == index) { + return c; + } + ++ i; + } + throw new IndexOutOfBoundsException(index + " not in [0, " + size + ")"); + } + + private static boolean equal(Object a, Object b) { + return (a == null && b == null) || (a != null && a.equals(b)); + } + + private void add(Cell c) { + ++ size; + + if (front == null) { + front = rear = c; + } else { + c.prev = rear; + rear = c; + } + } + + private Cell find(T element) { + for (Cell c = front; c != null; c = c.next) { + if (equal(c.value, element)) { + return c; + } + } + return null; + } + + private void remove(Cell c) { + -- size; + + if (c.prev == null) { + front = c.next; + } else { + c.prev.next = c.next; + } + + if (c.next == null) { + rear = c.prev; + } else { + c.next.prev = c.prev; + } + } + + public int size() { + return size; + } + + public boolean add(T element) { + add(new Cell(element, null, null)); + return true; + } + + public T get(int index) { + return find(index).value; + } + + public T remove(int index) { + Cell c = find(index); + remove(c); + return c.value; + } + + public boolean remove(T element) { + Cell c = find(element); + if (c == null) { + return false; + } else { + remove(c); + return true; + } + } + + public void clear() { + front = rear = null; + size = 0; + } + + public Iterator iterator() { + return new MyIterator(front); + } + + private static class Cell { + public T value; + public Cell prev; + public Cell next; + + public Cell(T value, Cell prev, Cell next) { + this.value = value; + this.prev = prev; + this.next = next; + } + } + + private class MyIterator implements Iterator { + private Cell current; + private Cell next; + + public MyIterator(Cell start) { + next = start; + } + + public T next() { + if (hasNext()) { + current = next; + next = next.next; + return current.value; + } else { + throw new NoSuchElementException(); + } + } + + public boolean hasNext() { + return next != null; + } + + public void remove() { + if (current != null) { + LinkedList.this.remove(current); + current = null; + } else { + throw new IllegalStateException(); + } + } + } +} diff --git a/classpath/java/util/List.java b/classpath/java/util/List.java new file mode 100644 index 0000000000..d23084f657 --- /dev/null +++ b/classpath/java/util/List.java @@ -0,0 +1,7 @@ +package java.util; + +public interface List extends Collection { + public T get(int index); + + public T remove(int index); +} diff --git a/classpath/java/util/Stack.java b/classpath/java/util/Stack.java new file mode 100644 index 0000000000..3f3d6ad69d --- /dev/null +++ b/classpath/java/util/Stack.java @@ -0,0 +1,20 @@ +package java.util; + +public class Stack extends Vector { + public boolean empty() { + return size() != 0; + } + + public T peek() { + return get(size() - 1); + } + + public T pop() { + return remove(size() - 1); + } + + public T push(T element) { + add(element); + return element; + } +} diff --git a/classpath/java/util/Vector.java b/classpath/java/util/Vector.java new file mode 100644 index 0000000000..65ce7fb908 --- /dev/null +++ b/classpath/java/util/Vector.java @@ -0,0 +1,54 @@ +package java.util; + +public class Vector implements List { + private final ArrayList list; + + public Vector(int capacity) { + list = new ArrayList(capacity); + } + + public Vector() { + this(0); + } + + public synchronized int size() { + return list.size(); + } + + public synchronized boolean add(T element) { + return list.add(element); + } + + public void addElement(T element) { + add(element); + } + + public synchronized T get(int index) { + return list.get(index); + } + + public T elementAt(int index) { + return get(index); + } + + public synchronized T remove(int index) { + return list.remove(index); + } + + public synchronized boolean remove(T element) { + return list.remove(element); + } + + public synchronized void clear() { + list.clear(); + } + + public Iterator iterator() { + return new Collections.ArrayListIterator(this); + } + + public Enumeration elements() { + return new Collections.IteratorEnumeration(iterator()); + } + +}