exporting a HashMap

R

Roedy Green

What is best code to export key-value pairs from a HashMap into some
structure in key-value order.

One possible way is to extract the keys, sort them, then look up the
values. That strikes me as infantile. Surely there is a better way.

The best I can think of is to invent a Pair dummy class, extract the
fields from an Entry into the two fields, and sort them in an array.

Part of the problem is generics and arrays don't mix.
 
E

Eric Sosman

What is best code to export key-value pairs from a HashMap into some
structure in key-value order.

One possible way is to extract the keys, sort them, then look up the
values. That strikes me as infantile. Surely there is a better way.

The best I can think of is to invent a Pair dummy class, extract the
fields from an Entry into the two fields, and sort them in an array.

Part of the problem is generics and arrays don't mix.

Why invent a Pair when Map.Entry already holds the data? Just
typed in, unchecked:

Map<K,V> map = ...;
List<Map.Entry<K,V>> entries =
new ArrayList<Map.Entry<K,V>>(map.entrySet());
Collections.sort(entries, new Comparator<Map.Entry<K,V>>() {
@Override
public int compare(Map.Entry<K,V> e1, Map.Entry<K,V> e2) {
return e1.getKey().compareTo(e2.getKey());
}
});
for (Map.Entry<K,V> e : entries) { ... }

There's scary Javadoc about the longevity of Map.Entry, but as long
as the underlying Map isn't changed all should be well.

Another approach is to use a SortedMap, either ab initio or as
a substitute for the List-and-sort above:

Map<K,V> map = ...;
SortedMap<K,V> map2 = new TreeMap<K,V>(map);
for (Map.Entry<K,V> e : map2.entrySet()) { ... }
 
A

Arne Vajhøj

What is best code to export key-value pairs from a HashMap into some
structure in key-value order.

One possible way is to extract the keys, sort them, then look up the
values. That strikes me as infantile. Surely there is a better way.

The best I can think of is to invent a Pair dummy class, extract the
fields from an Entry into the two fields, and sort them in an array.

Part of the problem is generics and arrays don't mix.

Generics and ArrayList mix fine.

Arne
 
L

Lew

Arne said:
Generics and ArrayList mix fine.

And anyway, generics and arrays do mix, just not well. To say merely that they
don't mix, without the qualifier "well", isinaccurate and misleading, and
certainly no help to newbies. Better would be to explain the limits, why they
exist, and what the alternatives are.
 
D

Daniel Pitts

What is best code to export key-value pairs from a HashMap into some
structure in key-value order.

One possible way is to extract the keys, sort them, then look up the
values. That strikes me as infantile. Surely there is a better way.

The best I can think of is to invent a Pair dummy class, extract the
fields from an Entry into the two fields, and sort them in an array.

Part of the problem is generics and arrays don't mix.
Uh, TreeMap is in key order. Why would you use HashMap if you want key
order?
 
R

Roedy Green

Why invent a Pair when Map.Entry already holds the data?

very good. I was getting stuck because the only thing Set had for
export was asArray. You cleverly looked for something that could
import a Set.
 
R

Roedy Green

And anyway, generics and arrays do mix, just not well. To say merely that they
don't mix, without the qualifier "well", isinaccurate and misleading, and
certainly no help to newbies. Better would be to explain the limits, why they
exist, and what the alternatives are.

If you were charged with writing a paragraph or to for newbies to
explain the impedance mismatch of arrays and generics what would you
say?
 
A

Arne Vajhøj

If you were charged with writing a paragraph or to for newbies to
explain the impedance mismatch of arrays and generics what would you
say?

"generics and arrays do mix, just not well" perhaps?

Arne
 
A

Arne Vajhøj

And anyway, generics and arrays do mix, just not well. To say merely
that they don't mix, without the qualifier "well", isinaccurate and
misleading, and certainly no help to newbies. Better would be to explain
the limits, why they exist, and what the alternatives are.

Or maybe just use the "well" modifier to keep focus on the
original problem.

Arne
 
D

David Lamb

nice stuff...

That's a really nice explanation -- simple statement first, slightly
expanded, then details with footnote. I might quibble with some of the
wording, but I'm the sort who might quibble with anybody's wording.
 
R

Roedy Green

Map<K,V> map = ...;
List<Map.Entry<K,V>> entries =
new ArrayList<Map.Entry<K,V>>(map.entrySet());
Collections.sort(entries, new Comparator<Map.Entry<K,V>>() {
@Override
public int compare(Map.Entry<K,V> e1, Map.Entry<K,V> e2) {
return e1.getKey().compareTo(e2.getKey());
}
});
for (Map.Entry<K,V> e : entries) { ... }

I have added your technique with attribution to
http://mindprod.com/jgloss/hashmap.html
 
R

Roedy Green

Generics and arrays do not mix well. That's because arrays "remember" their
underlying type at runtime, but generics just become 'Object' at runtime
through the process of "type erasure". [1] The compiler will not let you
create an array of generic types, unless the generic parameter comprises
entirely unadorned wildcard ('?') characters. So

Foo<?> [] bunchaFoos = new Foo<?> [NUMFOOS];

is legal, but

Foo<Bar> [] bunchaFoos = new Foo<Bar> [NUMFOOS];

is not. Other things like casting and reflection get really difficult, too.

For almost everything you want to do mixing arrays and generics you can use
'ArrayList' instead of an array. The syntax is a little more verbose but the
type safety and expressiveness compensate.

[1] In technical terms, an array is a "reifiable" type - it can be made "real"
in the JVM. Consequently its base type must also be reifiable. A generic
type, except for the pure wildcard '?' generics, is not reifiable because of
erasure. So the compiler won't let you make an array of a generic type.

I have added this to http://mindprod.com/jgloss/generics.html with
attribution.

There is an outstanding question your entry triggered:

/*
* @(#)Alphabetically.java
*
* Summary: Describe/summarise the comparison here..
*
* Requires: JDK 1.5+
*
* Created with: Canadian Mind Products ComparatorCutter.
*
* Version History:
* 1.0 2012-01-17 - initial release
*/
// <> package ...
import java.util.Comparator;

/**
* Describe/summarise the comparison here..
* <p/>
* Defines an alternate sort order for Thing.
*
* @author ...
* @version 1.0 2012-01-17 - initial release
* @since 2012-01-17
*/
class Alphabetically implements Comparator<Thing>
{
/**
* Describe/summarise the comparison here..
* Defines an alternate sort order for Thing with JDK 1.5+
generics.
* Compare two Thing Objects.
* Compares name case sensitively.
* Informally, returns (a-b), or +ve if a sorts after b.
* The Java source code for this Comparator was generated by the
* Canadian Mind Products ComparatorCutter Applet at
http://mindprod.com/applet/comparatorcutter.html
* For non-military purposes only.
*
* @param a first Thing to compare
* @param b second Thing to compare
*
* @return +ve if a&gt;b, 0 if a==b, -ve if a&lt;b
*/
public final int compare( @NotNull Thing a, @NotNull Thing b )
{
return a.name.compareTo( b.name );
}
}

at run time, what type are the parameters to compare, Thing or Object?
 

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,769
Messages
2,569,578
Members
45,052
Latest member
LucyCarper

Latest Threads

Top