001: package org.gui4j.core.util;
002:
003: import java.io.Serializable;
004: import java.util.HashMap;
005: import java.util.HashSet;
006: import java.util.Iterator;
007: import java.util.Map;
008: import java.util.Set;
009:
010: import org.gui4j.util.Pair;
011:
012: /**
013: * Generic Class for sparsely populated matrices. The size of the matrix is dynamic, i.e.
014: * you can specify arbitrary row and column parameters.
015: *
016: * Another way to look at this class is as a "two-dimensional" map. Instead of a single key
017: * it uses a row and a column element to store and retrieve data elements.
018: *
019: * The public Interface Traverser allows to traverse the matrix generically. The Traverser object is passed
020: * into <code>traverse(Traverser)</code> and is given the opportunity to work with each element of the matrix.
021: */
022: public final class SparseMatrix implements Serializable {
023: /**
024: * Allows objects to traverse the matrix.
025: * @see SparseMatrix#traverse(SparseMatrix.Traverser)
026: */
027: public static interface Traverser {
028: /**
029: * Called once for each element that is visited during traversal.
030: * There is no defined traversal sequence.
031: * If the Traverser manipulates any one of row, col or value the effects on the matrix are undefined.
032: * @param row the "row" of the traversal's current matrix cell
033: * @param col the "column" of the traversal's current matrix cell
034: * @param value the value of the traversal's current matrix cell
035: */
036: public void work(Object row, Object col, Object value);
037: }
038:
039: // The map where all matrix elements are stored.
040: private final Map matrixMap = new HashMap();
041:
042: /**
043: * Returns the value found at the specified row and column of the matrix.
044: * Returns null if there's no value for the specified row and column.
045: * @param row Object
046: * @param col Object
047: * @return Object
048: */
049: public Object get(Object row, Object col) {
050: return matrixMap.get(new Pair(row, col));
051: }
052:
053: /**
054: * Sets the value of the matrix at the specified row and column.
055: * @param row Object
056: * @param col Object
057: * @param value
058: */
059: public void set(Object row, Object col, Object value) {
060: if (row == null || col == null) {
061: throw new IllegalArgumentException(
062: "row or column may not be null.");
063: }
064:
065: matrixMap.put(new Pair(row, col), value);
066: }
067:
068: public void remove(Object row, Object col) {
069: matrixMap.remove(new Pair(row, col));
070: }
071:
072: /**
073: * Returns a Set of all used "columns" in the matrix.
074: * @return Set
075: */
076: public Set colSet() {
077: Set colSet = new HashSet();
078:
079: for (Iterator iterator = matrixMap.keySet().iterator(); iterator
080: .hasNext();) {
081: Pair pair = (Pair) iterator.next();
082: colSet.add(pair.getSecond());
083: }
084:
085: return colSet;
086: }
087:
088: /**
089: * Returns a Set of all used "rows" in the matrix.
090: * @return Set
091: */
092: public Set rowSet() {
093: Set rowSet = new HashSet();
094:
095: for (Iterator iterator = matrixMap.keySet().iterator(); iterator
096: .hasNext();) {
097: Pair pair = (Pair) iterator.next();
098: rowSet.add(pair.getFirst());
099: }
100:
101: return rowSet;
102: }
103:
104: /**
105: * Traverses the matrix and calls <code>work()</code> on the supplied
106: * Traverser object for each matrix element.
107: * The traversal sequence is undefined.
108: * @param traverser Traverser
109: */
110: public void traverse(Traverser traverser) {
111: Iterator iter = matrixMap.entrySet().iterator();
112: while (iter.hasNext()) {
113: Map.Entry entry = (Map.Entry) iter.next();
114: Pair key = (Pair) entry.getKey();
115: Object row = key.getFirst();
116: Object col = key.getSecond();
117: traverser.work(row, col, entry.getValue());
118: }
119: }
120:
121: /**
122: * Löscht alle Elemente
123: */
124: public void clear() {
125: matrixMap.clear();
126: }
127:
128: public boolean equals(Object obj) {
129: if (this == obj) {
130: return true;
131: }
132: if (!(obj instanceof SparseMatrix)) {
133: return false;
134: }
135:
136: SparseMatrix other = (SparseMatrix) obj;
137:
138: return this .matrixMap.equals(other.matrixMap);
139: }
140:
141: public int hashCode() {
142: return matrixMap.hashCode();
143: }
144:
145: public String toString() {
146: return "SparseMatrix (" + matrixMap.size() + " elements)";
147: }
148:
149: }
|