Go Back   Velocity Reviews > Newsgroups > Java
User Name
Password
Register FAQ Members List Calendar Search Today's Posts Mark Forums Read

Reply

Java - Using java.util.map

 
Thread Tools Search this Thread
Old 08-15-2006, 01:33 PM   #1
Default Using java.util.map


I sincerely hope I'm missing something about how java.util.map can be
used, but it seems that there is no way to update a single value
without traversing the map twice, at least not cleanly. As an
example, consider this code taken from the Sun autoboxing example:

public static void main(String[] args) {
Map<String, Integer> m = new TreeMap<String, Integer>();
for (String word : args) {
Integer freq = m.get(word);
m.put(word, (freq == null ? 1 : freq + 1));
}
}

Notice how both get() and put() are invoked. Clearly this means that
the map is traversed twice - once to find the value, and once to
figure out where to put a new value (which happens to be the same
place!). In C++ (where I come from), maps contain objects of type
pair<key, value>, and one can therefore retrieve the pair<> in
question and update the value with only one traversal of the map. Is
there any way to avoid two traversals in Java short of writing a kludgy
wrapper object such as

class WrapsAnInt {
private int wrapped;

public WrapsAnInt( int w ) { wrapped = w; }
public void setWrapped( int w ) { wrapped = w; }
public int getWrapped() { return wrapped; }
}

and put *those* in the map? If not, why didn't Java simply introduce
the concept of a pair<> like C++ did and fix the problem?

--
C. Benson Manica | I *should* know what I'm talking about - if I
cbmanica(at)gmail.com | don't, I need to know. Flames welcome.


Christopher Benson-Manica
  Reply With Quote
Old 08-15-2006, 02:08 PM   #2
Robert Klemme
 
Posts: n/a
Default Re: Using java.util.map
On 15.08.2006 14:33, Christopher Benson-Manica wrote:
> I sincerely hope I'm missing something about how java.util.map can be
> used, but it seems that there is no way to update a single value
> without traversing the map twice, at least not cleanly. As an
> example, consider this code taken from the Sun autoboxing example:
>
> public static void main(String[] args) {
> Map<String, Integer> m = new TreeMap<String, Integer>();
> for (String word : args) {
> Integer freq = m.get(word);
> m.put(word, (freq == null ? 1 : freq + 1));
> }
> }
>
> Notice how both get() and put() are invoked. Clearly this means that
> the map is traversed twice - once to find the value, and once to


Not the whole map is traversed twice. There are two lookups which take
O(log n) for the TreeMap and O(1) for the HashMap.

> figure out where to put a new value (which happens to be the same
> place!). In C++ (where I come from), maps contain objects of type
> pair<key, value>, and one can therefore retrieve the pair<> in
> question and update the value with only one traversal of the map. Is
> there any way to avoid two traversals in Java short of writing a kludgy
> wrapper object such as
>
> class WrapsAnInt {
> private int wrapped;
>
> public WrapsAnInt( int w ) { wrapped = w; }
> public void setWrapped( int w ) { wrapped = w; }
> public int getWrapped() { return wrapped; }
> }


If you're worried about performance writing a mutable Integer is the
best solution. Note that this class then also should inherit
java.lang.Number.

Also, use a HashMap which does faster lookups.

> and put *those* in the map? If not, why didn't Java simply introduce
> the concept of a pair<> like C++ did and fix the problem?


Java != C++

Cheers

robert


Robert Klemme
  Reply With Quote
Old 08-15-2006, 02:13 PM   #3
Stefan Ram
 
Posts: n/a
Default Re: Using java.util.map
Christopher Benson-Manica <> writes:
>In C++ (where I come from), maps contain objects of type pair<key, value>,


In Java, we have

http://download.java.net/jdk6/docs/a...Map.Entry.html

>and one can therefore retrieve the pair<> in question


But we can not retrieve it as needed.

Maybe, you should use another implementation of maps
then that of the Java SE or implement your own map.



Stefan Ram
  Reply With Quote
Old 08-15-2006, 03:14 PM   #4
Thomas Weidenfeller
 
Posts: n/a
Default Re: Using java.util.map
F'up set.

Christopher Benson-Manica wrote:
> I sincerely hope I'm missing something about how java.util.map can be
> used, but it seems that there is no way to update a single value
> without traversing the map twice, at least not cleanly.


