简体   繁体   English

初始化地图的类型安全的varargs方法

[英]Type-safe varargs method that initialises a Map

I'm wanting to write a method that I can use to initialise a Map. 我想编写一种可用于初始化地图的方法。 First cut: 初切:

Map map(Object ... o) {for (int i = 0; i < o.length; i+=2){result.put(o[i], o[i+1])}}

Simple, but not type-safe. 简单,但不是类型安全的。 Using generics, maybe something like: 使用泛型,也许像这样:

<TKey, TValue> HashMap<TKey, TValue> map(TKey ... keys, TValue ... values) 

but that syntax isn't supported. 但是不支持该语法。 So eventually I come to this: 所以最终我来到了这里:

public static <TKey, TValue, TMap extends Map<? super TKey, ? super TValue>> TMap map(TMap map, Pair<? extends TKey, ? extends TValue> ... pairs) {
    for (Pair<? extends TKey, ? extends TValue> pair: pairs) {
        map.put(pair.getKey(), pair.getValue());
    }
    return map;
}

public static <TKey, TValue> HashMap<? super TKey, ? super TValue> map(Pair<? extends TKey, ? extends TValue> ... pairs) {
    return map(new HashMap<TKey, TValue>(), pairs);
}

public static <TKey, TValue> Pair<TKey, TValue> pair(TKey key, TValue value) {
    return new Pair<TKey, TValue>(key, value);
}

public static final class Pair<TKey, TValue> {
    private final TKey key;
    private final TValue value;
    Pair(TKey key, TValue value) {this.key = key; this.value = value; }
    public TKey getKey() {return key;}
    public TValue getValue() {return value;}
}

But when I try it out, I need to cast it: 但是,当我尝试时,我需要将其强制转换:

private static final Map<? extends Class<? extends Serializable>, ? super TypeHandler<? extends Serializable > > validCodeTypes =
    /* (Map<? extends Class<? extends Serializable>, ? super TypeHandler<? extends Serializable >>) */
 map(
    pair(Integer.class,   new IntHandler()),
    pair(Integer.TYPE,    new IntHandler()),
    pair(Character.class, new CharHandler()),
    pair(Character.TYPE,  new CharHandler()),
    pair(String.class,    new StringHandler())
);

private interface TypeHandler<TType extends Serializable> {}

private static class CharHandler implements TypeHandler<Character> {}
private static class IntHandler implements TypeHandler<Integer> {}
private static class StringHandler implements TypeHandler<String> {}

Can anyone tell me how to code my map() methods so that it is entirely general yet doesn't need to be casted? 谁能告诉我如何对map()方法进行编码,使其完全通用但不需要强制转换?

To make life easier for yourself, never use a return type that contains wildcards. 为了使您的生活更轻松,请不要使用包含通配符的返回类型。 Wildcard types, in general, are for method parameters only. 通常,通配符类型仅用于方法参数。

So, try this: 因此,请尝试以下操作:

public static <TKey, TValue, TMap extends Map<TKey, TValue>> TMap map(TMap map, Pair<? extends TKey, ? extends TValue>... pairs) {
    for (Pair<? extends TKey, ? extends TValue> pair: pairs) {
        map.put(pair.getKey(), pair.getValue());
    }
    return map;
}

public static <TKey, TValue> HashMap<TKey, TValue> map(Pair<? extends TKey, ? extends TValue>... pairs) {
    return map(new HashMap<TKey, TValue>(), pairs);
}

I haven't tested it, but give it a go and see how you fare. 我还没有测试过,但请试试看,您的票价如何。

PS, rather than using a made-up Pair type, you may find it easier to use Map.Entry . PS,而不是使用Pair类型,您可能会发现使用Map.Entry更容易。

Why not this? 为什么不呢? Did I misunderstand something? 我误会了吗?

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

public class ToHash {
    public static <K, V> Map<K, V> toHash(Object... objects) {
        Map<K, V> map = new HashMap<K, V>(objects.length / 2);
        if (objects.length % 2 != 0) {
            throw new IllegalArgumentException("Odd number of elements: " + objects.length);
        }
        for (int i = 0; i < objects.length; i += 2) {
            map.put((K) objects[i], (V) objects[i + 1]);
        }
        return map;
    }
}

pgdx: Your technique certainly works but it does not prevent me from saying something like: pgdx:您的技术当然可以,但是并不能阻止我说出类似以下内容:

Map<Long, Date> map = toHash("hello", "world");

I was looking for a way which would allow the compiler to pick up on any type-mismatch errors. 我在寻找一种允许编译器选择任何类型不匹配错误的方法。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM