Sorted Multi Set
/**
* created Dec 12, 2007
*
* @by Marc Woerlein (woerlein@informatik.uni-erlangen.de)
*
* Copyright 2007 Marc Woerlein
*
* This file is part of parsemis.
*
* Licence:
* LGPL: http://www.gnu.org/licenses/lgpl.html
* EPL: http://www.eclipse.org/org/documents/epl-v10.php
* See the LICENSE file in the project's top-level directory for details.
*/
//package de.parsemis.utils;
import java.util.Collection;
import java.util.Iterator;
import java.util.NoSuchElementException;
/**
*
* @author Marc Woerlein (woerlein@informatik.uni-erlangen.de)
*
* @param <Type>
*/
public class SortedMultiSet<Type extends Comparable<Type>> implements
Collection<Type>, Comparable<SortedMultiSet<Type>> {
Type[] field;
int size;
@SuppressWarnings("unchecked")
public SortedMultiSet() {
size = 0;
field = (Type[]) new Comparable[4];
}
/*
* (non-Javadoc)
*
* @see java.util.Collection#add(java.lang.Object)
*/
@SuppressWarnings("unchecked")
public boolean add(final Type o) {
if (o == null) {
return false;
}
Type[] destField = field;
int pos = 0;
// skip smaller ones
while (pos < size && field[pos].compareTo(o) > 0) {
pos++;
}
if (size == field.length) {
// copy smaller ones
System.arraycopy(field, 0,
destField = (Type[]) new Comparable[(int) (size * 1.5)], 0,
pos);
}
// move bigger ones
System.arraycopy(field, pos, destField, pos + 1, size - pos);
// insert value
destField[pos] = o;
field = destField;
size++;
return true;
}
/*
* (non-Javadoc)
*
* @see java.util.Collection#addAll(java.util.Collection)
*/
public boolean addAll(final Collection<? extends Type> c) {
boolean ret = false;
for (final Type t : c) {
ret |= add(t);
}
return ret;
}
/*
* (non-Javadoc)
*
* @see java.util.Collection#clear()
*/
@SuppressWarnings("unchecked")
public void clear() {
size = 0;
field = (Type[]) new Comparable[field.length];
}
/*
* (non-Javadoc)
*
* @see java.lang.Comparable#compareTo(java.lang.Object)
*/
public int compareTo(final SortedMultiSet<Type> o) {
int c = 0;
int i = 0;
while (c == 0) {
if (i == size) {
return i == o.size ? 0 : -1;
}
if (i == o.size) {
return 1;
}
c = field[i].compareTo(o.field[i]);
i++;
}
return c;
}
/*
* (non-Javadoc)
*
* @see java.util.Collection#contains(java.lang.Object)
*/
@SuppressWarnings("unchecked")
public boolean contains(final Object o) {
return (o instanceof Comparable) && pos((Type) o) >= 0;
}
/*
* (non-Javadoc)
*
* @see java.util.Collection#containsAll(java.util.Collection)
*/
public boolean containsAll(final Collection<?> c) {
boolean ret = true;
for (final Object t : c) {
ret &= contains(t);
}
return ret;
}
/*
* (non-Javadoc)
*
* @see java.lang.Object#equals(java.lang.Object)
*/
@SuppressWarnings("unchecked")
@Override
public boolean equals(final Object obj) {
return obj instanceof SortedMultiSet
&& compareTo((SortedMultiSet) obj) == 0;
}
/*
* (non-Javadoc)
*
* @see java.lang.Object#hashCode()
*/
@Override
public int hashCode() {
return size();
}
/*
* (non-Javadoc)
*
* @see java.util.Collection#isEmpty()
*/
public boolean isEmpty() {
return size == 0;
}
/*
* (non-Javadoc)
*
* @see java.util.Collection#iterator()
*/
public Iterator<Type> iterator() {
return new Iterator<Type>() {
int idx = 0;
public boolean hasNext() {
return idx < size;
}
public Type next() {
if (hasNext()) {
return field[idx++];
}
throw new NoSuchElementException();
}
public void remove() {
throw new UnsupportedOperationException();
}
};
}
private int pos(final Type t) {
int c = -1;
int pos = 0;
for (; c < 0 && pos < size; pos++) {
c = field[pos].compareTo(t);
}
return c == 0 ? pos : -1;
}
/*
* (non-Javadoc)
*
* @see java.util.Collection#remove(java.lang.Object)
*/
@SuppressWarnings("unchecked")
public boolean remove(final Object o) {
if (o instanceof Comparable) {
final int pos = pos((Type) o);
if (pos >= 0) {
System.arraycopy(field, pos + 1, field, pos, --size - pos);
return true;
}
}
return false;
}
/*
* (non-Javadoc)
*
* @see java.util.Collection#removeAll(java.util.Collection)
*/
public boolean removeAll(final Collection<?> c) {
boolean ret = false;
for (final Object t : c) {
ret |= remove(t);
}
return ret;
}
/*
* (non-Javadoc)
*
* @see java.util.Collection#retainAll(java.util.Collection)
*/
public boolean retainAll(final Collection<?> c) {
int j = 0;
for (int i = 0; i < size; i++) {
if (c.contains(field[i])) {
field[j++] = field[i];
}
}
if (j == size) {
return false;
}
for (; j < size; j++) {
field[j] = null;
}
return true;
}
/*
* (non-Javadoc)
*
* @see java.util.Collection#size()
*/
public int size() {
return size;
}
/*
* (non-Javadoc)
*
* @see java.util.Collection#toArray()
*/
@SuppressWarnings("unchecked")
public Object[] toArray() {
return toArray((Type[]) new Comparable[size]);
}
/*
* (non-Javadoc)
*
* @see java.util.Collection#toArray(T[])
*/
public <T> T[] toArray(final T[] a) {
System.arraycopy(field, 0, a, 0, size);
return a;
}
}
Related examples in the same category
1. | Set, HashSet and TreeSet | | |
2. | Things you can do with Sets | | |
3. | Set operations: union, intersection, difference, symmetric difference, is subset, is superset | | |
4. | Set implementation that use == instead of equals() | | |
5. | Set that compares object by identity rather than equality | | |
6. | Set union and intersection | | |
7. | Set with values iterated in insertion order. | | |
8. | Putting your own type in a Set | | |
9. | Use set | | |
10. | Another Set demo | | |
11. | Set subtraction | | |
12. | Working with HashSet and TreeSet | | |
13. | TreeSet Demo | | |
14. | Show the union and intersection of two sets | | |
15. | Demonstrate the Set interface | | |
16. | Array Set extends AbstractSet | | |
17. | Sync Test | | |
18. | Set Copy | | |
19. | Set and TreeSet | | |
20. | Tail | | |
21. | What you can do with a TreeSet | | |
22. | Remove all elements from a set | | |
23. | Copy all the elements from set2 to set1 (set1 += set2), set1 becomes the union of set1 and set2 | | |
24. | Remove all the elements in set1 from set2 (set1 -= set2), set1 becomes the asymmetric difference of set1 and set2 | | |
25. | Get the intersection of set1 and set2, set1 becomes the intersection of set1 and set2 | | |
26. | Extend AbstractSet to Create Simple Set | | |
27. | Int Set | | |
28. | One Item Set | | |
29. | Small sets whose elements are known to be unique by construction | | |
30. | List Set implements Set | | |
31. | Converts a char array to a Set | | |
32. | Converts a string to a Set | | |
33. | Implements the Set interface, backed by a ConcurrentHashMap instance | | |
34. | An IdentitySet that uses reference-equality instead of object-equality | | |
35. | An implementation of the java.util.Stack based on an ArrayList instead of a Vector, so it is not synchronized to protect against multi-threaded access. | | |
36. | A thin wrapper around a List transforming it into a modifiable Set. | | |
37. | A thread-safe Set that manages canonical objects | | |
38. | This program uses a set to print all unique words in System.in | | |
39. | Indexed Set | | |
40. | An ObjectToSet provides a java.util.Map from arbitrary objects to objects of class java.util.Set. | | |
41. | Fixed Size Sorted Set | | |
42. | Set operations | | |
43. | A NumberedSet is a generic container of Objects where each element is identified by an integer id. | | |
44. | Set which counts the number of times a values are added to it. | | |
45. | Set which counts the number of times a values are added to it and assigns them a unique positive index. | | |
46. | Indexed Set | | |
47. | A set acts like array. | | |
48. | Implements a Bloom filter. Which, as you may not know, is a space-efficient structure for storing a set. | | |
49. | Implementation of disjoint-set data structure | | |
50. | Call it an unordered list or a multiset, this collection is defined by oxymorons | | |