Java 从列表中强制转换<;T>;要设置的地图输入值<;T>;

Java 从列表中强制转换<;T>;要设置的地图输入值<;T>;,java,generics,Java,Generics,我有一个映射,其中一个条目包含列表的值。我需要将列表的内容放入集合。我正在使用以下代码: Map<String, Object> map = SomeObj.getMap(); if (map.get("someKey") instance of List<?>) { Set<String> set = new HashSet<String>((List<String>) map.get("someKey")); } Map

我有一个
映射
,其中一个条目包含
列表
的值。我需要将
列表
的内容放入
集合
。我正在使用以下代码:

Map<String, Object> map = SomeObj.getMap();
if (map.get("someKey") instance of List<?>) {

    Set<String> set = new HashSet<String>((List<String>) map.get("someKey"));
}
Map Map=SomeObj.getMap();
if(列表的map.get(“someKey”)实例){
Set=newhashset((List)map.get(“someKey”);
}
我的基于Eclipse的IDE在这一行有几个警告:

  • 类型安全性:未选中从对象强制转换为 名单

代码按照预期的方式编译和运行。但是有没有更好的方法?用
@SuppressWarnings(“未选中”)
注释行是我最后也是最不喜欢的选项。

您可以执行以下操作:

Map<String, Object> map = SomeObj.getMap();
String key = "someKey";
if (map.get(key) instanceof List<?>) {
    List<?> list = (List<?>) map.get(key);
    Set<String> set = new HashSet<>();
    // Cast and add each element individually
    for (Object o : list) {
        set.add((String) o);
    }
    // Or, using streams
    Set<String> set2 = list.stream().map(o -> (String) o).collect(Collectors.toSet());
}
Map Map=SomeObj.getMap();
String key=“someKey”;
if(map.get(key)instanceof List){
List=(List)map.get(key);
Set=newhashset();
//分别铸造和添加每个元素
用于(对象o:列表){
set.add((字符串)o);
}
//或者,使用流
Set set2=list.stream().map(o->(String)o.collect(Collectors.toSet());
}

String
是一种特殊的方法,因为在所有对象上都存在一个方法来转换为它,即
Object.toString()
。对字符串调用
toString()
,将返回自身

因此,如果您知道它是一个
列表
,您可以按如下方式转换为
集合

List<?> list = (List<?>) map.get("some key");
Set<?> set = list.stream().map(Object::toString).collect(Collectors.toSet());
List List=(List)map.get(“某个键”);
Set Set=list.stream().map(Object::toString.collect(Collectors.toSet());
(您可能需要处理空元素)

您不能从列表“强制转换”到集合;这些是使用不同方法的不同接口。但是你可以改为

Set<String> set = new HashSet<String>();
set.addAll(map.get("someKey"));
Set Set=newhashset();
set.addAll(map.get(“someKey”);

这充分利用了addAll对集合界面的了解。

为什么map
对象的值类型是由我使用的库指定的
getMap()
返回类型为
Map
。注意:这不会更安全,但不会得到警告+1但这样会更安全一些,因为您可以在代码中查找元素是否为对象,而不是在以后尝试取出元素时查找!(请注意,编写映射cast的另一种方法是
.map(String.class::cast)
)。好吧,我甚至不会想到
String.class::cast
,即使
cast
从Java1.5开始就存在了!!与
.toString()
相比,使用它有什么好处吗?
null.toString()
抛出一个NPE,但是
(String)null
String.class.cast(null)
不可以。就
null
而言,您可能想要过滤它们,或者使用
.map(String::valueOf)
+1@PeterLawrey仅当您希望
为空时
用于空元素;如果你想让它们保持为空,你必须使用其他的东西。我得到了相同的答案,并投票给了第一个。由于这两个原因,我能够摆脱错误,并过滤掉列表中的空值。。。我没有考虑过这种情况,因为将返回从JWT令牌解析出的键值对的映射。@WebUser这个答案的要点是它是无条件安全的(一旦处理了null),因为除了将对象强制转换到列表的转换之外,没有其他转换;如果任何列表元素不是字符串,则另一种方法将在运行时失败。如果任何列表元素不是字符串,则另一种方法的哪一部分将失败?使用流的方法还是第一种?在这两种情况下,对象似乎都被转换为字符串类型。类型不匹配,
map.get(“someKey”)
是一个
对象
啊,我没注意到他在映射中混合了对象类型。