"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: 我只能使用 Reader
和 Writer
类.
顺便说一句:当我用 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();
这不是一个完整的解决方案,但应该提供有关解决此问题的另一种可能方法的建议。
我需要实现方法
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: 我只能使用 Reader
和 Writer
类.
顺便说一句:当我用 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();
这不是一个完整的解决方案,但应该提供有关解决此问题的另一种可能方法的建议。