a) You don't traverse the map twice (traversing means systematically
visiting every entry). You perform a lookup and an insertion. Only if
these operations degenerate each element in the map would have been visited.

b) You assume that the C++ way is clean (with the need to explicitly
create an extra pair<K,T> object for each entry), and the Java way is dirty.

I claim the C++ way is dirty, because it exposes implementation interna.

c) You claim there is an equivalent of the get() method in C++ for maps,
which return a pair<K,T>. To the best of my knowledge, there isn't. You
get pairs when you iterate over a C++ map (which is not done in the Java
example), or you get references to values when you use the index
operator[], but nor pairs.

d) You can get the equivalent of (artificially created) pairs when you
treat a Map as a Set and iterate over the set - just like iterating over
a C++ map.

> Notice how both get() and put() are invoked. Clearly this means that
> the map is traversed twice


Clearly it doesn't mean that.

> Is
> there any way to avoid two traversals in Java short of writing a kludgy
> wrapper object such as


That kludge is in fact a re-creation of the C++ kludge. You are adding
another level of indirection. Which is what the C++ pair<K,T> provides
in the first place in C++.

> and put *those* in the map? If not, why didn't Java simply introduce
> the concept of a pair<> like C++ did and fix the problem?


If you like C++'s way better, stay with C++.

/Thomas
--
The comp.lang.java.gui FAQ:
ftp://ftp.cs.uu.nl/pub/NEWS.ANSWERS/...g/java/gui/faq
http://www.uni-giessen.de/faq/archiv....java.gui.faq/


Thomas Weidenfeller
  Reply With Quote
Old 08-15-2006, 03:20 PM   #5
Patricia Shanahan
 
Posts: n/a
Default Re: Using java.util.map
Robert Klemme wrote:
....
> If you're worried about performance writing a mutable Integer is the
> best solution. Note that this class then also should inherit
> java.lang.Number.


Why inherit from java.lang.Number?

I had a situation like this, and wrote the following class, inside my
Counter class which has the HashMap:

private static class Count {
private int val = 0;

private void increment() {
val++;
}

private int get() {
return val;
}
}

It does everything the surrounding class needs it to do, and not one
thing more. You seem to saying that I should have implemented several
public methods that the surrounding class will never need, and no other
class can call except through reflection?

Patricia


Patricia Shanahan
  Reply With Quote
Old 08-15-2006, 03:26 PM   #6
Robert Klemme
 
Posts: n/a
Default Re: Using java.util.map
On 15.08.2006 16:20, Patricia Shanahan wrote:
> Robert Klemme wrote:
> ...
>> If you're worried about performance writing a mutable Integer is the
>> best solution. Note that this class then also should inherit
>> java.lang.Number.

>
> Why inherit from java.lang.Number?
>
> I had a situation like this, and wrote the following class, inside my
> Counter class which has the HashMap:
>
> private static class Count {
> private int val = 0;
>
> private void increment() {
> val++;
> }
>
> private int get() {
> return val;
> }
> }
>
> It does everything the surrounding class needs it to do, and not one
> thing more. You seem to saying that I should have implemented several
> public methods that the surrounding class will never need, and no other
> class can call except through reflection?


Of course you can do it this way. But if you frequently (i.e. in
different classes) need a mutable Integer / Float then IMHO it's better
to provide a more general implementation. And if that inherits
java.lang.Number (and implements methods as needed) then it can also be
used in contexts that deal with Number so it's more generally usable.
This should probably be in the standard lib anyway.

My 0.02EUR

Kind regards

robert


Robert Klemme
  Reply With Quote
Old 08-15-2006, 05:19 PM   #7
Christopher Benson-Manica
 
Posts: n/a
Default Re: Using java.util.map
Thomas Weidenfeller <> wrote:

> F'up set.


I have no idea why, and I don't read that group - I'm programming in
Java, and I just want to understand the Java way of doing this. I'm
setting them back to c.l.j.p, but if you really feel this discussion
belongs elsewhere, by all means set followup-to on your reply.

> a) You don't traverse the map twice (traversing means systematically
> visiting every entry). You perform a lookup and an insertion. Only if
> these operations degenerate each element in the map would have been visited.


You're right, "traverse" was not the right word.

> b) You assume that the C++ way is clean (with the need to explicitly
> create an extra pair<K,T> object for each entry), and the Java way is dirty.


