简体   繁体   中英

How do I combine 2 array lists of objects having same property value in java

I have 2 array lists as follows. One array contains student information mapped with id , name and city . The other array contains the marks details mapped with id, marks and grade . The goal is to compare each of these elements against each other and combine them based on the common field id in both the . The goal is to compare each of these elements against each other and combine them based on the common field id in both the ArrayList`.

student_details=[
        {
            "id": 1,
            "name": "sam",
            "city": "Chennai"
           
        },
        {
            "id": 2,
            "name": "peter",
            "city": "Chennai"
            
        }
    ]
student_grades=[
        {
            "id": 1,
            "marks": 95,
            "grade": "A"
           
        },
        {
            "id": 2,
            "marks":63,
            "grade": "B"
            
        }
    ]

The result should look as follows.

[
        {
            "id": 1,
            "name": "sam",
            "city": "Chennai",
            "marks": 95,
            "grade": "A"
           
        },
        {
            "id": 2,
            "name": "peter",
            "city": "Chennai",
            "marks":63,
            "grade": "B"
            
        }
    ]

I used the below code to achieve the same in javascript. How do I implement this in java?

async mergeData(data1, data2, key) {
    const result = data1.map(a =>
      Object.assign({}, a,
        data2.find(b => b[key] === a[key])
      )
    )
    return result
  }

If the attributes your data contains are always the same, then the easiest way would be to create an ArrayList and then call the toArrayMethod after all the entries were added to the ArrayList, otherwise you have to account for different cases where the id's don't match which would need a lot of code to account for different Array Sizes.

Then you simply iterate in 2 nested for loops over the arrays you were given and if the id's match, then you use the add method of ArrayList to add a new entry to your ArrayList.

The other question is what object type your data actually has, because I don't think you can create object pairs like of the nature of "attribute_name" = value in java, so your input is probably some json you're reading in. You could use gson or other libraries to map your json to 2 java classes, then use another 3rd class for the combined data.

Another way would be to map it yourself with a json handling library to a java class or some datastructure like a HashMap. A HashMap would make most sense if you have no clue what attributes your java class would have in the future.

Another way would be to map the object from json to another json with a json handling library, with 2 for loops iterating over your json arrays.

public static void main(String... args) {
    List<Map<String, String>> studentDetails = List.of(
            Map.of("id", "1", "name", "sam", "city", "Chennai"),
            Map.of("id", "2", "name", "peter", "city", "Chennai"));
    List<Map<String, String>> studentGrades = List.of(
            Map.of("id", "1", "marks", "95", "grade", "A"),
            Map.of("id", "2", "marks", "63", "grade", "B"));

    List<Map<String, String>> res = merge(studentDetails, studentGrades);
}

public static List<Map<String, String>> merge(
        List<Map<String, String>> studentDetails,
        List<Map<String, String>> studentGrades) {
    Map<String, Map<String, String>> map = new HashMap<>();
    Consumer<Map<String, String>> add = studentData -> {
        String id = studentData.get("id");
        map.computeIfAbsent(id, key -> new HashMap<>());
        map.get(id).putAll(studentData);
    };

    studentDetails.forEach(add);
    studentGrades.forEach(add);

    return new ArrayList<>(map.values());
}

You can use streams and records like bellow like below:

package pl.maro;

import java.util.Collection;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.Stream;

public class MyUtils {

    public static void main(String[] args) {
        var studentDetails = List.of(
            new StudentDetail(1, "sam", "Chennai"),
            new StudentDetail(2, "peter", "Chennai")
        );

        var studentGrades = List.of(
                new StudentGrade(1, 95, 'A'),
                new StudentGrade(2, 63, 'B')
        );

        List<StudentDao> studentDaos = yourMethod(studentDetails, studentGrades);
        studentDaos.forEach(System.out::println);
    }

    private static List<StudentDao> yourMethod(List<StudentDetail> studentDetails, List<StudentGrade> studentGrades) {
        var detailMap = studentDetails.stream().collect(Collectors.toMap(k -> k.id, v -> v));
        var gradeMap = studentGrades.stream().collect(Collectors.toMap(k-> k.id, v->v));

        return Stream.of(detailMap.keySet(), gradeMap.keySet())
                .flatMap(Collection::stream)
                .collect(Collectors.toSet())
                .stream()
                .filter(id -> detailMap.containsKey(id) && gradeMap.containsKey(id))
                .map(id -> createStudentDao(detailMap.get(id), gradeMap.get(id)))
                .toList();
    }

    private static StudentDao createStudentDao(StudentDetail studentDetail, StudentGrade studentGrade) {
        return new StudentDao(studentDetail.id, studentDetail.name, studentDetail.surname, studentGrade.marks, studentGrade.grade);
    }

    record StudentDetail(int id, String name, String surname) {}
    record StudentGrade(int id, int marks, char grade) {}
    record StudentDao(int id, String name, String surname, int marks, char grade) {
        @Override
        public String toString() {
            return "StudentDao{" +
                    "id=" + id +
                    ", name='" + name + '\'' +
                    ", surname='" + surname + '\'' +
                    ", marks=" + marks +
                    ", grade=" + grade +
                    '}';
        }
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM