Home arrow static arrow Java Programming [Archive] - Possibilities with zero footprint inheritance
Warning: Creating default object from empty value in /www/htdocs/w008deb8/wiki/components/com_staticxt/staticxt.php on line 51
Java Programming [Archive] - Possibilities with zero footprint inheritance
This topic has 32 replies on 3 pages.    1 | 2 | 3 | Next »

Posts:3,999
Registered: 00-05-26
Possibilities with zero footprint inheritance  
Jul 26, 2004 11:30 AM



 
Lets suppose you want to create a HashSet of Strings. However you want the semantics of the set to be that of equalsIgnoreCase. You immediately realize that String.hashCode, and String.equals are a problem.

The first possibility is that you derive from String, HMString and override hashCode and equals to use the toLowerCase version. The problem of course is that many api calls return String and not HMString, and so an explicit ctor needs to be called to convert. This causes many object allocations, and complicates the code.

Another option is to aggregate a String, into HMString. But the problems still exist.

Perhaps, a third option, perhaps the best? is to create a special HashSet, who's ctor, is defined as
public SpecialHashSet( Hashable h)
where the Hashable interface defines
int hashCode( Object o );
and
boolean equals( Object o1, Object o2 )
In this way, you can create an Object that implements Hashable, and calculates the correct hashCode, equals on the input String. But this means a special HashSet, and unfamilar code. It also means that we are removing responsibility from the String to give information about the String. But that is probably a lesser concern.



What if?



Assume we derive a special HMString from String that overrides hashCode and equals. And further what if this class had no member variables/added no storage at all to it's parent class. Theoretically, then, what would be the harm in assuming a common String was an HMString. If that were allowed, one could do

Set mySet = new HashSet();

String s = getAStringFromSomewhere();

mySet.add( downcast<HMString>(s));

downcast was a language feature that allowed statically changing the type of an object to a sub class, as long as that subclass did not add to the footprint of the object.



Those who do calendar math on dates retrieved from a database should instantly recognize this problem.
SQL returns a java.sql.Date,
You create a Gregorian Calendar from the data
Manipulate the date
Then pull a Date out of the calendar
You attempt to update the database with this new date, only to realize it's a java.util.Date
You then must make a bogus java.sql.Date object from it
But java.sql.Date doesn't change the footprint of the Date, so it would be nice if i could do

ps.setDate( 1, downcast<java.sql.Date>( myUtilDate ));



You may now begin castigating me.
Thank you.

 

Posts:37,103
Registered: 3/30/99
Re: Possibilities with zero footprint inheritance  
Jul 26, 2004 11:51 AM (reply 1 of 32)



 
You may now begin castigating me.

So you want to become a Unix?
 

Posts:18,384
Registered: 21.03.00
Re: Possibilities with zero footprint inheritance  
Jul 26, 2004 12:07 PM (reply 2 of 32)



 
Hi,

Interesting toughts... but it is hard to get over the fact that you in your example are using String, a class that is final, and can't be subclassed. I don't think I like the fact that I would be able to change type of an object in runtime. (But that is valid in aspect programming?)

Would it be valid to downcast from java.util.Date to java.sql.Date, and then use some method implementations of that subclass, and then go up to the base class again, and then downcast to my.Date?

/Kaj

 

Posts:3,999
Registered: 00-05-26
Re: Possibilities with zero footprint inheritance  
Jul 26, 2004 12:58 PM (reply 3 of 32)



 

Would it be valid to downcast from java.util.Date to
java.sql.Date, and then use some method
implementations of that subclass, and then go up to
the base class again, and then downcast to my.Date?

Should be
 

Posts:6,750
Registered: 1/25/04
Re: Possibilities with zero footprint inheritance  
Jul 27, 2004 8:45 AM (reply 4 of 32)



 
I'm guessing it would be hard to make this work in the JVM. You could have any number of references to the object, so you would have to either make sure to do the change in a way that doesn't affect them, or create a new object and repoint all the references. The latter would probably even require a change to the JLS. Conceptually I don't see a problem with it, but given that object allocation and cleanup are pretty cheap in small numbers, it's almost certainly not worth the cost of adding this feature.

Also you might want to come up with some word other than downcasting, since that already means converting an object reference.
 

Posts:3,999
Registered: 00-05-26
Re: Possibilities with zero footprint inheritance  
Jul 27, 2004 10:26 AM (reply 5 of 32)



 
I'm guessing it would be hard to make this work in the
JVM.

Prhaps

You could have any number of references to the
object, so you would have to either make sure to do
the change in a way that doesn't affect them, or
create a new object and repoint all the references.

Good point, although one would think that all the references would want them to behave the way the derived class works.

