TreeSet remove and comparator issue
Here is the situation:
I have stockexchange "Quote" objects with 4 fields, overridden hashCode() and equals() method (that only take into account 3 fields: price, quantity, exchange). Testing objects using quoteX.equals(quoteY) and hashCode() function properly.
In my app, I need to maintain a SortedSet of Quote objects. That is done by creating a Treeset<Quote>(quoteComp) where quoteComp is an object of class QuoteComparator that implements the Comparator interface.
Ordering objective is to compare Quote objects FIRST by their "price", THEN by their "exchange" according to a preferred exchange, e.g. if there are 2 quotes with same price and quantity, but their exchanges are different, the one with preferred exchange should come first!
Now comes the part where I am stuck.
The TreeSet and comparator work fine; Quotes are nicely kept in the right sequence. However I seem to have a problemremoving a Quote object as soon as a preferred exchange is set to something other than null..
What I don't understand is that the TreeSet uses the Comparatorboth for ordering the objects (which works great) but also for removing them. How can make sure a Quote object's Exchange is not compared to the preferredExchange if I am removing it? Can't seem to figure it out.
Feedback much appreciated.
publicclass Quote{
// private String side;
privatedouble price;
private String exchange;
privatelong quantity;
public Quote(double px,long qty, String mkt){
this.price = px;
this.exchange = mkt;
this.quantity = qty;
}
public Quote(double px,long qty, String mkt, Date time){
this.price = px;
this.exchange = mkt;
this.quantity = qty;
}
public String getExchange(){
return exchange;
}
publicvoid setExchange(String market){
this.exchange = market;
}
publicdouble getPrice(){
return price;
}
publicvoid setPrice(Double price){
this.price = price;
}
publiclong getQuantity(){
return quantity;
}
publicvoid setQuantity(Long quantity){
this.quantity = quantity;
}
privatestaticfinal String SEPARATOR ="|";
public String toString(){
return"Px:" + Double.toString(price) + SEPARATOR +"Qty:" + Long.toString(quantity)
+ SEPARATOR +"Exch:" + exchange;
}
publicboolean equals(Object obj){
boolean result =false;
if (obj ==this){
result =true;
}
if (!(objinstanceof Quote)){
result =false;
}
else{
Quote quote = (Quote)obj;
result = (price == quote.price
&& quantity == quote.quantity
&& exchange == quote.exchange) ?true :false;
}
return result;
}
publicvolatileint hashCode = 0;
publicint hashCode(){
if (hashCode == 0){
int result = 17;
int factor = 37;
result = factor*result + (int)quantity;
result = factor*result + (int)price;
result = factor*result + exchange.hashCode();
hashCode = result;
}
return hashCode;
}
}
import java.util.Comparator;
import java.util.SortedSet;
import java.util.TreeSet;
publicclass TreesetTest{
publicstaticvoid main(String[] args){
TreesetTest tt =new TreesetTest();
}
private String preferredExchange ="YYY";
public TreesetTest(){
QuoteComparator qc =new QuoteComparator();
SortedSet<Quote> set =new TreeSet<Quote>(qc);
// demonstrate ordering
Quote q =new Quote(16800D,200,"YYY");
set.add(q);
Quote q2 =new Quote(15000D,400,"XXX");
set.add(q2);
Quote q3 =new Quote(16500D,50,"YYY");
set.add(q3);
Quote q1 =new Quote(15000D,100,"YYY");
set.add(q1);
Quote q4 =new Quote(16500D,150,"XXX");
set.add(q4);
// --
// gets removed when pref exch is set to XXX
Quote r =new Quote(16800D,200,"YYY");
set.remove(r);
// gets removed when preferred exchange is set to YYY
Quote rr =new Quote(15000,400,"XXX");
set.remove(rr);
// both get removed when pref exch is null
for (Quote quote : set){
System.out.println(quote.toString());
}
}
publicclass QuoteComparatorimplements Comparator
{
privateboolean ascending =true;
publicint compare(Object objX, Object objY)
{
// cast!
Quote qX = (Quote)objX;
Quote qY = (Quote)objY;
int result = 0;
result = compareDouble(qX.getPrice(),qY.getPrice());
if (result == 0){
//both prices identical
if (preferredExchange !=null){
if (qX.getExchange().equals(preferredExchange)){
result = -1;
}
elseif (qY.getExchange().equals(preferredExchange)){
result = 1;
}
}
else{
// no preferred set, just compare exchange strings
result = compareString(qX.getExchange(),qY.getExchange());
}
}
return result;
}
privateint compareString(String val1, String val2){
// initialize strings if null, in order to compare!
if (val1 ==null){
val1 ="";
}
if (val2 ==null){
val2 ="";
}
return this.ascending ? val1.compareTo(val2) :
val2.compareTo(val1);
}
privateint compareDouble(Double d1, Double d2){
if (d1 !=null && d2 !=null){
return this.ascending ? d1.compareTo(d2) :
d2.compareTo(d1);
}
else{
return 0;
}
}
}
}

