"merge" 两个读者变成一个作者

"merge" two readers into one writer

我需要实现方法

void filter(Reader mails, Reader groups, Writer users) throws IOException

以这样一种方式,它将 reader 中的两条数据组合到一个写入器中。

mails 的文件如下所示:

Login;Email
login1;mail1@mail.com
login2;mail2@mail.com
login3;mail3@mail.com
login4;mail4@mail.com

groups 的文件如下所示:

Login;Group;
login1;Group1
login2;Group2
login3;Group3
login4;Group2

合并的结果应该是这样的:

Login;Email;Group
login1;mail1@mail.com;Group1
login2;mail2@mail.com;Group2
login3;mail3@mail.com;Group3
login4;mail4@mail.com;Group2

所以,我想到的是:从第一个 reader 获取一个字符串,然后从第二个 reader 获取另一个字符串,根据需要操作它们,然后用 writer 写入结果.

但是有没有办法让它变得不同或更优雅呢?

PS: 我只能使用 ReaderWriter 类.

顺便说一句:当我用 Writer 向文件写入内容时,如果我查看该文件,我会看到一些不可读的内容。但是,如果我用 Reader 读取同一个文件,然后在控制台上打印它,它看起来没问题。正常吗?或者我如何写入文件以使其可读?

如果你想用这个签名实现一个方法,你可以这样做:

public static void main(String[] args) throws Exception {
    String mails = "Login;Email\n"
            + "login1;mail1@mail.com\n"
            + "login2;mail2@mail.com\n"
            + "login3;mail3@mail.com\n"
            + "login4;mail4@mail.com";
    String groups = "Login;Group;\n"
            + "login1;Group1\n"
            + "login2;Group2\n"
            + "login3;Group3\n"
            + "login4;Group2";

    Reader mailsReader = new StringReader(mails);
    Reader groupsReader = new StringReader(groups);
    Writer mergedWriter = new StringWriter();

    filter(mailsReader, groupsReader, mergedWriter);

    System.out.println(mergedWriter.toString());
}

static void filter(Reader mails, Reader groups, Writer users) throws IOException {
    BufferedReader mbr = new BufferedReader(mails);
    BufferedReader gbr = new BufferedReader(groups);
    BufferedWriter ubw = new BufferedWriter(users);

    String ml = mbr.readLine();
    String gl = gbr.readLine();
    while (ml != null && gl != null) {
        ubw.write(ml + ";" + gl.split(";")[1] + "\n");
        ml = mbr.readLine();
        gl = gbr.readLine();
    }
    ubw.flush();
}

输出:

Login;Email;Group
login1;mail1@mail.com;Group1
login2;mail2@mail.com;Group2
login3;mail3@mail.com;Group3
login4;mail4@mail.com;Group2

在公用键 Login 上看起来像 join。 使用一些地图和一些 POJOs.

应该很容易解决这个问题

下面的一些附加信息应该有助于澄清我的想法。


让我们考虑以下数据table。它包含人们的名字和姓氏、他们的电子邮件地址和登录信息。

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+ Login             + Email            + First name    + Last name     +
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+ smith             + smith@mail.com   + John          + Smith         +
+ miller            + miller@mail.com  + John          + Miller        +
+ jackson           + mail@jackson.com + Scott         + Jackson       +
+ scott             + me@scott.com     + Scott         + Jackson       +
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

这些信息对于简单的数据查询来说已经足够了。如果我们想知道 John Smith 的电子邮件地址是什么,我们必须在第一个 table 中执行搜索。如果我们想知道 Scott Jackson 的地址,就会遇到问题,因为在我们的数据库中有两个人的名字完全相同。

所以需要一个区分人的手段,那就是栏目Login。它在这个 table 中是唯一的,因此可以用来避免歧义。 因为Login有这个属性,所以叫做key.

下一个 table 包含每次登录的组隶属关系。

++++++++++++++++++++++++++++++++++++++++
+ Login             + Group            +
++++++++++++++++++++++++++++++++++++++++
+ smith             + user             +
+ miller            + user             +
+ jackson           + admin            +
+ scott             + admin            +
++++++++++++++++++++++++++++++++++++++++

上面的 table 也有 Login 作为键。使用 属性 允许我们进行另一种类型的查询。可以询问人员的群组隶属关系,为此,我们必须检索相关用户的登录信息。因此使用第一个table。由于 Login 是第二个 table 中的一个键,它可用于获取组隶属关系。

这个过程称为加入,我们将第二个table中的组隶属关系与第一个[=48=中的名字和第二个名字的信息结合起来] 并将登录信息用作 key.

自然联接对所有行执行此操作。在这一点上,我希望很清楚为什么,我提出了一个加入。这 2 个文件对应 2 tables(它们对数据顺序的变化是不变的)。加入它们会产生包含所有信息的第三个 table。打印 table 是对 OP 问题的回答。

要利用底层关系代数的强大功能,可以使用以 Login 作为键的简单 java.util.Map

使用 Map 和 POJO 容器如何?

Pojo

String email;
String group;

然后你有一个散列图

Map<String,EmailGroup> emailGroup = new HashMap<String,EmailGroup>();

然后您的阅读代码将阅读电子邮件列表,然后填充群组。

readEmail(emailGroup);
readGroup(emailGroup);


readEmail(Map<String,EmailGroup> map)
{
    EmailGroup tempgroup;
    if(map.contains(login))
    {
       tempGroup = map.get();
    }
    else
    {
       EmailGroup tempGroup = new EmailGroup();
    }
    tempGroup.setEmail(readEmailAddress);
    map.put(login,tempGroup); 
}

readGroup 做同样的事情但调用 setGroup();

这不是一个完整的解决方案,但应该提供有关解决此问题的另一种可能方法的建议。