You certainly don't want to create a new object, you can do that already.
 

Posts:13,769
Registered: 00-11-29
Re: Possibilities with zero footprint inheritance  
Jul 27, 2004 10:39 AM (reply 6 of 32)



 
My first thought is to create a new Set class that accepts only Strings (in 1.5 this becomes a lot easier, obviously) and wraps a HashSet. You then just use the toLower version of thString to build the Set. If you need to return the String in the form it was first added in, then wrap a HashMap.

To preempt anyone who will say that this violates the contract of Set, I point out that so does TreeSet so neener-neener.
 

Posts:6,750
Registered: 1/25/04
Re: Possibilities with zero footprint inheritance  
Jul 27, 2004 10:48 AM (reply 7 of 32)



 
Technically, so does HashSet. Set.contains "Returns true if this set contains the specified element. More formally, returns true if and only if this set contains an element e such that (o==null ? e==null : o.equals(e))." That is not the behavior of HashSet.contains.
 

Posts:13,769
Registered: 00-11-29
Re: Possibilities with zero footprint inheritance  
Jul 27, 2004 10:51 AM (reply 8 of 32)



 
You could make this a general class by creating a new interface Equivalent (or whatever) that has two methods, equal(Object a, Object b) and hashCode(Object o). You could use this to wrap a HashMap where you use a special Object that wraps the value and returns the reults of the Equivalent the Set was constructed with.
 

Posts:349
Registered: 1/8/04
Re: Possibilities with zero footprint inheritance  
Jul 27, 2004 10:55 AM (reply 9 of 32)



 
This doesn't address your interest in side/down-casting, but your original problem could be solved by writing a SetWrapper class extending or wrapping a HashSet and a HMString class wrapping a String. The SetWrapper could implement add() to convert the String to a HMString, and get() to convert it back. HMString would only need to hold a String and implement equals() and hashCode() the way you want them. You'd be adding/getting Strings to/from SetWrapper which would be converting and adding/getting HMStrings from HashSet.

You'd end up with two very small classes wrapping/customizing standard classes.
 

Posts:4,906
Registered: 23/07/02
Re: Possibilities with zero footprint inheritance  
Jul 27, 2004 12:16 PM (reply 10 of 32)



 
Technically, so does HashSet.

Mutable elements?
 

Posts:3,999
Registered: 00-05-26
Re: Possibilities with zero footprint inheritance  
Jul 27, 2004 12:58 PM (reply 11 of 32)



 
This doesn't address your interest in
side/down-casting, but your original problem could be
solved by writing a SetWrapper class extending or
wrapping a HashSet and a HMString class wrapping a
String. The SetWrapper could implement add() to
convert the String to a HMString, and get() to convert
it back. HMString would only need to hold a String and
implement equals() and hashCode() the way you want
them. You'd be adding/getting Strings to/from
SetWrapper which would be converting and
adding/getting HMStrings from HashSet.

You'd end up with two very small classes
wrapping/customizing standard classes.

Sure, but a special class just for Sets of Strings seems silly. Really the set shouldn't know anything about it's contents.
 

Posts:3,999
Registered: 00-05-26
Re: Possibilities with zero footprint inheritance  
Jul 27, 2004 12:59 PM (reply 12 of 32)



 
You could make this a general class by creating a new
interface Equivalent (or whatever) that has two
methods, equal(Object a, Object b) and hashCode(Object
o). You could use this to wrap a HashMap where you
use a special Object that wraps the value and returns
the reults of the Equivalent the Set was constructed
with.

Yes, this is basically my third option from OP.
 

Posts:13,769
Registered: 00-11-29
Re: Possibilities with zero footprint inheritance  
Jul 27, 2004 1:00 PM (reply 13 of 32)



 
Sure, but a special class just for Sets of Strings
seems silly. Really the set shouldn't know anything
about it's contents.

Actually it's prefectly normal in 1.5. There are classes in the new JDK that do just that. I don't think that's a problem at all.
 

Posts:3,999
Registered: 00-05-26
Re: Possibilities with zero footprint inheritance  
Jul 27, 2004 1:02 PM (reply 14 of 32)



 
My first thought is to create a new Set class that
accepts only Strings (in 1.5 this becomes a lot
easier, obviously) and wraps a HashSet. You then just
use the toLower version of thString to build the Set.
If you need to return the String in the form it was
first added in, then wrap a HashMap.

To preempt anyone who will say that this violates the
contract of Set, I point out that so does TreeSet so
neener-neener.

Of course, but a class that is a Set just for strings smells wrong, to me.
 
This topic has 32 replies on 3 pages.    1 | 2 | 3 | Next »