Indexing by multiple keys

  • Thread starter nooneinparticular314159
  • Start date
N

nooneinparticular314159

I would like to use an object that behaves like a hashmap (ie. put,
get, with a key), but I'd like to be able to index items in that
object by more than one key.

Is there a way to do this?

Ie. if I had a name for the objects I'm adding as well as a social
security number, I'd like to be able to return the object by either
name or number depending on need. Is there an object that does this,
or do I have to write it myself?

Thanks!
 
A

Arne Vajhøj

I would like to use an object that behaves like a hashmap (ie. put,
get, with a key), but I'd like to be able to index items in that
object by more than one key.

Is there a way to do this?

Ie. if I had a name for the objects I'm adding as well as a social
security number, I'd like to be able to return the object by either
name or number depending on need. Is there an object that does this,
or do I have to write it myself?

You can create your own SuperHaspMap with .put(k1, k2, val) and
..getByKey1(k1) and .getByKey2(k2) methods.

But usually you would just put the same objects in two different
HashMap's.

(since the HashMap only stores a ref to the objects not a copy,
then that works fine)

Arne
 
M

markspace

I would like to use an object that behaves like a hashmap (ie. put,
get, with a key), but I'd like to be able to index items in that
object by more than one key.

Is there a way to do this?

Ie. if I had a name for the objects I'm adding as well as a social
security number, I'd like to be able to return the object by either
name or number depending on need. Is there an object that does this,
or do I have to write it myself?


You can put the same object in more than once, with different keys.
This is a little less safe in terms of programmer usage, but works fine.

class Person {
int ssn;
String name = "";
}

HashMap<Object,Person> map = new HashMap<Object,Person>();

Person person = new Person();
map.put( person.ssn, person );
map.put( person.name, person );

Now "person" is in the map twice, once under SSN and once by their name.
As Arne said, this is done by reference so there's no wasted space or
extra copies or anything bad like that.
 
N

nooneinparticular314159

Ok, let's say I put the same object in the map twice. Doesn't that
mean that if I try to delete it, I have to know both keys in order for
it to succeed?
 
A

Arne Vajhøj

nooneinparticular314159 said:
Ok, let's say I put the same object in the map twice. Doesn't that
mean that if I try to delete it, I have to know both keys in order for
it to succeed?

If you have two maps, then you would need to delete it from both.

Arne
 
R

Roedy Green

On Fri, 31 Jul 2009 14:35:56 -0700 (PDT),
I would like to use an object that behaves like a hashmap (ie. put,
get, with a key), but I'd like to be able to index items in that
object by more than one key.

You could do this with two HashMaps, or with one HashMap where you do
a put with two different keys and the same value object. HashMap is
really concerned only with the keys. It does not care it two keys
point to the same object.
--
Roedy Green Canadian Mind Products
http://mindprod.com

"Patriotism is fierce as a fever, pitiless as the grave, blind as a stone, and as irrational as a headless hen."
~ Ambrose Bierce (born: 1842-06-24 died: 1914 at age: 71)
 
M

markspace

nooneinparticular314159 said:
Ok, let's say I put the same object in the map twice. Doesn't that
mean that if I try to delete it, I have to know both keys in order for
it to succeed?


Almost certainly yes, for correct operation.
 
L

Lew

Almost certainly yes, for correct operation.

You don't put objects into maps, you put references into maps.

If you have two different keys, say a name string (reference) and a
social-security-number string (reference), that retrieve the same value
(reference) from the same map, both keys need to go away for the value to be
removed from the map.
 
L

Lew

markspace said:
You can put the same object in more than once, with different keys. This
is a little less safe in terms of programmer usage, but works fine.

class Person {
int ssn;

A Social Security Number is a string, not an int. Were you to foolishly
represent it as a numeric type, an int wouldn't hold the range of values.
String name = "";
}

HashMap<Object,Person> map = new HashMap<Object,Person>();

Say, rather,

Map said:
Person person = new Person();
map.put( person.ssn, person );
map.put( person.name, person );

Now "person" is in the map twice, once under SSN and once by their name.
As Arne said, this is done by reference so there's no wasted space or
extra copies or anything bad like that.

There could be wasted space. Using your example:

