an array in a hashtable

J

joez3

Hi,
Can someone help me out? I am trying to create a hashtable where the
values are arrays. So in my code I have:
Hashtable moves = new Hashtable();
moves.put (11, new Integer[]{2,3,3,2});
moves.put (21, new Integer[]{1,3,3,3});

Now how do I access the items in the array? When I do:
System.out.println("\n :"+moves.get(11)+": \n");
I get something like:
:[Ljava.lang.Integer;@10b62c9:
Is this a pointer to the array? How can I access each item in the
array?

Thanks,
Zim
 
C

Chris Uppal

Hashtable moves = new Hashtable();
moves.put (11, new Integer[]{2,3,3,2});
moves.put (21, new Integer[]{1,3,3,3});

Now how do I access the items in the array? When I do:
System.out.println("\n :"+moves.get(11)+": \n");
I get something like:
:[Ljava.lang.Integer;@10b62c9:

Since you put an array of Integers into the array under key
Integer.valueOf(11), when you look for the object at that index, that (you hope
;-) is what you'll find -- an array of Integers.

If you want one of the integers /in/ that array then you'll have to dereference
it.
(moves.get(11))[3]
(you may need a cast if you are not using Generics -- or if Generics screw up
this particular case).

You code might be wanting to print all the moves from the array, in which case
you could use a loop, or use the utilitiy method
java.utils.Arrays.toString(Object[]) to obtain a "nice" representation fo the
contents of the array.

-- chris
 
R

ricky.clarkson

With generics, this is fairly straightforward, despite Chris Uppal's
misgivings:

Map<Integer,int[]> map=new HashMap<Integer,int[]>();

map.put(11,new int[]{2,3,3,2});
map.get(11)[2]=5;
System.out.println(map.get(11)[2]);
 
T

Thomas Hawtin

With generics, this is fairly straightforward, despite Chris Uppal's
misgivings:

Map<Integer,int[]> map=new HashMap<Integer,int[]>();

map.put(11,new int[]{2,3,3,2});
map.get(11)[2]=5;

It's probably arrays of generic types that Chris was thinking about.
With generics, you might as well avoid arrays of all reference types.

The other worrying thing is that auto[un]boxing can behave a little
strangely. For instance the following code:

class Box {
public static void main(String[] args) {
java.util.List<Integer> list =
new java.util.ArrayList<Integer>();
list.add(1001);
list.add(1002);
list.remove(1001);
System.out.println(list.size());
}
}

Guess what it prints, and then try it.

Tom Hawtin
 
R

ricky.clarkson

Heh, I fell for that one. I was expecting 1, and half expecting 2, and
to discover that Integer.equals or hashCode was broken..

That's more of an issue with overloading. When remove(int) and
remove(Integer) are available, Java will pick int if it can, the
closest match.

That is not a fault of generics, but of the collections APIs, and
possibly of Java, allowing overloading at all (beyond the scope of
this).

You might as well avoid arrays of reference types, yes, because they
are statically broken in Java (but sound at runtime).

Integer[] ints={1,2,3};
Number[] numbers=ints;
number[0]=6.0; //ArrayStoreException, the runtime catches what the
compiler doesn't.

The problem with generics and reference types is that, because arrays
are statically broken, the runtime needs to know the type of an array.
Because generics are not statically broken, the runtime doesn't need to
know the generic type parameter. I'm rather surprised that there is
nothing like Array.newInstance, but that returns a T[] instead of
Object. Maybe there is and I missed it, but Angelika Langer doesn't
mention anything..
http://www.angelikalanger.com/Articles/Papers/JavaGenerics/ArraysInJavaGenerics.htm

Thomas said:
With generics, this is fairly straightforward, despite Chris Uppal's
misgivings:

Map<Integer,int[]> map=new HashMap<Integer,int[]>();

map.put(11,new int[]{2,3,3,2});
map.get(11)[2]=5;

It's probably arrays of generic types that Chris was thinking about.
With generics, you might as well avoid arrays of all reference types.

The other worrying thing is that auto[un]boxing can behave a little
strangely. For instance the following code:

class Box {
public static void main(String[] args) {
java.util.List<Integer> list =
new java.util.ArrayList<Integer>();
list.add(1001);
list.add(1002);
list.remove(1001);
System.out.println(list.size());
}
}

Guess what it prints, and then try it.

Tom Hawtin
 
R

ricky.clarkson

Part of that should have read:

"The problem with generics and arrays"

rather than:

"The problem with generics and reference types"

Heh, I fell for that one. I was expecting 1, and half expecting 2, and
to discover that Integer.equals or hashCode was broken..

That's more of an issue with overloading. When remove(int) and
remove(Integer) are available, Java will pick int if it can, the
closest match.

That is not a fault of generics, but of the collections APIs, and
possibly of Java, allowing overloading at all (beyond the scope of
this).

You might as well avoid arrays of reference types, yes, because they
are statically broken in Java (but sound at runtime).

Integer[] ints={1,2,3};
Number[] numbers=ints;
number[0]=6.0; //ArrayStoreException, the runtime catches what the
compiler doesn't.

The problem with generics and reference types is that, because arrays
are statically broken, the runtime needs to know the type of an array.
Because generics are not statically broken, the runtime doesn't need to
know the generic type parameter. I'm rather surprised that there is
nothing like Array.newInstance, but that returns a T[] instead of
Object. Maybe there is and I missed it, but Angelika Langer doesn't
mention anything..
http://www.angelikalanger.com/Articles/Papers/JavaGenerics/ArraysInJavaGenerics.htm

Thomas said:
With generics, this is fairly straightforward, despite Chris Uppal's
misgivings:

Map<Integer,int[]> map=new HashMap<Integer,int[]>();

map.put(11,new int[]{2,3,3,2});
map.get(11)[2]=5;

It's probably arrays of generic types that Chris was thinking about.
With generics, you might as well avoid arrays of all reference types.

The other worrying thing is that auto[un]boxing can behave a little
strangely. For instance the following code:

class Box {
public static void main(String[] args) {
java.util.List<Integer> list =
new java.util.ArrayList<Integer>();
list.add(1001);
list.add(1002);
list.remove(1001);
System.out.println(list.size());
}
}

Guess what it prints, and then try it.

Tom Hawtin
 
C

Chris Uppal

Thomas said:
It's probably arrays of generic types that Chris was thinking about.
With generics, you might as well avoid arrays of all reference types.

More accurately, I wasn't thinking at all -- I remembered problems with arrays
and generics, and couldn't be bothered to check/think about whether this
specific case was applicable. Not very professional, but it was only a
qualification of a qualification...

class Box {
public static void main(String[] args) {
java.util.List<Integer> list =
new java.util.ArrayList<Integer>();
list.add(1001);
list.add(1002);
list.remove(1001);
System.out.println(list.size());
}
}

/Very/ nice example.

-- chris
 
H

Hendrik Maryns

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1
class Box {
public static void main(String[] args) {
java.util.List<Integer> list =
new java.util.ArrayList<Integer>();
list.add(1001);
list.add(1002);
list.remove(1001);
System.out.println(list.size());
}
}

/Very/ nice example.

Although it is the same problem as short conversion to ints. So I don’t
consider this a particularly strong argument against autoboxing, but
rather one more against the whole automatic conversion thing.

H.
- --
Hendrik Maryns
http://tcl.sfs.uni-tuebingen.de/~hendrik/
==================
http://aouw.org
Ask smart questions, get good answers:
http://www.catb.org/~esr/faqs/smart-questions.html
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.2 (GNU/Linux)

iD8DBQFE/UAle+7xMGD3itQRAjCrAJoDYnyJhk0h1kAJguKGnB3iIoVyOACfdUKf
0H56C1BmFUhmeaNcGVUEWjg=
=awFA
-----END PGP SIGNATURE-----
 
C

Chris Uppal

Hendrik said:
class Box {
public static void main(String[] args) {
java.util.List<Integer> list =
new java.util.ArrayList<Integer>();
list.add(1001);
list.add(1002);
list.remove(1001);
System.out.println(list.size());
}
}

/Very/ nice example.

Although it is the same problem as short conversion to ints. So I don't
consider this a particularly strong argument against autoboxing, but
rather one more against the whole automatic conversion thing.

While I agree that the combination of method overloading and automatic
conversion leads (at least potentially) to confusion, I don't think I'd go so
far as to blame the above example on that. I don't think it would be possible
to achieve the effect of Thomas's masterful indirection without the more
powerful intuition-breaking possibilities of autoboxing.

It would probably be possible to concoct an example which misbehaved as badly
using only the conversions in Java before 1.5, but I think the API would be
obviously artificial. In this case an /existing/, and not obviously crap[*],
API has been broken by autoboxing.

-- chris

[*] a bit dodgy, but not to the point where I remember anyone ever pointing it
out, or complaining about it.
 
R

ricky.clarkson

At least it shouldn't be too hard to make pmd, checkstyle, your
favourite IDE, etc., flag that up as a dodgy area, calling remove(int)
on a List<Integer>. I'm not sure what you could do about it though, to
shut the checker up. Putting an explicit cast to int in? First
assigning it to a List<?>? Neither seems satisfactory.

Maybe deprecate it and use a static utility method to get at it.
That'd be popular..

I'll be even more careful to avoid overloading in my future APIs.

Nice discussion.

Chris said:
Hendrik said:
class Box {
public static void main(String[] args) {
java.util.List<Integer> list =
new java.util.ArrayList<Integer>();
list.add(1001);
list.add(1002);
list.remove(1001);
System.out.println(list.size());
}
}

/Very/ nice example.

Although it is the same problem as short conversion to ints. So I don't
consider this a particularly strong argument against autoboxing, but
rather one more against the whole automatic conversion thing.

While I agree that the combination of method overloading and automatic
conversion leads (at least potentially) to confusion, I don't think I'd go so
far as to blame the above example on that. I don't think it would be possible
to achieve the effect of Thomas's masterful indirection without the more
powerful intuition-breaking possibilities of autoboxing.

It would probably be possible to concoct an example which misbehaved as badly
using only the conversions in Java before 1.5, but I think the API would be
obviously artificial. In this case an /existing/, and not obviously crap[*],
API has been broken by autoboxing.

-- chris

[*] a bit dodgy, but not to the point where I remember anyone ever pointing it
out, or complaining about it.
 
C

Chris Uppal

At least it shouldn't be too hard to make pmd, checkstyle, your
favourite IDE, etc., flag that up as a dodgy area, calling remove(int)
on a List<Integer>. I'm not sure what you could do about it though, to
shut the checker up. Putting an explicit cast to int in? First
assigning it to a List<?>? Neither seems satisfactory.

Probably better to configure your electronic nanny to whinge about autoboxing.
That way you could tell there was something odd about the call to remove(int),
since the nanny wouldn't be complaining about it.

Sort of like the way you can tell when your car has been stolen, because you
can't hear the burglar alarm going off anymore...

-- chris
 
R

ricky.clarkson

I used to do that, then realised it wasn't worth the effort. Most of
the time it doesn't cause me a problem, and the resulting code from
autoboxing and autounboxing is clearer than Integer.valueOf(int).

Consider this:

private static <Key> int sum(final Function<Key, Integer> function,
final Iterable<Key> keys)
{
int total=0;

for (final Key key : keys)
total+=function.run(key);

return total;
}

compared to the alternative, total+=function.run(key).intValue(); It
does the same thing, but is harder to read, slightly. I should have
dug for a more involved case. ;)

I wouldn't enable this warning now, because I'd expect to see so many
warnings that I would ignore more important warnings. I'd rather use a
different API that didn't overload, or at least didn't overload in a
possibly-ambiguous way.
 
T

Thomas Hawtin

Chris said:
While I agree that the combination of method overloading and automatic
conversion leads (at least potentially) to confusion, I don't think I'd go so
far as to blame the above example on that. I don't think it would be possible
to achieve the effect of Thomas's masterful indirection without the more
powerful intuition-breaking possibilities of autoboxing.

It would probably be possible to concoct an example which misbehaved as badly
using only the conversions in Java before 1.5, but I think the API would be
obviously artificial. In this case an /existing/, and not obviously crap[*],
API has been broken by autoboxing.

I think somewhere in the interview below Josh talks about Effective Java
(Item 26) needing tightening up with respect to overloading. The old
collections with "Element" everywhere were a bit clumsy. If List was
written now, it would still have Vector's "At"s.

http://media.libsyn.com/media/javapolis/Joshua_Bloch_and_Neal_Gafter_interview.mp3

If you though autoboxing of primitives was a bit unpleasant, you should
see the proposed autoboxing of closures.

JButton button = new JButton("Click here");
void listener(ActionEvent event) {
button.setText("Clicked");
}
button.addActionListener(listener);
button.removeActionListener(listener);

Now is the listener still applied to the button? It might be, or it
might not. The function type is implicitly boxed. Possibly to a new
object each time. As listener removal is based on ==, using a different
wrapper object will not work.

Tom Hawtin
 
C

Chris Uppal

Thomas said:
If you though autoboxing of primitives was a bit unpleasant, you should
see the proposed autoboxing of closures.

God help us !

Something has gone very, very, badly wrong with the maintenance and development
of Java.

-- chris
 
P

Patricia Shanahan

Chris said:
God help us !

Something has gone very, very, badly wrong with the maintenance and development
of Java.

The KISS principle that drove much of the earlier design of Java seems
to have got lost somewhere along the way. The result is an odd mixture
of limitations whose payoff is simplicity, but without the payoff
because other things make it complicated.

Patricia
 
C

Chris Uppal

Patricia Shanahan wrote:

[me:]
The KISS principle that drove much of the earlier design of Java seems
to have got lost somewhere along the way. The result is an odd mixture
of limitations whose payoff is simplicity, but without the payoff
because other things make it complicated.

<nods sadly/>

-- chris
 

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,773
Messages
2,569,594
Members
45,121
Latest member
LowellMcGu
Top