【问题标题】:Converting Java class to List<List<String>> to show in a table将 Java 类转换为 List<List<String>> 以显示在表格中
【发布时间】:2018-09-09 22:22:05
【问题描述】:

我想在 Java 中的一些类之间进行转换以显示在表格中。 我收到了List&lt;Version&gt;(删除了 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")
            ))
        );

我想将其转换为表格,以便于阅读。在哪里,我想合并包含相同名称和版本的作业,当版本不同时,再添加一行并指出哪个服务器的版本不同,例如:

+------------+--------------+------------+
| job        | DEV          | UK         |
+------------+--------------+------------+
| a          | 1.1.1        | 1.1.1      |
| b          | 10.0.1       | 10.0.0     |
| b          |              | 10.0.1 (4) |
| c          | 2.0.1        | 2.0.2      |
| c          | 2.0.1 (3)    |            |
+------------+--------------+------------+

好的,所以,如您所见,(x) 是不正确的服务器,例如,我收到了至少 7 个项目的List&lt;Version&gt;(3 个来自 DEV,4 个来自英国),恰好有 3 个列表中每个项目(abc)中的作业,最后,对于 a,我将在作业 a 的所有 7 个条目中拥有版本 1.1.1,而对于 @ 987654334@ 我将在 DEV 中拥有所有 3 个版本 10.0.1,但在英国的服务器 uk-4.lan 中拥有 3 个版本 10.0.0 和 1 个版本 10.0.1。 c 也会有类似的结果,但结果不同的服务器将是 dev-3.lan 服务器。

现在,我的问题是如何将List&lt;Version&gt; 转换为一个简单的List&lt;List&lt;String&gt;&gt; 来表示这个表或类似的东西?不用担心打印,因为我已经完成了这部分。

所以,我希望我的输出是这样的:

var expectedOutput = List.Of
        List.of("apps","DEV", "Uk"),
        List.of("a", "1.1.1", "1.1.1"),
        List.of("b", "10.0.1", "10.0.0"),
        List.of("b", "", "10.0.1 (4)"),
        List.of("c", "2.0.1", "2.0.2"),
        List.of("c", "2.0.2 (3)", ""),
        )
    );

但是,如果你告诉我如何使用另一种类型的结构生成表格,它也是有效的。

非常感谢, 若昂

【问题讨论】:

  • 您的问题不清楚,我们无法回答。请解释输入和期望的输出。
  • 我相信@korolar 有一个很好的输入示例,而输出将是一个变量 Map> 其中哪个整数代表表格的行和 List 将是列值。最后我想看一张桌子,不需要是地图,可以是别的东西。干杯,若昂

标签: java list lambda hashmap set


【解决方案1】:

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

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

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);
        }
    }
}

【讨论】:

  • 感谢示例代码。当我说:Each item of the list is the information of one server, so multiple servers contains multiple jobs, but each of the servers have the same jobs, but the version can be different. 时,我的意思是我将永远有相同的工作,但来自不同的服务器。感谢您的示例,这似乎是一个不错的解决方案,让我对其进行测试,我会将其作为更正的解决方案。
  • 抱歉,我没有得到解析器的输出:` Map>>>` 如何在表格中转换它如我的问题所示?
  • 好的,我最后使用了你的解决方案。我改变的是展示它的方式,所以现在我以你返回的方式展示它,现在很好。谢谢。
猜你喜欢
  • 2021-09-17
  • 1970-01-01
  • 2022-01-05
  • 2015-06-05
  • 1970-01-01
  • 2021-08-08
  • 2022-01-11
  • 1970-01-01
  • 2011-02-02
相关资源
最近更新 更多