All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.anc.util.SparseArray Maven / Gradle / Ivy

The newest version!
/*-
 * Copyright 2009 The American National Corpus
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 */
package org.anc.util;

import java.util.Hashtable;
import java.util.Iterator;

/**
 * Experimental.
 * 

* An array/vector like data structure with a large capacity, that is a large * maximum index, but that is expected to be mostly empty. For example, an array * with space for one million elements but that will only ever contain a few * hundred items. *

* This implementation uses two a data structures to provide the backing store * for the sparse array. A {@link org.anc.util.SkipList} to provide efficient * linear access to the elements of the array, and a {@link java.util.Hashtable} * to provide efficient random access to the elements of the array. *

* NOTE: The iterator returned by a call to method iterator() * iterates over the items present in the array and not the individual array * elements. For example, the following only prints two items even though the * array is 1,000 elements "long". *

 *     SparseArray array = new SparseArray();
 *     array.setElementAt(0, "Hello");
 *     arrar.setElementAt(999, "World");
 *     for (String s : array)
 *     {
 *         System.out.println(s);
 *     }
 * 
* * * @author Keith Suderman * @version 1.0 */ // TODO Implement the Collection interface and/or extend AbstractCollection. public class SparseArray implements Iterable { /** A list of the elements in the array to provide efficient iterator access. */ private SkipList> fList = new SkipList>(); /** A hash table of the elements to provide efficient random access. */ private Hashtable> fTable = new Hashtable>(); /** The largest index of any element stored in the array. */ private long fMaxIndex = 0; public SparseArray() { } public void setElementAt(long index, T value) { if (index > fMaxIndex) { fMaxIndex = index; } Element e = new Element(index, value); fList.replace(e); fTable.put(new Index(index), e); } public T getElementAt(long index) { Element e = fTable.get(new Index(index)); if (e == null) { return null; } return e.getElement(); } public long size() { return fList.size(); } public long getMaxIndex() { return fMaxIndex; } public void clear() { fMaxIndex = 0; fList.clear(); fTable.clear(); } @Override public Iterator iterator() { return new SparseArrayIterator(fList.iterator()); } public static void main(String[] args) { SparseArray sparsearray = new SparseArray(); for (int i = 0; i < 10; ++i) { System.out.println("Setting element at " + (i + i)); sparsearray.setElementAt(i + i, Integer.valueOf(i)); } for (int i = 0; i < 10; ++i) { Integer j = sparsearray.getElementAt(i + i); System.out.println("index " + (i + i) + ": " + j); } Iterator it = sparsearray.iterator(); while (it.hasNext()) { System.out.println(it.next()); } } } class SparseArrayIterator implements Iterator { private Iterator> iterator; public SparseArrayIterator(Iterator> it) { iterator = it; } @Override public boolean hasNext() { return iterator.hasNext(); } @Override public T next() { return iterator.next().getElement(); } @Override public void remove() { // Iterator next = iterator.next(); // iterator.remove(); // iterator = next; throw new UnsupportedOperationException( "Deletion via a SparseArrayIterator is not allowed."); } } /** * An element of the sparse array. The parameter type T is the type of objects * stored in the array. * */ class Element implements Comparable> { /** The index of the this element in the array. */ private long index; /** The item to be stored in this array element. */ private T element; public Element(long index, T element) { this.index = index; this.element = element; } /** * Two elements are ordered by their index and are equal iff their indices * are the same. */ @Override public int compareTo(Element other) { return (int) (index - other.index); } @Override public int hashCode() { final int prime = 31; int result = 1; result = prime * result + ((element == null) ? 0 : element.hashCode()); result = prime * result + (int) (index ^ (index >>> 32)); return result; } @Override public boolean equals(Object obj) { if (this == obj) return true; if (obj == null) return false; if (getClass() != obj.getClass()) return false; Element other = (Element) obj; if (element == null) { if (other.element != null) return false; } else if (!element.equals(other.element)) return false; if (index != other.index) return false; return true; } /** Return the item stored in this element. */ public T getElement() { return element; } @Override public String toString() { return index + ": " + element.toString(); } } /** * An index into the sparse array. Index objects are used as the keys into the * hash table backing store. */ class Index implements Comparable { protected long fIndex; public Index(long index) { fIndex = index; } @Override public int compareTo(Index i) { return (int) (fIndex - i.fIndex); } @Override public boolean equals(Object object) { if (!(object instanceof Index)) { return false; } Index i = (Index) object; return fIndex == i.fIndex; } @Override public int hashCode() { return (int) fIndex; } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy