Home | Contact Us | FAQ | Search & Site Map | Link to Us
Sign In | Join | Other 45 Sites in Network
HomeAnnouncementsWhite Papers
Discussion GroupsFirst AidDatabasesJavaBeansGUIJava 3DVirtual MachineCORBASecurityToolsGeneral
Java DirectoryOpen Source ProjectsSample Book ChaptersUser GroupsWeb Resources
Related Topics
Databases.NETMore Topics ...

Java Forum / General / April 2007

Tip: Looking for answers? Try searching our database.

HashMap.put error in Xcode

Thread view: 
Composer - 22 Apr 2007 18:56 GMT
I'm using Apple's Xcode 1.1 and have had no big problem with it until
now.  I've created a HashMap and used the put() method to insert a
BitSet into it, but cannot get the compiler to like it.  A paraphrase
of my code:

import java.util.*;
HashMap hm = new HashMap(72);
BitSet bs = new BitSet(12);
hm.put(bs.hashCode(), bs);

The error message from Xcode is:

cannot resolve symbol : method put(int,java.util.BitSet)

If I change the BitSet to a String, or change the HashMap to a
Hashtable, I get the same error.  I don't understand this, because the
put() method takes an integer and an Object, and I believe that's what
I'm providing it.  Is it possible that Xcode 1.1 is doing something
wrong?  Thanks.
Mike Schilling - 22 Apr 2007 20:40 GMT
> I'm using Apple's Xcode 1.1 and have had no big problem with it until
> now.  I've created a HashMap and used the put() method to insert a
[quoted text clipped - 15 lines]
> I'm providing it.  Is it possible that Xcode 1.1 is doing something
> wrong?  Thanks.

HashMap requires an Object as the key.  This will compile if you code

   hm.put(new Integer(bs.hashCode()), bs);

But it seems unlikely that hashCode() will give you a useful key.  It's not
something you're likely to know if you don't already have the object handy,
nor is it guaranteed to be unique.  What are you trying to do?
Tom Hawtin - 22 Apr 2007 21:13 GMT
> import java.util.*;
> HashMap hm = new HashMap(72);
[quoted text clipped - 4 lines]
>
> cannot resolve symbol : method put(int,java.util.BitSet)

Firstly, a BitSet (or pretty much any type) will not have a unique hash
code. There can only be 2^32 hash codes, but there are many more
possibilities for BitSet. Would a Set be more appropriate?

Secondly, I suggest you use Java 1.5 (1.6 if you didn't have to put up
with Apple) and generics.

Thirdly, made up initials like 'hm' make the code very difficult to read.

Fourthly, It's much better to least specific types where you don't have
to mention the implementation. In this case, other than construction we
don't need to know you are using HashMap.

Fifthly, importing an entire package is rarely a good idea. It's
difficult to see where the types are coming from.

Anyway:

Assuming 1.4, you are trying to use an int where an Object is expected.
An int is a primitive, which are not Objects. So you need to 'box' the
int into some sort of Object. An Integer will do fine. So (ignoring the
non-uniqueness of hash codes; generics commented out):

import java.util.BitSet;
import java.util.Map;

Map/*<Integer,BitSet>*/ map =
    new java.util.HashMap/*<Integer,BitSet>*/(72);
BitSet bits = new BitSet(12);
map.put(new Integer(bits.hashCode()), bits);

Tom Hawtin
Composer - 22 Apr 2007 22:13 GMT
Humble apologies to all.
I didn't look closely enough at the HashMap.put() documentation.  Of
course you're right;  it takes two Objects.  I had misinterpreted what
my 1999 Sams book said:  "Any class that defines a hashCode() method
can be efficiently stored and accessed in a hash table."  Since the
hashCode() methods of BitSet and String return an int, I assumed that
an int would be suitable as a key in a HashMap.  I was wrong.

(Why do these classes have a hashCode() method, if it doesn't create a
unique key?)

To answer why I was using a HashMap in the first place, I expect the
user to generate a large number of 12-bit BitSets.  I want to do 2
things with them:  de-duplicate them before adding them to a list,
then draw certain subsets from the list based on certain bits in each
BitSet being on or off.  It seemed that a BitSet, with its and() and
or() methods, would support the second objective, and storing the
BitSets in a HashMap would allow easy de-duplication and speedy
searching.

If it's true that the hashCode() method won't reliably give me a
unique key for each BitSet, then I could create my own;  maybe a short
(16 bit) number could be created in which the first 12 bits are
significant.  But maybe I should abandon the whole idea of hash codes
and keys, and simply put all my BitSets into a Vector, which I would
search manually using the BitSet.equals() method.

Although I've created several small Java applications, I'm not a
professional Java programmer, so if I can continue using a free
environment like Xcode it would be economic.  That means, at the
present, that 1.4.2 is my upper limit for Java versions.

Thanks very much for your speedy help.
zero - 22 Apr 2007 22:26 GMT
Composer <composer@uwclub.net> wrote in news:1177276399.699379.294020
@q75g2000hsh.googlegroups.com:

> Although I've created several small Java applications, I'm not a
> professional Java programmer, so if I can continue using a free
> environment like Xcode it would be economic.  That means, at the
> present, that 1.4.2 is my upper limit for Java versions.

All you need to develop java applications is the SDK, which is free, and a
text editor.  Even if you want an integrated environment, there are plenty
of choices besides Xcode, with eclipse probably being the most popular.

Anyway, unless you need to support Panther, you can switch to 1.5.  
Unfortunately 1.5 doesn't run under Panther, but Tiger and Leopard are no
problem.  I'm not 100% sure Xcode can handle 1.5 (I think it can), but if
it can't you can just switch to a different editor.

Zero
Patricia Shanahan - 22 Apr 2007 22:39 GMT
> Humble apologies to all.
> I didn't look closely enough at the HashMap.put() documentation.  Of
[quoted text clipped - 6 lines]
> (Why do these classes have a hashCode() method, if it doesn't create a
> unique key?)

The point of hash-based data structures is to partition the keys, based
on a hash code, so that only a subset of the keys in the data structure
need to be searched for any given access.

> To answer why I was using a HashMap in the first place, I expect the
> user to generate a large number of 12-bit BitSets.  I want to do 2
[quoted text clipped - 11 lines]
> and keys, and simply put all my BitSets into a Vector, which I would
> search manually using the BitSet.equals() method.

I still don't see why you cannot use a HashMap with BitSet keys. It is
VERY unlikely that your BitSet instances all have the same hash code,
and that is what it would take to make a HashMap access as inefficient
as a linear search of a Vector.

Or use a HashSet of BitSet elements.

You could probably do the task more efficiently using short, if you
designed your data structures carefully, but it would be more work.

Patricia
Tom Hawtin - 23 Apr 2007 00:09 GMT
> To answer why I was using a HashMap in the first place, I expect the
> user to generate a large number of 12-bit BitSets.  I want to do 2
[quoted text clipped - 4 lines]
> BitSets in a HashMap would allow easy de-duplication and speedy
> searching.

It seems that a HashSet/*<BitSet>*/ would remove duplicates for you fine.

As for searching, it depends upon your criteria. If it's an exact match,
a HashSet should be fine. If you need ranges, then a TreeSet/*<BitSet>*/
(that is a SortedSet, of NavigableSet in 1.6) with an appropriate
Comparator would be fine. Anything more complicated and you're looking
multiple maps, or scanning the entire set of BitSets.

If you are only dealing with 12-bits, you can easily use an int instead
of a BitSet (there's not much point in using a short, unless you have
large arrays of them). 12-bits only gives you 4096 possibilities, which
would be small on a Vic 20. If you have an int instead of BitSet, and
it's only 12 bits, then you can use the int as an index into a BitSet or
an array. That will give you fast scanning (if you are prepared not to
create BitSets as you scanned).

Tom Hawtin
Daniel Pitts - 23 Apr 2007 04:27 GMT
> Humble apologies to all.
> I didn't look closely enough at the HashMap.put() documentation.  Of
[quoted text clipped - 3 lines]
> hashCode() methods of BitSet and String return an int, I assumed that
> an int would be suitable as a key in a HashMap.  I was wrong.
The Key to a hashmap is an actual key, not the hash of the key.
HashMap calls hashCode() on the key in order to partition the keys in
to easy-to-find buckets.

