From: Roedy Green on
Can anyone think of a way to write a method that takes an array of X,
and produces a HashMap<Key,X>

How would you specify the name of the key field/method?

Maybe you could do it by making X implement an interface that defines
the key.

Perhaps you could do it with reflection.
--
Roedy Green Canadian Mind Products
http://mindprod.com

What is the point of a surveillance camera with insufficient resolution to identify culprits?
From: Lew on
On 05/10/2010 06:20 PM, Roedy Green wrote:
> Can anyone think of a way to write a method that takes an array of X,
> and produces a HashMap<Key,X>
>
> How would you specify the name of the key field/method?
>
> Maybe you could do it by making X implement an interface that defines
> the key.
>
> Perhaps you could do it with reflection.

Map <Key, X> map = new HashMap <Key, X>();
for ( X x : arrayOfX )
{
map.put( genKey( x ), x );
}

Example:

public class X
{
private final Key key; // getter and setter omitted
public X( Key k ) { key = k; }
public Key getKey() { return key; }
// other attributes omitted
}

other class#method:

...
for ( X x : arrayOfX )
{
map.put( x.getKey(), x );
}

--
Lew
From: Arne Vajhøj on
On 10-05-2010 18:20, Roedy Green wrote:
> Can anyone think of a way to write a method that takes an array of X,
> and produces a HashMap<Key,X>
>
> How would you specify the name of the key field/method?
>
> Maybe you could do it by making X implement an interface that defines
> the key.
>
> Perhaps you could do it with reflection.

The two approaches seems to be what is available.

See below for some code.

Arne

=============================

import java.beans.IntrospectionException;
import java.beans.PropertyDescriptor;
import java.lang.reflect.InvocationTargetException;
import java.util.HashMap;
import java.util.Map;

public class A2HM {
public static <K,T extends KeyContainer<K>> Map<K,T> convert1(T[] a) {
Map<K,T> res = new HashMap<K,T>();
for(T e : a) {
res.put(e.getKey(), e);
}
return res;
}
@SuppressWarnings("unchecked")
public static <K,T> Map<K,T> convert2(T[] a, String prop, Class<K>
clz) throws IntrospectionException, IllegalArgumentException,
IllegalAccessException, InvocationTargetException {
PropertyDescriptor pd = new PropertyDescriptor(prop,
a.getClass().getComponentType());
Map<K,T> res = new HashMap<K,T>();
for(T e : a) {
res.put((K)pd.getReadMethod().invoke(e), e);
}
return res;
}
public static void main(String[] args) throws Exception {
Foobar[] a = new Foobar[3];
a[0] = new Foobar(1,1.2,"A");
a[1] = new Foobar(2,12.34,"BB");
a[2] = new Foobar(3,123.456,"CCC");
System.out.println(convert1(a));
System.out.println(convert2(a, "k", Integer.class));
}
}

interface KeyContainer<K> {
public K getKey();
}

class Foobar implements KeyContainer<Integer> {
private int k;
private double v1;
private String v2;
public Foobar(int k, double v1, String v2) {
this.k = k;
this.v1 = v1;
this.v2 = v2;
}
public int getK() {
return k;
}
public void setK(int k) {
this.k = k;
}
public double getV1() {
return v1;
}
public void setV1(double v1) {
this.v1 = v1;
}
public String getV2() {
return v2;
}
public void setV2(String v2) {
this.v2 = v2;
}
public Integer getKey() {
return k;
}
@Override
public String toString() {
return "(" + k + "," + v1 + "," + v2 + ")";
}
}
From: Robert Klemme on
On 11.05.2010 00:20, Roedy Green wrote:
> Can anyone think of a way to write a method that takes an array of X,
> and produces a HashMap<Key,X>
>
> How would you specify the name of the key field/method?
>
> Maybe you could do it by making X implement an interface that defines
> the key.
>
> Perhaps you could do it with reflection.

I'd rather provide an interface that is responsible for the conversion
from X to Key - this is more modular.

package util;

import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;

public class MapUtil {

public interface Transformer<A, B> {
B transform(A a);
}

public static <K, V> Map<K, V> createHash(V[] i, Transformer<V, K> t) {
return createHash(Arrays.asList(i), t);
}

public static <K, V> Map<K, V> createHash(Iterable<V> i,
Transformer<V, K> t) {
final Map<K, V> map = new HashMap<K, V>();
fill(map, i, t);
return map;
}

public static <K, V> void fill(Map<K, V> m, Iterable<V> i,
Transformer<V, K> t) {
for (V val : i) {
m.put(t.transform(val), val);
}
}
}

Kind regards

robert

--
remember.guy do |as, often| as.you_can - without end
http://blog.rubybestpractices.com/
From: Kevin McMurtrie on
In article <qf1hu5d02ptja2duic3saa60qgolal9llm(a)4ax.com>,
Roedy Green <see_website(a)mindprod.com.invalid> wrote:

> Can anyone think of a way to write a method that takes an array of X,
> and produces a HashMap<Key,X>
>
> How would you specify the name of the key field/method?
>
> Maybe you could do it by making X implement an interface that defines
> the key.
>
> Perhaps you could do it with reflection.

If the key is easily derived from the value, what you might have is a
set rather than a map. If that's not the case, Generics trickery will
make it a simple task.


interface Key
{
boolean equals(Object other);
int hashCode ();
// Other stuff
}

interface Keyed
{
Key getKey();
}

public <K extends Keyed> HashMap <Key, K> keyedMap (K[] in)
{
HashMap<Key, K> map= new HashMap<Key, K>(in.length);
for (K keyed : in)
map.put(keyed.getKey(), keyed);
return map;
}


You could even put generics on they Key to support different categories
of keys. It would be nearing the boundary of where Generics stops
making coding easier, though.
--
I won't see Google Groups replies because I must filter them as spam