subtle class lookup with sets.

C

cbongior

So, I have a situation where I have a set that has a listing of
"supported" class types (See below). The problem is that, I HAVE to
override the toString() method of the BigInteger in a subclass. Well,
By subclassing BigInteger the .getClass() method changes and thus, will
not lookup in this set.

class Class is final, so I can't override any of the methods (like
hashcode). method getClass() is final, so that's out. I can't use a
HashSet (cannot change the hash for Class) or a TreeSet (Class has no
natural ordering and my own Comparator would require me to devise an
arbitrary numerical value for each element -- the most obvious choice
for the compare being the hashCode -- putting me back to the HashSet
problem)

Current set and my idea below

----------begin current set----------------------

public static final Set SUPPORTED_TYPES = new HashSet();
static {

SUPPORTED_TYPES.add(Integer.TYPE);
SUPPORTED_TYPES.add(Long.TYPE);
SUPPORTED_TYPES.add(Short.TYPE);
SUPPORTED_TYPES.add(Byte.TYPE);
SUPPORTED_TYPES.add(Boolean.TYPE);
SUPPORTED_TYPES.add(Float.TYPE);
SUPPORTED_TYPES.add(Double.TYPE);
SUPPORTED_TYPES.add(Integer.class);
SUPPORTED_TYPES.add(Long.class);
SUPPORTED_TYPES.add(Short.class);
SUPPORTED_TYPES.add(Byte.class);
SUPPORTED_TYPES.add(Boolean.class);
SUPPORTED_TYPES.add(Float.class);
SUPPORTED_TYPES.add(Double.class);
SUPPORTED_TYPES.add(String.class);
SUPPORTED_TYPES.add(BigInteger.class);
SUPPORTED_TYPES.add(BigDecimal.class);
SUPPORTED_TYPES.add(Date.class);
}
----------end current set----------------------

I would like to somehow make use of hashing or binary searching for a
speed up. So, I was thinking of using an existing set and overidding
contains to be:

public boolean contains(Object o) {
boolean contains = false;
if(o != null) {
contains = super.contains(o);
if(contains == false)
contains = super.contains(o.getSuperClass());
}

return contains;
}

Clearly this would be slower, but not by much given the limited class
hierarchy and because the original set only contains 2 (for now)
extendable class types. Any thoughts on the subject?

Christian
http://christian.bongiorno.org/resume.pdf
 
E

Eric Sosman

So, I have a situation where I have a set that has a listing of
"supported" class types (See below). The problem is that, I HAVE to
override the toString() method of the BigInteger in a subclass. Well,
By subclassing BigInteger the .getClass() method changes and thus, will
not lookup in this set.

class BigKahuna extends BigInteger { ... }

...
SUPPORTED_TYPES.add(BigInteger.class);
SUPPORTED_TYPES.add(BigKahuna.class);
...

It seems so obvious I fear I must have overlooked something.
 
C

cbongior

Update: In one case I merely used a Anonymous Inner class for the
override and, to my utter confusion, it passed lookup in the above set.
The class SHOULD BE

OutterClass$1 -- the hash for the two class do NOT match. Any
explanations for this behavior?

public BigInteger getUOI_ID() {
return new BigInteger(UOI_ID.getBytes()) {
public String toString() {
return toString(16);
}
};
}
 
T

Thomas Hawtin

So, I have a situation where I have a set that has a listing of
"supported" class types (See below). The problem is that, I HAVE to ^^^^Why?
override the toString() method of the BigInteger in a subclass. Well,
By subclassing BigInteger the .getClass() method changes and thus, will
not lookup in this set.

Are you sure you want to do that? Couldn't you just alter the code that
calls toString on it?
class Class is final, so I can't override any of the methods (like
hashcode). method getClass() is final, so that's out. I can't use a
HashSet (cannot change the hash for Class) or a TreeSet (Class has no
natural ordering and my own Comparator would require me to devise an
arbitrary numerical value for each element -- the most obvious choice
for the compare being the hashCode -- putting me back to the HashSet
problem)

I would suggest not trying to extend a Set. There isn't really any
point. Instead use a map from Class to whether it is known to be in the
set or not. If it isn't known check the super and put the result back in
the map.

Here's some code. (Not tested. Not compiled. Usual disclaimers.)

private static final Map<Class<?>,Boolean> supportedTypes;
static {
supportedType = new java.util.WeakHashMap();
supportedType.put(Object.class, false);
supportedType.put(Integer.class, true);
...
}

public static boolean isSupported(Class<?> clazz) {
synchronized (supportedTypes) {
Boolean supported = supportedType.get(clazz);
if (supported == null) {
Class<?> superclass = clazz.getSuperClass();
assert superclass != null;
if (isSupported(superclass)) {
supported = true;
} else {
for (Class iface : class.getInterfaces()) {
if (isSupported(iface)) {
supported = true;
break;
}
}
}
supportedTypes.put(clazz, supported);
}
return supported;
}
}

I did something similar the other week to check whether
java.awt.Component instances override coalesceEvents (whoever did the
original code wasn't paying attention).

Tom Hawtin
 
C

cbongior

Indeed you did. Everytime a new subclass to BigInteger is created you
have to update the map and, good code adapts. I am looking for a
solution that readily supports polymorphic types of classes in the
supported type set. I want the lookup to return true for polymorphic
types for those listed.

Christian

http://christian.bongiorno.org/resume.pdf
 
C

cbongior

Your snippet of code is functionally nearly identical to what I had
posted (but I like the idea of caching). I Also considered the
interface issue too but it wasn't relavent to my example. What I am
missing is what using a map buys me. After all, HashSet is backed by a
HashMap.

Christian

http://christian.bongiorno.org/resume.pdf
 
P

Patricia Shanahan

Your snippet of code is functionally nearly identical to what I had
posted (but I like the idea of caching). I Also considered the
interface issue too but it wasn't relavent to my example. What I am
missing is what using a map buys me. After all, HashSet is backed by a
HashMap.

There are three interesting states for a class:

1. Known to be permitted.

2. Known not to be permitted.

3. Not known, either way.

A Map provides a natural representation of these three states:

1. The Class is a key, with value Boolean.TRUE, or equivalent.

2. The Class is a key, with value Boolean.FALSE, or equivalent.

3. The Class is not a key.

A Set can support only two alternatives. The Class is either in the set,
or not in the set. There is no way to distinguish lack of knowledge.

Patricia
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,995
Messages
2,570,236
Members
46,822
Latest member
israfaceZa

Latest Threads

Top