为了账号安全,请及时绑定邮箱和手机立即绑定

将 Java 类转换为 List<List<String>> 以显示在表格中

将 Java 类转换为 List<List<String>> 以显示在表格中

森栏 2021-09-12 10:33:54
我想在 Java 中的某些类之间进行转换以显示在表格中。我收到一个List<Version>(删除了 getter/setter 以使其更短):public class Version {    private String server;    private List<Job> jobs;}public class Job {    private String name;    private String version;}现在,我所拥有的是一个工具来检查所有作业的服务器数据: - 列表中的每一项都是一个服务器的信息,因此多个服务器包含多个作业,但每个服务器都有相同的作业,但版本可能不同。- 所以,Version.server是服务器Job.name的名称,作业的名称,以及作业Job.version的版本。- 此外,所有服务器都以相同的名称开头,例如:dev-1.lan、dev-2.lan、uk-1.lan、us-1.lan 等;感谢@Korolar,这是一个有效的输入:   var input = List.of(            new Version("dev-1.lan", List.of(                new Job("a", "1.1.1"),                new Job("b", "10.0.1"),                new Job("c", "2.0.1")            )),            new Version("dev-2.lan", List.of(                new Job("a", "1.1.1"),                new Job("b", "10.0.1"),                new Job("c", "2.0.1")            )),            new Version("dev-3.lan", List.of(                new Job("a", "1.1.1"),                new Job("b", "10.0.1"),                new Job("c", "2.0.2")            )),            new Version("uk-1.lan", List.of(                new Job("a", "1.1.1"),                new Job("b", "10.0.0"),                new Job("c", "2.0.2")            )),            new Version("uk-2.lan", List.of(                new Job("a", "1.1.1"),                new Job("b", "10.0.0"),                new Job("c", "2.0.2")            )),            new Version("uk-3.lan", List.of(                new Job("a", "1.1.1"),                new Job("b", "10.0.0"),                new Job("c", "2.0.2")            )),            new Version("uk-4.lan", List.of(                new Job("a", "1.1.1"),                new Job("b", "10.0.1"),                new Job("c", "2.0.2")            ))        );我想将其转换为表格,以便于阅读。在哪里,我想合并包含相同名称和版本的作业,当版本不同时,再添加一行并指出哪个服务器的版本不同,例如:
查看完整描述

1 回答

?
暮色呼如

TA贡献1853条经验 获得超9个赞

恐怕您的问题对于“哪个服务器不相同”问题并不完全清楚。我不认为它定义得很好。例如,如果您有四台服务器,每台服务器都有不同的作业版本怎么办?


考虑到这一点,我假设您想要的是通过以下测试:


import static org.junit.jupiter.api.Assertions.assertEquals;


import java.util.List;

import java.util.Map;

import java.util.Set;

import org.junit.jupiter.api.Test;


class QuestionTest {

    @Test

    void example() {

        var input = List.of(

            new Version("dev-1.lan", List.of(

                new Job("a", "1.1.1"),

                new Job("b", "10.0.1"),

                new Job("c", "2.0.1")

            )),

            new Version("dev-2.lan", List.of(

                new Job("a", "1.1.1"),

                new Job("b", "10.0.1"),

                new Job("c", "2.0.1")

            )),

            new Version("dev-3.lan", List.of(

                new Job("a", "1.1.1"),

                new Job("b", "10.0.1"),

                new Job("c", "2.0.2")

            )),

            new Version("uk-1.lan", List.of(

                new Job("a", "1.1.1"),

                new Job("b", "10.0.0"),

                new Job("c", "2.0.2")

            )),

            new Version("uk-2.lan", List.of(

                new Job("a", "1.1.1"),

                new Job("b", "10.0.0"),

                new Job("c", "2.0.2")

            )),

            new Version("uk-3.lan", List.of(

                new Job("a", "1.1.1"),

                new Job("b", "10.0.0"),

                new Job("c", "2.0.2")

            )),

            new Version("uk-4.lan", List.of(

                new Job("a", "1.1.1"),

                new Job("b", "10.0.1"),

                new Job("c", "2.0.2")

            ))

        );


        var expectedOutput = Map.of(

            "a", Map.of(

                "DEV", Map.of(

                    "1.1.1", Set.of(1, 2, 3)

                ),

                "UK", Map.of(

                    "1.1.1", Set.of(1, 2, 3, 4)

                )

            ),

            "b", Map.of(

                "DEV", Map.of(

                    "10.0.1", Set.of(1, 2, 3)

                ),

                "UK", Map.of(

                    "10.0.0", Set.of(1, 2, 3),

                    "10.0.1", Set.of(4)

                )

            ),

            "c", Map.of(

                "DEV", Map.of(

                    "2.0.1", Set.of(1, 2),

                    "2.0.2", Set.of(3)

                ),

                "UK", Map.of(

                    "2.0.2", Set.of(1, 2, 3, 4)

                )

            )

        );


        var actualOutput = Main.parse(input);


        assertEquals(expectedOutput, actualOutput);

    }

}

有了这个假设,您的问题就变成了使用 Java lambda 的有趣练习。我找到的解决方案是:


import static java.util.stream.Collectors.groupingBy;

import static java.util.stream.Collectors.mapping;

import static java.util.stream.Collectors.toSet;


import java.util.List;

import java.util.Map;

import java.util.Set;


class Main {

    static Map<String, Map<String, Map<String, Set<Integer>>>> parse(List<Version> input) {

        return input.stream()

            .flatMap(version -> version.jobs.stream().map(job -> new Entry(version, job)))

            .collect(

                groupingBy(

                    entry -> entry.jobName,

                    groupingBy(

                        entry -> entry.serverName,

                        groupingBy(

                            entry -> entry.jobVersion,

                            mapping(entry -> entry.serverNumber, toSet())

                        )

                    )

                )

            );

    }

}

助手类Entry定义为:


class Entry {

    final String serverName;

    final int serverNumber;

    final String jobName;

    final String jobVersion;


    Entry(Version version, Job job) {

        this.serverName = version.serverName;

        this.serverNumber = version.serverNumber;

        this.jobName = job.name;

        this.jobVersion = job.version;

    }

}

与:


class Job {

    final String name;

    final String version;


    Job(String name, String version) {

        this.name = name;

        this.version = version;

    }

}

最后:


import java.util.List;

import java.util.Locale;

import java.util.regex.Matcher;

import java.util.regex.Pattern;


class Version {

    private static final Pattern SERVER_NAME_PATTERN = Pattern.compile("(\\w+)-(\\d+)\\.lan");


    final String server;

    final List<Job> jobs;


    final String serverName;

    final int serverNumber;


    Version(String server, List<Job> jobs) {

        this.server = server;

        this.jobs = List.copyOf(jobs);


        Matcher matcher = SERVER_NAME_PATTERN.matcher(server);

        if (matcher.matches()) {

            this.serverName = matcher.group(1).toUpperCase(Locale.US);

            this.serverNumber = Integer.parseInt(matcher.group(2));

        } else {

            throw new IllegalArgumentException("Invalid server: " + server);

        }

    }

}


查看完整回答
反对 回复 2021-09-12
  • 1 回答
  • 0 关注
  • 174 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信