> (Why do these classes have a hashCode() method, if it doesn't create a
> unique key?)
Like whats been stated alread, hashCode() returns a "hash", which is
*likely* to be different between two objects. This lets you store them
in different locations.  Think of it like sorting your clothes by
color.  The color is the hash code. You know you want a red shirt, so
you first look for "reds", then you search for "shirt".

> To answer why I was using a HashMap in the first place, I expect the
> user to generate a large number of 12-bit BitSets.  I want to do 2
[quoted text clipped - 4 lines]
> BitSets in a HashMap would allow easy de-duplication and speedy
> searching.
A couple of things here.  First, BitSets are a bit overkill for 12
bits.  I suggest using a simple integer, or at least a custom wrapper
around an int.  BitSets contain an array of longs, so you don't gain
any space benefit from using BitSet instead of "int".  Although you
might get some clarity, depends on what your doing.

Second, you should use a Set, (not a map) to remove duplicates.

> If it's true that the hashCode() method won't reliably give me a
> unique key for each BitSet, then I could create my own;  maybe a short
> (16 bit) number could be created in which the first 12 bits are
> significant.  But maybe I should abandon the whole idea of hash codes
> and keys, and simply put all my BitSets into a Vector, which I would
> search manually using the BitSet.equals() method.

Or, put them into an ArrayList, and call List.contains() on them :-)

> Although I've created several small Java applications, I'm not a
> professional Java programmer, so if I can continue using a free
> environment like Xcode it would be economic.  That means, at the
> present, that 1.4.2 is my upper limit for Java versions.

I believe Eclipse is free, although I use IntelliJ IDEA, and it does
cost money.  You can install JDK 1.5+ and use any text editor to edit
classes, although a good IDE is definitely worth a bit of money.

> Thanks very much for your speedy help.

I hope this does indeed help you.
Good luck,
Daniel.
Composer - 23 Apr 2007 13:11 GMT
Thanks again to all.

I have thought more clearly now, and abandoned the hash code approach
in favor of putting the BitSets into an ArrayList, and calling
List.contains() on them.  This is an easy solution to my de-
duplicating requirement when building the list.  Thanks.

When searching the list for sets having specific bits turned on or
off, I have to inspect every set in the ArrayList;  there is no "key"
that would have helped this operation.  So I really just needed an
Iterator for this requirement.

An int would do the job instead of a BitSet.  But I'm still using
BitSet because I have to do other operations on the sets (rotation,
inversion) and I find these easier than bit operations.  It's a single-
user, small-scale application, and I don't expect memory to be an
issue.

Thanks again, all.
Daniel Pitts - 23 Apr 2007 16:11 GMT
> Thanks again to all.
>
[quoted text clipped - 15 lines]
>
> Thanks again, all.

public class BitSetCollection {
  List<BitSet> all = new ArrayList<BitSet>();
  Map<Integer, List<BitSet>> withBitSet = new HashMap<Integer,
List<BitSet>>();
  public void addBitSet(BitSet bs) {
     if (all.contains(bs)) {
       return;
     }
     for (int i = 0; i < 12; ++i) {
       if (bs.get(i)) {
         List<BitSet> sets = withBitSet.get(new Integer(i));
         if (sets == null) {
            sets = new ArrayList<BitSet>();
            withBitSet.put(new Integer(i), sets);
         }
         sets.add(i);
       }
     }
  }

  public List<BitSet> withBitSet(int bit) {
     return withBitSet.get(new Integer(i));
  }
}

As a starting point :-)


Free Magazines

Get these publications absolutely FREE for up to 12 months. There are no hidden fees and no obligation. Simply choose a title, complete the application form and submit it. Read more ...

Oracle MagazineNetwork ComputingComputer WorldBio-IT WorldeWeekInformation WeekInfosecurity
 
Sign In
Join
My Latest Posts
My Monitored Threads
My Blog
My Photo Gallery
My Profile
My Homepage

Start New Thread
Enable EMail Alerts
Rate this Thread



©2009 Advenet LLC   Privacy Policy - Terms of Use
This website includes both content owned or controlled by Advenet as well as content owned or controlled by third parties.