I'm not saying Java is dirty, I'm just saying it seems to require two
lookups unless the programmer takes countermeasures.

> I claim the C++ way is dirty, because it exposes implementation interna.


It's certainly an arguable point.

> c) You claim there is an equivalent of the get() method in C++ for maps,
> which return a pair<K,T>. To the best of my knowledge, there isn't.


find( const key_type& x ) returns an iterator to the pair with key x,
if it exists.

> Clearly it doesn't mean that.


But the lookup is performed twice, yes?

> That kludge is in fact a re-creation of the C++ kludge. You are adding
> another level of indirection. Which is what the C++ pair<K,T> provides
> in the first place in C++.


Yes, it's exactly a recreation of the C++ kludge, and I'm just
astonished that apparently the desire for it is small enough that
isn't built into the java.util.map...

--
C. Benson Manica | I *should* know what I'm talking about - if I
cbmanica(at)gmail.com | don't, I need to know. Flames welcome.


Christopher Benson-Manica
  Reply With Quote
Old 08-15-2006, 05:23 PM   #8
Christopher Benson-Manica
 
Posts: n/a
Default Re: Using java.util.map
Robert Klemme <> wrote:

> Not the whole map is traversed twice. There are two lookups which take
> O(log n) for the TreeMap and O(1) for the HashMap.


Right, I definitely misspoke.

> If you're worried about performance writing a mutable Integer is the
> best solution.


Yes...

> Java != C++


Clearly But surely programmers have similar desires in both
languages, and I'm only curious why Java did not provide for this
specific desire.

--
C. Benson Manica | I *should* know what I'm talking about - if I
cbmanica(at)gmail.com | don't, I need to know. Flames welcome.


Christopher Benson-Manica
  Reply With Quote
Old 08-15-2006, 05:44 PM   #9
Patricia Shanahan
 
Posts: n/a
Default Re: Using java.util.map
Robert Klemme wrote:
> On 15.08.2006 16:20, Patricia Shanahan wrote:
>> Robert Klemme wrote:
>> ...
>>> If you're worried about performance writing a mutable Integer is the
>>> best solution. Note that this class then also should inherit
>>> java.lang.Number.

>>
>> Why inherit from java.lang.Number?
>>
>> I had a situation like this, and wrote the following class, inside my
>> Counter class which has the HashMap:
>>
>> private static class Count {
>> private int val = 0;
>>
>> private void increment() {
>> val++;
>> }
>>
>> private int get() {
>> return val;
>> }
>> }
>>
>> It does everything the surrounding class needs it to do, and not one
>> thing more. You seem to saying that I should have implemented several
>> public methods that the surrounding class will never need, and no other
>> class can call except through reflection?

>
> Of course you can do it this way. But if you frequently (i.e. in
> different classes) need a mutable Integer / Float then IMHO it's better
> to provide a more general implementation. And if that inherits
> java.lang.Number (and implements methods as needed) then it can also be
> used in contexts that deal with Number so it's more generally usable.
> This should probably be in the standard lib anyway.


Of course, if I found I generally needed a mutable integer, I might well
at some point refactor my code to use it instead of my Count class.
However, so far, I've had no need for a mutable integer.

Patricia


Patricia Shanahan
  Reply With Quote
Old 08-15-2006, 09:09 PM   #10
Lee Fesperman
 
Posts: n/a
Default Re: Using java.util.map
Patricia Shanahan wrote:
>
> Of course, if I found I generally needed a mutable integer, I might well
> at some point refactor my code to use it instead of my Count class.
> However, so far, I've had no need for a mutable integer.


I agree. Despite my attitude when I first started with Java, I've never found a need for
it. Later, I did implement a set of Mutable classes (integer, double, string) for our
ORDBMS. We use Java methods for Stored Procedures, and the Mutable classes were intended
to support standard semantics for Stored Procedures. Even though it is a pure Java
database system, we do provide an ODBC driver where this capability is more important.

--
Lee Fesperman, FFE Software, Inc. (http://www.firstsql.com)
================================================== ============
* The Ultimate DBMS is here!
* FirstSQL/J Object/Relational DBMS (http://www.firstsql.com)


Lee Fesperman
  Reply With Quote
Reply


Thread Tools Search this Thread
Search this Thread:

Advanced Search

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

vB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are Off
Pingbacks are Off
Refbacks are Off




SEO by vBSEO 3.3.2 ©2009, Crawlability, Inc.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46