Re: Encapsulating HashMap bulding
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 + ")";
}
}