在同一字段逻辑上合并两个列表

merge two list on same field logic

提问人:tom 提问时间:10/26/2023 最后编辑:geocodeziptom 更新时间:10/27/2023 访问量:43

问:

我有两个列表,两个列表具有相同的字段。有些学生在不同的国家有两所房子。我想在合并两个列表的同时增加 studentList2 的 id 字段。我可以使用两个for循环来检查所有列表,但是您知道这个问题的更好解决方案吗?

List1 是 studentList1

schoolId | id | countryCode | cityCode
5555       1      20            1
5555       1      24            2
5555       2      1             3
5555       3      1             3
5555       4      1             3

List2 是 studentList2

  schoolId | id | countryCode | cityCode
  6666       1      20            1
  6666       1      24            2
  6666       2      20            1
  6666       2      24            2
  6666       3      20            1
  6666       3      24            2
  6666       4      20            1
  6666       4      24            2
  6666       5      1             3
  6666       6      1             3

我的期望是

  schoolId | id | countryCode | cityCode
  5555       1      20            1
  5555       1      24            2
  5555       2      1             3
  5555       3      1             3
  5555       4      1             3
  6666       5      20            1
  6666       5      24            2
  6666       6      20            1
  6666       6      24            2
  6666       7      20            1
  6666       7      24            2
  6666       8      20            1
  6666       8      24            2
  6666       9      1             3
  6666       10     1             3

我可以使用两个 for 循环来比较列表字段,但我想找到更好的解决方案。

爪哇岛 列表 爪哇-8

评论

2赞 Scott Hunter 10/27/2023
请发布您尝试解决此问题的帖子。

答:

0赞 Mr. Polywhirl 10/27/2023 #1

您必须将所有数据集 A 添加到新列表中,并通过引用数据集 A 中的最后一项来计算 id 偏移量。

获得偏移量后,可以克隆所有数据集 B 并将其追加到新列表中。

static List<Student> combine(List<Student> left, List<Student> right) {
    List<Student> combined = new ArrayList<>(left);
    final long idOffset = combined.get(combined.size() - 1).getId();
    combined.addAll(right.stream()
            .map((student ->
                    student.toBuilder()
                            .id(student.getId() + idOffset)
                            .build()))
            .toList());
    return combined;
}

完整示例

import lombok.Builder;
import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.ToString;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

public class DataProcessor {
    private static final String[] COLUMN_NAMES = { "schoolId", "id", "countryCode", "cityCode" };

    public static void main(String[] args) {
        List<Student> datasetA = parseDataset(DATASET_A);
        List<Student> datasetB = parseDataset(DATASET_B);
        List<Student> combined = combine(datasetA, datasetB);
        printDataset(combined);
    }

    private static String datasetHeaderFormat = "%8s | %4s | %11s | %8s%n";
    private static String datasetRowFormat = "%8d %6d %13d %10d%n";

    static void printDataset(List<Student> students) {
        System.out.printf(datasetHeaderFormat, COLUMN_NAMES);
        for (Student student : students) {
            System.out.printf(datasetRowFormat,
                    student.getSchoolId(),
                    student.getId(),
                    student.getCountryCode(),
                    student.getCityCode());
        }
    }

    static List<Student> combine(List<Student> left, List<Student> right) {
        List<Student> combined = new ArrayList<>(left);
        final long idOffset = combined.get(combined.size() - 1).getId();
        combined.addAll(right.stream()
                .map((student ->
                        student.toBuilder()
                                .id(student.getId() + idOffset)
                                .build()))
                .toList());
        return combined;
    }

    static List<Student> parseDataset(String dataset) {
        return Arrays.stream(dataset.trim()
                        .split("\n")).skip(1)
                .map(DataProcessor::parseLine)
                .collect(Collectors.toList());
    }

    private static Student parseLine(String line) {
        String[] tokens = line.trim().split("\\s+");
        if (tokens.length != 4) {
            throw new IllegalArgumentException("Expected a token count of 4");
        }
        return Student.builder()
                .schoolId(Long.parseLong(tokens[0]))
                .id(Long.parseLong(tokens[1]))
                .countryCode(Integer.parseInt(tokens[2]))
                .cityCode(Integer.parseInt(tokens[3]))
                .build();
    }

    @Builder(toBuilder = true)
    @EqualsAndHashCode
    @Getter
    @ToString
    private static final class Student {
        private long id;
        private long schoolId;
        private int countryCode;
        private int cityCode;
    }

    static String DATASET_A = """
            schoolId | id | countryCode | cityCode
            5555       1      20            1
            5555       1      24            2
            5555       2      1             3
            5555       3      1             3
            5555       4      1             3
            """;

    static String DATASET_B = """
            schoolId | id | countryCode | cityCode
            6666       1      20            1
            6666       1      24            2
            6666       2      20            1
            6666       2      24            2
            6666       3      20            1
            6666       3      24            2
            6666       4      20            1
            6666       4      24            2
            6666       5      1             3
            6666       6      1             3
            """;
}

输出

schoolId |   id | countryCode | cityCode
    5555      1            20          1
    5555      1            24          2
    5555      2             1          3
    5555      3             1          3
    5555      4             1          3
    6666      5            20          1
    6666      5            24          2
    6666      6            20          1
    6666      6            24          2
    6666      7            20          1
    6666      7            24          2
    6666      8            20          1
    6666      8            24          2
    6666      9             1          3
    6666     10             1          3