An example of commented Java code
package tools;
import java.util.*;
import tools.*;
import java.io.Serializable;
/**
* Asymmetric Index container for Distance objects.<br />
* This class has been designed to handle Distances between objects
* and provides several ways to retrieve distances. <br />
*
* In this implementation distances are considered asymmetrically.
* This means that d(a,b, 10) could be different from (b,a, 20);
* <br />
*
* This choice allows handling of directed graphs.
*
* @author Alberto Corni, July 2000
*/
public class DistanceMap implements Serializable {
/**
* @name Constructors.
*/
//@{
/**
* Indexes a set of Distance objects.
*
* @param distances Distance instance to be indexed.
*/
public DistanceMap() {
}
/**
* Indexes a set of Distance objects.
*
* @param distances Distance instance to be indexed.
*/
public DistanceMap(Distance[] distances) {
//
putArray(distances);
}
/**
* Clonation method.
*/
public DistanceMap(DistanceMap oldMap) {
//
putArray(oldMap.getAllDistances().toArray());
}
/**
* Clonation method with filter.
* <br>
* The new DistanceMap will contain only the element specified
* in the <i>preserve<i> set.
* @param oldMap the DistanceMap to copy from.
* @param preserve the list of element to preserve.
*/
public DistanceMap(DistanceMap oldMap, Set preserve) {
//
putArrayRestricted(oldMap.getAllDistances().toArray(), preserve);
}
//@}
/**
* @name Instance protected Methods.
*/
//@{
/**
* Indexes an array of Distance objects.
*
* @param distances array of Distance instance to be indexed.
*/
protected void putArray(Object[] distances) {
//
// generates the two sorted maps
for (int i = 0; i < distances.length; i++) {
put((Distance)distances[i]);
}
}
/**
* Indexes an array of Distance objects with filter on nodes.
* <br>
* Will be copied only the distances between the element specified
* in the <i>preserve<i> set.
* <br>
* In the <i>preserve<i> set must be specified a list of node element
* (source or destination for the distances).
* This method will copy only the relation specific of the subgraph
* given by the intesection between the nodes of the <i>preserve<i> set
* and the nodes present in the DistanceMap to clone.
*
* @param distances distances to insert.
* @param preserve the list of element to preserve.
*/
protected void putArrayRestricted(Object[] distances, Set preserve) {
//
// generates the two sorted maps
for (int i = 0; i < distances.length; i++) {
Distance d = (Distance)distances[i];
if (preserve.contains(d.getSrc()) && preserve.contains(d.getDst())) {
put((Distance)distances[i]);
}
}
}
//@}
/**
* @name Instance Methods.
*/
//@{
/**
* Return a set containing ALL distances stored in this data-structure
*/
public Set getAllDistances() {
HashSet rv = new HashSet();
Object[] arr;
//
arr = _srcMap.values().toArray();
for (int i=0;i<arr.length;i++) {
Set s = (Set)arr[i];
rv.addAll(s);
}
//
arr = _dstMap.values().toArray();
for (int i=0;i<arr.length;i++) {
Set s = (Set)arr[i];
rv.addAll(s);
}
//
return(rv);
}
/**
* Add a distance object in the indexing structure.<br />
* <b>
* If a distance between the given elements already exists,
* it is substituted whith the new object.
* </b>
*
* @param distance The distance element to add to this indexing
* structure
*/
public void put(Distance distance) {
//
//
delete(distance);
//
// element keys
Object src = distance.getSrc();
Object dst = distance.getDst();
//
HashSet s;
//
// store ThesRelation in the first-element map
s = (HashSet)_srcMap.get(src);
if (s == null) {
s = new HashSet();
_srcMap.put(src, s);
}
s.add(distance);
//
// store ThesRelation in the second-element map
s = (HashSet)_dstMap.get(dst);
if (s == null) {
s = new HashSet();
_dstMap.put(dst, s);
}
s.add(distance);
}
/**
* Given source and destination object
* returns the Distance object between them .
*
* @return the Distance object between the source and destination
* objects (remind this class is directional), null
* if such distance is not present.
*/
public Distance get(Object src, Object dst) {
//
Distance rv = null;
//
HashSet ssrc = (HashSet)_srcMap.get(src);
HashSet sdst = (HashSet)_dstMap.get(dst);
if (ssrc != null && sdst != null) {
//
// sdel contains all Distance objects that are in srcMap
HashSet srv = new HashSet(ssrc);
// removes from sdel all elements that are also in sdest
srv.retainAll(sdst);
//
if(srv.size() > 0) {
rv = (Distance)((srv.toArray())[0]);
}
}
return(rv);
}
/**
* Given an object returns all distances starting from it.
*
* @return a set of Distance object starting form the given object.
* null if no Distance object start from the given obj.
*/
public Set getStartingFrom(Object src) {
//
//
HashSet rv = (HashSet)_srcMap.get(src);
return(rv);
}
/**
* Given an object returns all distances ending in it.
*
* @return a set of Distance object ending in the given object.
* null if no Distance object ends in the given obj.
*/
public Set getEndingIn(Object src) {
//
//
HashSet rv = (HashSet)_dstMap.get(src);
return(rv);
}
/**
* All distances that contains the Given object.
* @return null if the object does not appears in any distance obj.
*/
public Set getRelatedTo(Object src) {
//
//
HashSet rv = new HashSet();
HashSet srcSet = (HashSet)_srcMap.get(src);
HashSet dstSet = (HashSet)_dstMap.get(src);
if (srcSet != null) rv.addAll(srcSet);
if (dstSet != null) rv.addAll(dstSet);
return(rv);
}
/**
* Given a Distance object, looks for equivalent all Distance object
* (same src and dst objects) and removes them from the indexing structure.
*
* @param distance The distance element to be removed from this tructure.
*/
public void delete(Distance distance) {
//
// element keys
delete(distance.getSrc(), distance.getDst());
}
/**
* Removes from the indexing structure all distances from
* the given src and the given dst.
*
*/
public void delete(Object src, Object dst) {
//
//
HashSet ssrc = (HashSet)_srcMap.get(src);
HashSet sdst = (HashSet)_dstMap.get(dst);
if (ssrc != null && sdst != null) {
//
// sdel contains all Distance objects that are in srcMap
HashSet sdel = new HashSet(ssrc);
// removes from sdel all elements that are also in sdest
sdel.retainAll(sdst);
//
// Now in sdel I have all Destination objects that have
// both _src == src and _dst == dst
//
// So I have to remove them from the indexing structure.
//
ssrc.removeAll(sdel);
sdst.removeAll(sdel);
}
}
/**
* Retuns a set of object that appears at least once in this
* indexing data structure as SOURCE or as DESTINATION.
*/
public Set getSetOfElements() {
HashSet rv = new HashSet(getSetOfSourceElements());
rv.addAll(getSetOfDestinationElements());
return(rv);
}
/**
* Retuns a set of object that appears at least once as SOURCE object.
*/
public Set getSetOfSourceElements() {
Set rv = _srcMap.keySet();
return(rv);
}
/**
* Retuns a set of object that appears at least once as DESTINATION object.
*/
public Set getSetOfDestinationElements() {
Set rv = _dstMap.keySet();
return(rv);
}
/**
* Retuns all stored distances as a set.
*/
public Set getSetOfDistances() {
HashSet rv = new HashSet();
Object[] am = _srcMap.values().toArray();
for (int i=0; i<am.length; i++){
rv.addAll(((Set)am[i]));
}
return(rv);
}
/**
* String representation.
*/
public String toString() {
String rv = getClass().getName() + ":\n";
Set list = getSetOfDistances();
Object[] as = (list).toArray();
for (int j=0; j<as.length; j++){
rv = rv + " " + as[j] + "\n";
}
return(rv);
}
/**
* String representation.<br />
* Produces a tabular output
*/
public String toStringTable() {
String rv = "";
int padlen = 4;
//
//
int i;
int j;
//
// Defining short names
Object[] allElements = getSetOfElements().toArray();
Arrays.sort(allElements, new Comparator() {
public int compare(Object o1, Object o2) {
return(o1.toString().compareTo(o2.toString()));
}
public boolean equals(Object obj) {
return(false);
}
});
rv = rv + "Elements: " + allElements.length + "\n";
for (i=0;i<allElements.length;i++) {
rv =rv+" "+
Tools.stringCenterAndPad("e"+i, padlen) + allElements[i] + "\n";
}
//
// Table
//
// header Dests:
rv =rv+Tools.stringCenterAndPad("src->", padlen)+"|";
for (i=0;i<allElements.length;i++) {
// if (getSetOfSourceElements().contains(allElements[i])) {
rv =rv+Tools.stringCenterAndPad("e"+i, padlen) + "|";
// }
}
rv =rv+"\n";
//
// rows
for (j=0;j<allElements.length;j++) {
// if (getSetOfDestinationElements().contains(allElements[j])) {
// row header:
rv =rv+Tools.stringCenterAndPad("e"+j, padlen) + "|";
for (i=0;i<allElements.length;i++) {
// if (getSetOfSourceElements().contains(allElements[i])) {
String cellValue;
Distance element = get(allElements[i],allElements[j]);
if (element == null) {
cellValue = "";
} else {
cellValue = "" + element.getDistance();
}
rv=rv+Tools.stringCenterAndPad("" + cellValue,padlen) + "|";
// }
}
rv =rv+"\n";
// }
}
return(rv);
}
//@}
/**
* @name Main/test static routine.
*/
//@{
/**
* Routine used to test the class.
* <p>
* Tests the tools.
*/
public static void main(String[] args) {
DistanceMap dm = new DistanceMap();
// -----
Object s;
Object d;
double ds;
Distance t;
//
System.out.println(" - inserting values...");
s="a";d="b";ds=10;t=new Distance(s,d,ds);dm.put(t);System.out.println(t);
s="b";d="a";ds=15;t=new Distance(s,d,ds);dm.put(t);System.out.println(t);
s="b";d="c";ds=20;t=new Distance(s,d,ds);dm.put(t);System.out.println(t);
s="d";d="c";ds=30;t=new Distance(s,d,ds);dm.put(t);System.out.println(t);
s="b";d="d";ds=46;t=new Distance(s,d,ds);dm.put(t);System.out.println(t);
//
System.out.println(" ----- map content:");
System.out.println("" + dm);
System.out.println(" ----- querying:");
s="a";d="b";System.out.println(s+","+d+": " + dm.get(s,d));
s="d";d="c";System.out.println(s+","+d+": " + dm.get(s,d));
s="e";d="d";System.out.println(s+","+d+": " + dm.get(s,d));
//
System.out.println(" ----- over-writing:");
s="a";d="b";ds=17;t=new Distance(s,d,ds);dm.put(t);System.out.println(t);
s="d";d="c";ds=37;t=new Distance(s,d,ds);dm.put(t);System.out.println(t);
s="e";d="d";ds=0;t=new Distance(s,d,ds);dm.put(t);System.out.println(t);
//
System.out.println(" ----- map content:");
System.out.println(" a <15---17> b --20> c <37-- d <0-- e");
System.out.println("" + dm);
//
System.out.println(" ----- source elements:");
System.out.println(dm.getSetOfSourceElements());
System.out.println(" ----- destination elements:");
System.out.println(dm.getSetOfDestinationElements());
System.out.println(" ----- Involved elements:");
System.out.println(dm.getSetOfElements());
//
System.out.println(" ----- toStringTable:");
System.out.println(dm.toStringTable());
//
System.out.println(" ----- getting related:");
s="b";System.out.println("Starts in " + s+" " +dm.getStartingFrom(s));
s="z";System.out.println("Starts in " + s+" " +dm.getStartingFrom(s));
s="b";System.out.println("Ends in " + s+" " +dm.getEndingIn(s));
s="b";System.out.println("Related: " + s+" " +dm.getRelatedTo(s));
//
// Try to use a restriction
//
HashSet restriction = new HashSet();
restriction.add("a");
restriction.add("b");
DistanceMap newMapRestricted = new DistanceMap(dm, restriction);
System.out.println(" ----- Restriction to a and b:");
System.out.println("" + newMapRestricted.toStringTable());
//
// Try to use a restriction
//
restriction = new HashSet();
restriction.add("a");
restriction.add("b");
restriction.add("d");
newMapRestricted = new DistanceMap(dm, restriction);
System.out.println(" ----- Restriction to a and e:");
System.out.println("" + newMapRestricted.toStringTable());
//
//
// Done
//
System.out.println(" -- done.");
}
//@}
/**
* @name Instance variables.
*/
//@{
/**
* Index on the first element of the distance.
*/
private HashMap _srcMap = new HashMap();
/**
* Index on the second element of the distance.
*/
private HashMap _dstMap = new HashMap();
//@}
}
The MOMIS Home Page