3

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, marksandgrade. 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
  }
6
  • 1
    So what have you tried? Or what would you do in Javascript to achieve this? Commented Dec 1, 2021 at 6:44
  • async mergeData(data1, data2, key) { const result = data1.map(a => Object.assign({}, a, data2.find(b => b[key] === a[key]) ) ) return result }---this was the code I implemented in javascript and it works Commented Dec 1, 2021 at 6:52
  • include that in your question to make it more valuable for future readers :) Commented Dec 1, 2021 at 6:55
  • Is your input a java literal or are you mapping json objects to java? Commented Dec 1, 2021 at 7:04
  • these objects are result of few sql queries mapped to json objects Commented Dec 1, 2021 at 7:08

3 Answers 3

1

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.

Sign up to request clarification or add additional context in comments.

Comments

1

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 +
                    '}';
        }
    }
}

3 Comments

var and record are new keywords @oleg.cherednik
@oleg.cherednik this is java17
btw var's is form java10, record's from java14, and you can invoke directly toList() on stream from java17 previously you should use collect(Collectors.toList())
1
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());
}

public static class StudentDetails {

    private int id;
    private String name;
    private String city;

    public StudentDetails(int id, String name, String city) {
        this.id = id;
        this.name = name;
        this.city = city;
    }

}

public static class StudentGrades {

    private int id;
    private int marks;
    private String grade;

    public StudentGrades(int id, int marks, String grade) {
        this.id = id;
        this.marks = marks;
        this.grade = grade;
    }

}

public static class Student {

    private final int id;
    private String name;
    private String city;
    private int marks;
    private String grade;

    public Student(int id) {
        this.id = id;
    }

}

public static void main(String... args) {
    List<StudentDetails> studentDetails = List.of(
            new StudentDetails(1, "sam", "Chennai"),
            new StudentDetails(2, "peter", "Chennai"));
    List<StudentGrades> studentGrades = List.of(
            new StudentGrades(1, 95, "A"),
            new StudentGrades(2, 63, "B"));
    List<Student> students = merge(studentDetails, studentGrades);
}

public static List<Student> merge(List<StudentDetails> studentDetails,
        List<StudentGrades> studentGrades) {
    Map<Integer, Student> map = new HashMap<>();

    studentDetails.forEach(studentDetail -> {
        Student student = map.computeIfAbsent(studentDetail.id, Student::new);
        student.name = studentDetail.name;
        student.city = studentDetail.city;
    });

    studentGrades.forEach(studentGrade -> {
        map.computeIfAbsent(studentGrade.id, Student::new);
        studentGrade.marks = studentGrade.marks;
        studentGrade.grade = studentGrade.grade;
    });

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

6 Comments

This solution returns list of map. Result should be a list.
List of what? I gave an example with List<Map<String, String>> as input and output parameters.
I can see java in tags either.
"List of what" is rather question to author not to me. Propably some Dao object. 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"}]
The code looks fine...but I have created seperate classes for student details and student grades and setting the values using setters and getters. So Ideally it is like List<Student_details> sdetails=new ArrayList<Student_details>(); List<Student_grades> sgrades=new ArrayList<Student_grades>(); and these detailsa re populated from calls to sql server. Am still stuck up at this step.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.