Sorting maps by value

S

Spivee

I have seen several topics about this, but generally, they don't seem
very helpful, mostly stating that there is no built-in way to do it,
and that a custom solution must be created. Also, most posts say that
there shouldn't be a reason for it, but here's my current dilemma.

I am doing a struts based form page to manage our application servers
etc. I want to do a form page with a dropdown of all our servers, in
alphabetical order by servername.

I want a dropdown list of servers with the html tag value being the
server_id value from our database. Each server has two values, (of
interest to this issue), server_id, a unique row identifier, and
host_name. Hostname does not have to be unique since we have servers
in different environments that are named the same.

I want something like this..

<select name="server_id">
<option value="1">aserver1</option>
<option value="3">bserver2</option>
<option value="2">cserver3</option>
</select>

When I pull the data out of the db, I have been putting the values in a
hashmap, with key equal to server_id and value equal to host_name. I
then use logic:iterate or html:eek:ptions to print out the dropdown select
elements.

Something like this...

<html:select property="server_id">
<html:eek:ptions collection="servermap"
property="key"
labelProperty="value" />
</html:select>

The problem is that maps sort by key, so all my servers come out in the
order of server_id, nt host_name. Since two servers can have the same
name, I can't just invert the hashmap key/values.

I know I could probably do this with a custom solution, but that would
make a less than pretty jsp file. I doubt I could use any of the html
taglibs to do it. This just seems to me to be a basic type of thing
that would be done a lot in web based applications. I'm thinking
there's either a solution out there I'm unaware of or the process I'm
trying to use is flawed. Maybe there's an easier way for me to build
the map and the page.

Any suggestions would be helpful.
 
R

Roedy Green

The problem is that maps sort by key, so all my servers come out in the
order of server_id, nt host_name. Since two servers can have the same
name, I can't just invert the hashmap key/values.

There are at least two ways to skin this cat.

The simplest is to export the collection as an array and sort it
whenever you need the sorted order. see
http://mindprod.com/jgloss/sort.html


Another is to have multiple collections on the same set of objects,
e..g. a HashMap or TreeMap to look up by key and/or keep in a sorted
order.
see http://mindprod.com/jgloss/hashmap.html
http://mindprod.com/jgloss/treemap.html
 
D

Daniel Cer

I want a dropdown list of servers with the html tag value being the
server_id value from our database. Each server has two values, (of
interest to this issue), server_id, a unique row identifier, and
host_name. Hostname does not have to be unique since we have servers
in different environments that are named the same.
When I pull the data out of the db, I have been putting the values in a
hashmap, with key equal to server_id and value equal to host_name. I
then use logic:iterate or html:eek:ptions to print out the dropdown select
elements.

You could just have the database return the pairs in the appropriate
sorted order (think something like 'order by host_name'). Then, rather
than loading the key/value pairs into a HashMap, you could put them
into either an array/List in order to preserve the ordering.

dan
 
T

Tim B

Spivee said:
I am doing a struts based form page to manage our application servers
etc. I want to do a form page with a dropdown of all our servers, in
alphabetical order by servername.

check out org.apache.struts.util.LabelValueBean, a struts class designed
for this precise use. Its compareTo method sorts based on the label, so if
you just puts your query results in an ArrayList of LabelValueBeans instead
of a hashmap, and sort if necessary, you'll have just what you need.
 
S

surferjeff

Ideally, change the SQL to give you the rows in the order you need.
Appending "order by hostname, server_id" should give you the order you
need.

If you can't modify the SQL query, then don't use a HashMap. Use a
vector.

Create a private little class with public everything that just contains
the server_id and host_name. Override compare() so that it compares
hostname first, and then server_id. (Maybe vice-versa, I'm not sure
whether you want them sorted by hostname or server_id).

As you pull rows from the db, put the server_id and host_name into the
vector via instances of the little private class.

Then call java.util.Arrays.sort(vector.toArray()), and you're done.
 
M

Monique Y. Mudama

The problem is that maps sort by key, so all my servers come out in
the order of server_id, nt host_name. Since two servers can have
the same name, I can't just invert the hashmap key/values.

Does this mean that your users sometimes see more than one entry in
their dropdown that look identical, but behave differently when
clicked?
 
S

Spivee

Thanks all. I think LabelValueBean may be what I needed. I've worked
with it before, but didn't know it had a compareTo() method. Looking
at it quickly, I'm not sure how to use compareTo() to order a vector of
LabelValueBeans, but I'll probably be able to find something online to
help me out (Unless somebody'd be nice enough to give me an example :)
I'd tried ordering this with database queries prior to asking, but
because of the way this is working (and it would take too long to
explain) I can't really do that.

Monique, as to your question.. not really. I didn't specify in the
description because it was really out of scope, but the servers are
unique to an environment. I tack the environment on to the end of the
server name, so my dropdowns look more like...

<select name="server_id">
<option value="1">aserver1 - hosting</option>
<option value="3">bserver2 - intranet</option>
<option value="2">cserver3 - internet</option>
</select>
 
T

Tim B

Spivee said:
Thanks all. I think LabelValueBean may be what I needed. I've worked
with it before, but didn't know it had a compareTo() method. Looking
at it quickly, I'm not sure how to use compareTo() to order a vector of
LabelValueBeans, but I'll probably be able to find something online to
help me out (Unless somebody'd be nice enough to give me an example :)

Collections.sort(myListOfLvBeans); // sorts on label by default

by the way, performance-wise, you'd be better off using an ArrayList rather
than a Vector.
Vector is synchronized, which adds considerable overhead and provides no
benefit unless you actually need it, which in this case seems very unlikely.
 

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

Forum statistics

Threads
473,769
Messages
2,569,582
Members
45,058
Latest member
QQXCharlot

Latest Threads

Top