将hashmap列表转换为set

时间:2016-09-28 19:45:51

标签: java generics collections hashmap set

我想将List<HashMap<String, Object>>投射到Set<StudentInfo>

我有方法

public List<HashMap<String,Object>> getStudentData(studentId);

我想将结果转换为Set,所以我使用了

Set<StudentInfo> studentFilteredInfo = new HashSet<>();
List<Map<String, Object>> studentCompleteRecord = getStudentData(1005);
studentFilteredInfo.addAll((Collection<? extends StudentInfo>studentCompleteRecord ));

最初当我在localhost上使用java 8,eclipse和tomcat 8执行它时工作正常。

当我尝试用maven构建它时

mvn clean package

它将通过错误:

不兼容的类型:java.util.List<java.util.Map<java.lang.String,java.lang.Object>>

cannot be converted to java.util.Collection<? extends com.school.model.StudentInfo>

2 个答案:

答案 0 :(得分:9)

错误List<Map<String, Object>>中没有投射到某些Set<Whatever>

投射基本上意味着:知道某些“对象”具有更具体的类型;因此,你告诉编译器:“你可以放心地认为这里的东西是现实中的其他东西”。

但这意味着:在现实中(在运行时),“thingy”真的是“别的东西”!单独在您的问题中提供的泛型类型非常明确:您不能在此处执行强制转换

换句话说:您必须编写代码 迭代您的地图列表;提取创建新 StudentInfo 对象所需的信息。然后你收集那些新创建的对象;并将它们放入一个新的集合;然后你可以从你的方法返回!

最后:始终避免“具体”实现类型;您使用了List<HashMap<... - 而应该使用List<Map<...

答案 1 :(得分:1)

您需要编写代码以将Map<String,Object>显式转换为StudentInfo实例。假设StudentInfo有这样的方法:

static StudentInfo create(Map<String, Object> info) {
  String name = info.get("name");
  Transcript transcript = info.get("grades");
  return new StudentInfo(name, transcript);
}

然后,您需要迭代列表中的每个元素,并使用您的方法将Map实例转换为StudentInfo个对象。

使用lambdas:

  Set<StudentInfo> studentFilteredInfo = studentCompleteRecord.stream()
    .map(StudentInfo::create)
    .collect(Collectors.toSet());

没有lambdas:

  Set<StudentInfo> studentFilteredInfo = new HashSet<>();
  for (Map<String,Object> e : studentCompleteRecord) 
    studentFilteredInfo.add(StudentInfo.create(e);