如何将HashMap <k,v =“”>值类型从Object更改为String?</k,>

时间:2013-07-16 22:53:42

标签: java dictionary data-structures hashmap type-conversion

转换的最简单/最佳方式是什么?

Map<String, Object>

HashMap<String, String>

我使用的API具有返回Map的方法,但如果我不必每次都将Object转换为String,那将会更容易。

此外,这甚至值得做吗? HashMap会比Map更快/更有效吗?

我假设我必须遍历原始Map并将值复制到新的HashMap。

提前致谢!

3 个答案:

答案 0 :(得分:9)

您可以像其他人一样使用构造函数:

Map<String, String> newMap = new HashMap(oldMap);

只有当您知道有问题的Object {/ 1}}时才会有效。

但我应该提一下:

请勿将接口混淆。 String只是界面; 合同,仅包含定义。另一方面,接口的具体实现。因此,如果您使用Map 接口或其运行时类型(Map),则在性能方面没有任何区别。但是,如果您交换实现(例如,HashMap),它可能会有所不同。

编辑:

以下是EE人员喜欢的详细解决方案(不涉及任何演员/原型警告):

TreeMap

答案 1 :(得分:2)

在原始类型上使用复制构造函数:

HashMap<String, String> hashMap = new HashMap(map);

然而,由于类型系统被忽略,解决方案很难看。

EDIT1:

执行时

public static void main(String[] args) throws IllegalArgumentException,
        InterruptedException, IOException {
    HashMap<String, Object> map = new HashMap<String, Object>();
    map.put("Bla", new Object());
    HashMap<String, String> hashMap = new HashMap(map);
    System.out.println(hashMap.get("Bla").getClass());
}

你得到了类强制转换异常:

Exception in thread "main" java.lang.ClassCastException: java.lang.Object cannot be cast to java.lang.String

当“System.out.println(hashMap.get(”Bla“)。getClass());”时抛出它被执行。

因此,演员阵容实际上已经延迟了。

EDIT2:

您可以使用

来避免复制
HashMap<String, String> hashMap = (HashMap)map;

但是,问题仍然与以下代码所示相同:

public static void main(String[] args) throws IllegalArgumentException,
        InterruptedException, IOException {
    HashMap<String, Object> oldMap = new HashMap<String, Object>();
    oldMap.put("Bla", new Object());
    HashMap<String, String> hashMap = (HashMap)oldMap;
    System.out.println(hashMap.get("Bla").getClass());
}

它的行为与上面EDIT1中的另一个例子相同。

EDIT3: 怎么样使用lambda?

    Map<String, Object> map = new HashMap<String, Object>();

    // 1

    final Stream<Map.Entry<String, Object>> entries = map.entrySet()
            .stream();

    final Function<Map.Entry<String, Object>, String> keyMapper = (
            Map.Entry<String, Object> entry) -> entry.getKey();

    final Function<Map.Entry<String, Object>, String> valueMapper = (
            Map.Entry<String, Object> entry) -> {
        final Object value = entry.getValue();
        if (value instanceof String) {
            return (String) value;
        } else {
            throw new ClassCastException("Value '" + value + "' of key '"
                    + entry.getKey() + "' cannot be cast from type "
                    + ((value != null) ? value.getClass().getName() : null)
                    + " to type " + String.class.getName());
        }
    };

    final BinaryOperator<String> duplicateHandler = (key1, key2) -> {
        throw new IllegalStateException(String.format("Duplicate key %s",
                key1));
    };

    final HashMap<String, String> hashMap = entries.collect(Collectors
            .toMap(keyMapper, valueMapper, duplicateHandler, HashMap::new));

    System.out.println(hashMap);

如果map只有字符串到字符串的条目,它将全部复制它们。 例如。插入

    map.put("aKey", "aValue");

评论1.它将打印

    {aKey=aValue}

这很好。

如果地图中至少有一个字符串到非字符串条目,则复制将失败。

E.g。插入

    map.put("aKey", 42);

评论1.它将打印

Exception in thread "main" java.lang.ClassCastException: Value '42' of key ' aKey' cannot be cast from type java.lang.Integer to type java.lang.String
    at ...

显示字符串到非字符串的条目。

我知道这个解决方案不是那么简单但是很安全。

答案 2 :(得分:0)

如果你知道键和值的类型(比如<String, String>),你可以只渲染整个地图:

Map<String, String> newMap = (HashMap<String, String>)oldMap;

如果您需要单独的Map实例,则可以使用HashMap的构造函数:

HashMap<String, String> = new HashMap<String, String>((HashMap<String, String>) oldMap);