Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/308.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java:平面列表<;地图<;字符串,对象>&燃气轮机;到分层列表<;地图<;字符串,对象>&燃气轮机;_Java_Jackson_Gson_Java Stream_Linkedhashmap - Fatal编程技术网

Java:平面列表<;地图<;字符串,对象>&燃气轮机;到分层列表<;地图<;字符串,对象>&燃气轮机;

Java:平面列表<;地图<;字符串,对象>&燃气轮机;到分层列表<;地图<;字符串,对象>&燃气轮机;,java,jackson,gson,java-stream,linkedhashmap,Java,Jackson,Gson,Java Stream,Linkedhashmap,这个问题似乎相当复杂,所以我在这里发布这个问题,寻找任何可能的解决方法 我有地图清单。我还需要一个地图列表,但要确保地图被转换成某种层次结构 原始数据:(列表) 此地图列表将转换为以下地图列表:(列表) 作为一个幼稚的解决方案,我试图手动处理它们(真的很无聊),所以我正在寻找任何高效、干净的方法,使用流或任何其他可能的方法来处理它们 更新 简单的解决方案如下所示 public List<Map<String, Object>> transformResultSet(Lis

这个问题似乎相当复杂,所以我在这里发布这个问题,寻找任何可能的解决方法

我有地图清单。我还需要一个地图列表,但要确保地图被转换成某种层次结构

原始数据:(列表)

此地图列表将转换为以下地图列表:(列表)

作为一个幼稚的解决方案,我试图手动处理它们(真的很无聊),所以我正在寻找任何高效、干净的方法,使用流或任何其他可能的方法来处理它们

更新 简单的解决方案如下所示

public List<Map<String, Object>> transformResultSet(List<Map<String, Object>> flatDataList) {
    List<Map<String, Object>> hierarchicalDataList = new ArrayList<Map<String, Object>>();
    Map<String, List<Map<String, Object>>> studentIdToStudentDataListMap = new LinkedHashMap<>();

    for (Map<Integer, Object> flatData : flatDataList) {
        if (studentIdToStudentDataListMap.get(flatData.get("student_id")) == null) {
            studentIdToStudentDataListMap.put(Integer.valueOf(flatData.get("student_id").toString()), new ArrayList<Map<String, Object>>());
        }
        studentIdToStudentDataListMap.get(Integer.valueOf(flatData.get("student_id").toString())).add(flatData);
    }

    for (Map.Entry<Integer, List<Map<String, Object>>> studentFlatDataList : studentIdToStudentDataListMap.entrySet()) {
        Map<String, Object> studentHierarchicalDataMap = new LinkedHashMap<String, Object>();
        Map<String, Object> studentFlatDataMap = studentFlatDataList.getValue().get(0);
        studentHierarchicalDataMap.put("studentId", studentFlatDataMap.get("studentId"));
        studentHierarchicalDataMap.put("name", studentFlatDataMap.get("name"));
        
        List<Map<String, Object>> academicsList = new ArrayList<Map<String, Object>>();
        for (Map<String, Object> studentDetailAcademic : studentFlatDataList.getValue()) {
            Map<String, Object> academic = new LinkedHashMap<String, Object>();
            academic.put("subjectId", studentDetailAcademic.get("subjectId"));
            academic.put("marks", studentDetailAcademic.get("marks"));

            academicsList.add(academic);
        }
        studentHierarchicalDataMap.put("academics", academicsList);

        Map<String, Object> address = new LinkedHashMap<String, Object>();
        address.put("street", studentFlatDataMap.get("street"));
        address.put("state", studentFlatDataMap.get("state"));
        studentHierarchicalDataMap.put("address", address);

        hierarchicalDataList.add(studentHierarchicalDataMap);
    }
    return hierarchicalDataList;
}
公共列表transformResultSet(列表flatDataList){
List HierarchycalDataList=新建ArrayList();
Map studentTostudentDataListMap=新建LinkedHashMap();
用于(地图平面数据:平面数据列表){
if(studentdtostudentdatalistmap.get(flatData.get(“学生id”))==null){
studentToStudentDataListMap.put(Integer.valueOf(flatData.get(“student_id”).toString()),new ArrayList());
}
StudentToStudentDataListMap.get(Integer.valueOf(flatData.get(“学生id”).toString()).add(flatData);
}
对于(Map.Entry studentFlatDataList:studentDTStudentDataListMap.entrySet()){
Map studentHierarchicalDataMap=新建LinkedHashMap();
Map studentFlatDataMap=studentFlatDataList.getValue().get(0);
studentHierarchicalDataMap.put(“studentId”,studentFlatDataMap.get(“studentId”);
studentHierarchicalDataMap.put(“name”),studentFlatDataMap.get(“name”);
List academicsList=新建ArrayList();
对于(映射studentDetailAcademic:studentFlatDataList.getValue()){
Map academic=新建LinkedHashMap();
academic.put(“subjectId”),studentDetailAcademic.get(“subjectId”);
学术性。输入(“分数”),学生详细信息学术性。获取(“分数”);
学术列表。添加(学术);
}
studentHierarchicalDataMap.put(“学术界”,学术列表);
映射地址=新LinkedHashMap();
地址.put(“street”,studentFlatDataMap.get(“street”);
address.put(“state”,studentFlatDataMap.get(“state”);
studentHierarchicalDataMap.put(“地址”,address);
添加(studentHierarchicalDataMap);
}
返回层次数据表;
}

从json示例中,您似乎有
列表
而不是
列表
。 所以,只是给你一个想法创建两个对象,比如
StudentDto
MarkDto

假设输入对象是
Student
StudentDto
的成员为
List

Map<String, List<Student>>  map = list.stream().collect(groupingBy(Student::studentId)); 
Map<String, StudentDto>  dtoMap = new HashMap<>();
for(Map.Entry<String, List<Student>> entry : map.entrySet()) {
    StudentDto stud = new StudentDto();
    //assign other studentDto properties
    
    for(Student std : entry.getValue()) {
        MarkDto mark = new MarkDto();
        mark.setSubjectId(std.getStudentid());
        mark.setMark(entry.getMark()));
        
        stud.add(mark);
    }
    
    dtoMap.put(String.valueOf(stud.getId()), stud);
}

return dtoMap.stream().collect(Collectors.toList()); // or return the map itself
Map Map=list.stream().collect(groupingBy(Student::studentId));
Map dtoMap=newhashmap();
对于(Map.Entry:Map.entrySet()){
StudentDto stud=新StudentDto();
//将其他学生分配到属性
对于(学生标准:entry.getValue()){
MarkDto mark=新的MarkDto();
mark.setsubject(std.getStudentid());
mark.setMark(entry.getMark());
螺柱.添加(标记);
}
dtoMap.put(String.valueOf(stud.getId()),stud);
}
返回dtoMap.stream().collect(Collectors.toList());//或者返回地图本身

您可以通过以下几个步骤拆分算法:

  • 提取
    subjectId
    标记
    到新的
    地图
  • 街道
    提取到新的
    地址
    地图
  • 列表
    包裹
    地图
  • 通过
    studentId
    合并数据。当发生冲突时,我们需要合并
    列表
  • 步骤
    1.
    2.
    除了键名之外是相同的。我们可以将其提取到一个新类中,以避免重复方法引用:

    class ExtractKeysToMap implements Function<Map<String, Object>, Map<String, Object>> {
    
        private final List<String> keys;
        private final String newKey;
    
        ExtractKeysToMap(String newKey, List<String> keys) {
            this.newKey = Objects.requireNonNull(newKey);
            this.keys = Objects.requireNonNull(keys);
        }
    
        @Override
        public Map<String, Object> apply(Map<String, Object> map) {
            Map<String, Object> academics = new HashMap<>();
            keys.forEach(key -> {
                Object value = map.remove(key);
                if (value != null) academics.put(key, value);
            });
            map.put(newKey, academics);
    
            return map;
        }
    }
    

    似乎您需要按学生分组,同时还要更改json结构

    更高级别,您可以这样做(稍后我们将看到详细信息):

    以及
    mergeHierarchicalStudents
    方法:

    Map<String, Object> mergeHierarchicalStudents(
            Map<String, Object> oldSt, Map<String, Object> newSt) {
    
        // We only need to merge the subjects
        List<Map<String, Object>> oldAcademics = 
            (List<Map<String, Object>>) oldSt.get("academics");
        List<Map<String, Object>> newAcademics = 
            (List<Map<String, Object>>) newSt.get("academics");
        oldAcademcis.addAll(newAcademics);
    
        return oldS;
    }
    

    提供“幼稚的解决方案”以及迄今为止您尝试了什么。我们不知道您想要实现的对象结构。您确定要使用
    列表
    作为输出而不是结构对象吗?仅仅因为解决方案“无聊”并不一定意味着它不好。您的帖子不太清楚这是一个问题还是关于如何使用无聊的实现。你应该展示无聊的工作原理。如果有帮助,您可以基于字段
    studentId
    map
    上使用
    groupingBy
    。试着把它弄清楚一点看看类似的问题:,你只需要实现不同的合并功能。@Aman:问题更新为解决方案有多无聊:像一个可伸缩的解决方案。
    class ExtractKeysToMap implements Function<Map<String, Object>, Map<String, Object>> {
    
        private final List<String> keys;
        private final String newKey;
    
        ExtractKeysToMap(String newKey, List<String> keys) {
            this.newKey = Objects.requireNonNull(newKey);
            this.keys = Objects.requireNonNull(keys);
        }
    
        @Override
        public Map<String, Object> apply(Map<String, Object> map) {
            Map<String, Object> academics = new HashMap<>();
            keys.forEach(key -> {
                Object value = map.remove(key);
                if (value != null) academics.put(key, value);
            });
            map.put(newKey, academics);
    
            return map;
        }
    }
    
    import com.fasterxml.jackson.databind.ObjectMapper;
    import com.fasterxml.jackson.databind.SerializationFeature;
    import com.fasterxml.jackson.databind.type.CollectionType;
    
    import java.io.File;
    import java.util.Arrays;
    import java.util.Collection;
    import java.util.Collections;
    import java.util.HashMap;
    import java.util.LinkedList;
    import java.util.List;
    import java.util.Map;
    import java.util.Objects;
    import java.util.function.Function;
    import java.util.stream.Collectors;
    
    public class JsonApp {
    
        public static void main(String[] args) throws Exception {
            File jsonFile = new File("./src/main/resources/test.json");
    
            ObjectMapper mapper = new ObjectMapper();
            mapper.enable(SerializationFeature.INDENT_OUTPUT);
    
            CollectionType jsonType = mapper.getTypeFactory().constructCollectionType(List.class, Map.class);
            List<Map<String, Object>> response = mapper.readValue(jsonFile, jsonType);
    
            final String academicsKey = "academics";
            Collection<Map<String, Object>> result = response
                    .stream()
                    .map(new ExtractKeysToMap(academicsKey, Arrays.asList("subjectId", "marks")))
                    .map(new ExtractKeysToMap("address", Arrays.asList("street", "state")))
                    .peek(map -> map.computeIfPresent(academicsKey, (k, v) -> new LinkedList<>(Collections.singletonList(v))))
                    .collect(Collectors.toMap(
                            map -> map.get("studentId"),
                            map -> map,
                            (map0, map1) -> {
                                ((List<Object>) map0.get(academicsKey)).addAll((List<Object>) map1.get(academicsKey));
    
                                return map0;
                            }))
                    .values();
    
            mapper.writeValue(System.out, result);
        }
    }
    
    [ {
      "studentId" : 101,
      "name" : "John",
      "academics" : [ {
        "subjectId" : 2001,
        "marks" : 85
      }, {
        "subjectId" : 2002,
        "marks" : 75
      } ],
      "address" : {
        "street" : "Bakers Street",
        "state" : "LA"
      }
    }, {
      "studentId" : 102,
      "name" : "Shae",
      "academics" : [ {
        "subjectId" : 3001,
        "marks" : 96
      } ],
      "address" : {
        "street" : "Howards",
        "state" : "NYC"
      }
    } ]
    
    Map<Integer, Map<String, Object>> grouped = flatDataList.stream()
        .collect(Collectors.toMap(
            s -> (Integer) s.get("studentId"),
            s -> transformToHierarchicalStudent(s),
            (oldS, newS) -> mergeHierarchicalStudents(oldS, newS)));
    
    Map<String, Object> transformToHierarchicalStudent(Map<String, Object> flat) {
    
        Map<String, Object> student = new LinkedHashMap<>();
    
        student.put("studentId", flat.get("studentId"));
        student.put("name", flat.get("name"));
    
        Map<String, Object> address = new LinkedHashMap<>();
        address.put("street", flat.get("street"));
        address.put("state", flat.get("state"));
        student.put("address", address);
    
        List<Map<String, Object>> academics = new ArrayList<>();
        Map<String, Object> subject = new LinkedHashMap<>();
        subject.put("subjectId", flat.get("subjectId"));
        subject.put("marks", flat.get("marks"));
        academics.add(subject);
        student.put("academics", academics);
    
        return student;
    }
    
    Map<String, Object> mergeHierarchicalStudents(
            Map<String, Object> oldSt, Map<String, Object> newSt) {
    
        // We only need to merge the subjects
        List<Map<String, Object>> oldAcademics = 
            (List<Map<String, Object>>) oldSt.get("academics");
        List<Map<String, Object>> newAcademics = 
            (List<Map<String, Object>>) newSt.get("academics");
        oldAcademcis.addAll(newAcademics);
    
        return oldS;
    }
    
    List<Map<String, Object>> hierarchicalStudents = new ArrayList<>(grouped.values());