map.put( person.name, person );
map.put( new String( person.name ), person );

will create two instances of name strings with the same value, neither of
which can be GCed while the person lives and is in the map.

I also fear it will create two entries in the map. While 'equals()' is
polymorphic, it also has to handle comparing String to Integer.
 
A

Arne Vajhøj

Lew said:
A Social Security Number is a string, not an int. Were you to foolishly
represent it as a numeric type, an int wouldn't hold the range of values.

Depends on the country.

But US SSN's has only 9 digits - correct ? (and that can be in an int)
Say, rather,



There could be wasted space. Using your example:

map.put( person.name, person );
map.put( new String( person.name ), person );

will create two instances of name strings with the same value, neither
of which can be GCed while the person lives and is in the map.

True.

But I can not see any reason for doing that.

Arne
 
A

Arne Vajhøj

Lew said:
There could be wasted space. Using your example:

map.put( person.name, person );
map.put( new String( person.name ), person );
I also fear it will create two entries in the map.

Not if it is java.lang.String.

Arne
 
M

markspace

markspace said:
2^31 = 2147483648
0xxxyyzzzz = ssn xxx-yy-zzzz


This example looks right while I type this reply but seemed to have
extra spaces in the second line when being viewed by Thunderbird. Line
up the 2147483648 and the 0xxxyyzzzz to see what I'm trying to display
there.

2147483648 = 2^31
0xxxyyzzzz = ssn xxx-yy-zzzz

There, that should line up regardless.
 
J

Joshua Cranmer

markspace said:
This example looks right while I type this reply but seemed to have
extra spaces in the second line when being viewed by Thunderbird. Line
up the 2147483648 and the 0xxxyyzzzz to see what I'm trying to display
there.

The text-to-html converter swallowed the ^ when making the letters
superscript: there's your missing space.
 
M

markspace

Joshua said:
The text-to-html converter swallowed the ^ when making the letters
superscript: there's your missing space.


I hate it when programs try to "improve" my ASCII. :)
 
L

Lew

I did a quick check before I posted that, maybe I miscounted:

2^31 = 2147483648
0xxxyyzzzz = ssn xxx-yy-zzzz

Silly me.

I must have been counting the dashes.

Everyone who corrected me on that point is correct, of course.

An SSN is still not numeric, though.
 
L

Lew

Peter said:
> It's true that, with the first string coming from the Person instance,
> having that entry no longer in the HashMap won't allow the string
> instance to be GC'ed (it's still referenced by the Person instance).
> But if you reverse the order, so that the newly constructed string is
> added first, then when the second call to put() happens, that first
> newly constructed string will be collectable (assuming no other code,
> where it's retained elsewhere, of course).

Sure, but my point was a response to the notion that the Map as construed in
the example unequivocally would have "no wasted space or extra copies or
anything bad like that". All it took was one example of how that isn't true.
 
A

Arved Sandstrom

Lew said:
Silly me.

I must have been counting the dashes.

Everyone who corrected me on that point is correct, of course.

An SSN is still not numeric, though.
It's numeric, consisting of 3 numbers. Even the SSA says so. It's not a
string. It's just that it makes little or no sense to contemplate
arithmetic operations involving SSNs, except perhaps for incrementing
the serial number part.

AHS
 
L

Lew

Arved said:
It's numeric, consisting of 3 numbers. Even the SSA says so.

Where does it say so?
It's not a string. It's just that it makes little or no sense to contemplate
arithmetic operations involving SSNs, except perhaps for incrementing
the serial number part.

If you simply increment the serial number part, you could break the checksum,
so that operation isn't actually valid.
 
A

Arved Sandstrom

Lew said:
Where does it say so?

Without being facetious, all over their website, including at
http://www.socialsecurity.gov/history/ssn/geocard.html.

The group number and serial number definitely use numerical concepts
(like odd and even for group number).
If you simply increment the serial number part, you could break the
checksum, so that operation isn't actually valid.

What is the checksum procedure for a SSN? I wasn't aware there was any.
The SSA does not describe any kind of checksum procedure for figuring
out whether an SSN is valid. There is a procedure of course for doing so.

AHS
 

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,999
Messages
2,570,246
Members
46,842
Latest member
MableIwk73

Latest Threads

Top