Java - 投射地图

发布于 2024-12-10 09:48:10 字数 159 浏览 0 评论 0原文

如何以最简洁的方式将 Map 转换为 Map

有没有办法在不迭代地图的情况下做到这一点?

谢谢

How can I cast a Map<Object,Object> to Map<String,String> in the cleanest way?

Is there a way to do that without iterating over the map?

Thanks

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

弥枳 2024-12-17 09:48:10

实际的答案是:

Map<Object,Object> valueMap = ...;
@SuppressWarnings("unchecked")
Map<String,String> targetMap = (Map)valueMap;

The actual answer is:

Map<Object,Object> valueMap = ...;
@SuppressWarnings("unchecked")
Map<String,String> targetMap = (Map)valueMap;
一笔一画续写前缘 2024-12-17 09:48:10

我认为解释为什么简单的解决方案不起作用以及为什么你永远不应该使用它是一个好主意。

假设您可以将 List转换为 List(这同样适用于 Map,只是接口更简单)。您期望从以下代码中发生什么:

List<Object> m = Something;
m.add("Looks good.");
m.add(42);
List<String> s = (List<String>)m; // uhuh, no we don't want that.
String myString = s.get(1); // huh exception here.

现在您确实可以使用 Bohemians/Chris 解决方案破解它,但您基本上会破坏 Java 的类型系统。 不要这样做。您不希望List包含整数!稍后进行有趣的调试 - 循环遍历所有变量的附加代码将避免很多令人头疼的问题,而且几乎不是性能问题。

如果有理由将 Map 声明为采用对象而不是字符串,那么有人可能会向其中添加任何对象 - 通常您应该能够使用更好的泛型来避免这种情况。

I think it's a good idea to explain why the simple solution doesn't work and why you never, ever should use this.

Assume you could cast List<Object> to List<String> (the same applies to Map, just a simpler interface). What would you expect to happen from the following code:

List<Object> m = Something;
m.add("Looks good.");
m.add(42);
List<String> s = (List<String>)m; // uhuh, no we don't want that.
String myString = s.get(1); // huh exception here.

Now you CAN hack it indeed using Bohemians/Chris solution, but you basically destroy Java's type system. DON'T DO THAT. You don't want a List<String> to contain an Integer! Have fun debugging that later on - the additional code of looping through all variables will avoid lots of headaches and hardly is a performance problem.

If there's a reason to declare the Map as taking an Object instead of a String someone may add any object to it - usually you should be able to avoid this with a better generic.

仲春光 2024-12-17 09:48:10

想要干净,就必须“深度”转换!键和值。

使用 Java 8 流,只需几行:

static public Map<String, String> toStringString(Map<? extends Object, ? extends Object> map) {
        return map
                .entrySet()
                .stream()
                .collect(Collectors.toMap(
                    e -> e.getKey().toString(),
                    e -> e.getValue().toString()
                ));
    }

If you want something clean, you must convert "deeply"! keys and values.

Using Java 8 stream, this take only a few lines:

static public Map<String, String> toStringString(Map<? extends Object, ? extends Object> map) {
        return map
                .entrySet()
                .stream()
                .collect(Collectors.toMap(
                    e -> e.getKey().toString(),
                    e -> e.getValue().toString()
                ));
    }
花之痕靓丽 2024-12-17 09:48:10
 public  Map<String, String> castOnlyStringValues(final Map<String, Object> map) {
    return map.entrySet().stream()
              .filter(x -> String.class.isAssignableFrom(x.getValue().getClass()))
              .map(x -> (Entry<?, ?>) x).map(x -> (Entry<String, String>) x)
              .collect(toMap(Entry::getKey, Entry::getValue));
}
 public  Map<String, String> castOnlyStringValues(final Map<String, Object> map) {
    return map.entrySet().stream()
              .filter(x -> String.class.isAssignableFrom(x.getValue().getClass()))
              .map(x -> (Entry<?, ?>) x).map(x -> (Entry<String, String>) x)
              .collect(toMap(Entry::getKey, Entry::getValue));
}
白日梦 2024-12-17 09:48:10

基于 Chris J 的回答,这是他的“黑客”代码,显示了它有效:

public static void main(String[] args) {
    Map<Object, Object> valueMap = new HashMap<Object, Object>();
    valueMap.put("foo", "bar");
    @SuppressWarnings("unchecked")
    Map<String, String> targetMap = (Map<String, String>) ((Object) valueMap); // hack alert!
    for (Map.Entry<String, String> entry : targetMap.entrySet()) {
        String key = entry.getKey();
        String value = entry.getValue();
        System.out.println(key + "=" + value); // prints foo=bar :)
    }
}

哇!没有运行时异常:)

Building on Chris J's answer, here's his "hack" code in action, showing it works:

public static void main(String[] args) {
    Map<Object, Object> valueMap = new HashMap<Object, Object>();
    valueMap.put("foo", "bar");
    @SuppressWarnings("unchecked")
    Map<String, String> targetMap = (Map<String, String>) ((Object) valueMap); // hack alert!
    for (Map.Entry<String, String> entry : targetMap.entrySet()) {
        String key = entry.getKey();
        String value = entry.getValue();
        System.out.println(key + "=" + value); // prints foo=bar :)
    }
}

Wow! No runtime exceptions :)

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文