/*
*
* Copyright (c) 2007
* Adrian Michel
* http://www.tradery.com
*
* Permission to use, copy, modify, distribute and sell this software
* and its documentation for any purpose is hereby granted without fee,
* provided that the above copyright notice appear in all copies and
* that both that copyright notice and this permission notice appear
* in supporting documentation. Adrian Michel makes no
* representations about the suitability of this software for any
* purpose. It is provided "as is" without express or implied warranty.
*/
package com.tradery.collections;
import com.tradery.contract.Contract;
import java.util.Hashtable;
import java.util.Enumeration;
import java.io.IOException;
import java.io.OutputStream;
/**
* IntegerSet class - models a set of unique integer values.
*
* The hash value is the sum of all elements, which allows for fast comparison
* in case the two hash values are different, the sets are different.
*
* Note for syntax tree class: when the tree is brought to the Star Normal Form, the integer set used by model
* will be implemented as lists, because all sets manipulated are disjoint in this case and so
* the reunion operation can be modeled as a simple concatenation of two lists (this is to optimize
* the DFA generation algorithm)
*/
public class IntegerSet extends SetAsHashtable
{
private int hashCode;
/**
* Default constructor
*/
public IntegerSet()
{
hashCode = 0;
}
/**
* Constructor that sets the first integer value in the set
*
* @param n The integer value to be added to the set
*/
public IntegerSet( int n )
{
this();
put( new Integer( n ) );
hashCode = n;
}
/**
* Does the reunion of an integer set with the current integer sets.
* All the new values are added to the current integer set, which holds
* the reunion.
* In case of duplicate values, only one of them is added to the new set.
*
* @param set The set to do the reunion with
* @return A reference to the current integer set
*/
public IntegerSet reunion( IntegerSet set )
{
if( Contract.REQUIRE )
Contract.require( set != null );
for( Enumeration e = set.elements() ; e.hasMoreElements() ;)
{
Integer integer = (Integer)e.nextElement();
// only add to the hashcode the new values
if( put( integer ) == null )
hashCode += integer.intValue();
}
return this;
}
/**
* Indicates whether two sets have any common values.
*
* @param set The set to compare with
* @return true if the two sets have common values, false otherwise
*/
public boolean intersection( SetAsHashtable set )
{
if( Contract.REQUIRE )
Contract.require( set != null );
// Set intersection = new Set();
for( Enumeration e = set.elements(); e.hasMoreElements(); )
{
if( contains( e.nextElement() ) )
return true;
}
return false;
}
/**
* Adds a new value to the set. If it is a duplicate of an existing value,
* it does not do anything
*
* @param n The value to be added to the set
*/
public void add( int n )
{
// add to hashcode only if it is a new element
if( put( new Integer( n ) ) == null )
hashCode += n;
}
/**
* Tests two sets for equality
*
* @param set The set to be tested for equality relative to the current one
* @return true if the two sets are equal, false otherwise
*/
public boolean equals( Object set )
{
if( set == null )
return false;
IntegerSet h = (IntegerSet)set;
// if the hashcodes or sizes are not equal, then the objects are not equal
if( hashCode() != set.hashCode() || h.size() != size() )
return false;
else
{
// compare all elements
for( Enumeration e = elements(); e.hasMoreElements() ; )
{
// TODO: this is not efficient, because contains does a search for each element
if( !h.contains( e.nextElement() ) )
return false;
}
return true;
}
}
/**
* Returns a hascode value. Used by collections
*
* @return The hashcode value
*/
public int hashCode() { return hashCode; }
/**
* Indicates if the current set contains a value
*
* @param n The value to be tested
* @return true if the set contains the value, false otherwise
*/
public boolean contains( int n ) { return contains( new Integer( n ) ); }
/**
* Dumps the contents of the set to an output stream
*
* @param os the output stream
* @exception IOException
*/
public void dump( OutputStream os )
throws IOException
{
//TODO: replace all ModelWriter... with C1 statements
os.write( toString().getBytes() );
}
/**
* Creates a string representation of the IntegerSet object and it has the
* following format: "{1,2,3}".
*
* @return The string representation of the IntegerSet object
*/
public String toString()
{
String str = new String();
str += "{";
boolean first = true;
for( Enumeration e = elements(); e.hasMoreElements() ; )
{
if( !first )
str += ",";
else
first = false;
str += e.nextElement().toString();
}
str += "}";
return str;
}
}