2015-04-02 43 views
1

我需要實現方法「合併」兩個讀卡器成一個作家

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

以這樣一種方式,它會結合數據FROW讀者的兩片成一個作家。

的文件mails應該是這樣的:

Login;Email 
login1;[email protected] 
login2;[email protected] 
login3;[email protected] 
login4;[email protected] 

groups文件應該是這樣的:

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

和合並的結果應該是這樣的:

Login;Email;Group 
login1;[email protected];Group1 
login2;[email protected];Group2 
login3;[email protected];Group3 
login4;[email protected];Group2 

那麼,我想到的是:得到一個str從第一個閱讀器讀取數據,然後從第二個閱讀器讀取另一個字符串,根據需要操作它們,然後用寫入器寫入結果。

但是有沒有辦法讓它變得不同或更優雅?

PS:我不得不只使用ReaderWriter類。當我使用Writer向文件寫入內容時,如果我查看文件,我會看到一些不可讀的內容。但是,如果我用Reader讀取相同的文件,然後在控制檯上打印它,它看起來沒問題。這是正常的嗎?或者我如何寫入文件以使其可讀?

+0

你爲什麼要用'Reader'和'Writer'做這個?兩個輸入文件是否總是被排序,這樣來自兩者的行總是可以被合併? – 2015-04-02 12:29:33

+0

是的,他們是。那麼,我不想使用他們:)但這樣的任務) – 2015-04-02 12:31:07

+0

即使文件被排序,仍然可能會丟失一個條目。我發現很難依靠這樣的事情。 – mike 2015-04-03 02:32:48

回答

1

如果你想實現這個簽名的方法,你可以這樣做:

public static void main(String[] args) throws Exception { 
    String mails = "Login;Email\n" 
      + "login1;[email protected]\n" 
      + "login2;[email protected]\n" 
      + "login3;[email protected]\n" 
      + "login4;[email protected]"; 
    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;[email protected];Group1 
login2;[email protected];Group2 
login3;[email protected];Group3 
login4;[email protected];Group2 
+0

感謝您的想法! – 2015-04-02 12:46:41

+0

這個解決方案依賴於文件中數據的順序,它很容易中斷。 – mike 2015-04-03 02:28:19

+0

@mike是的。這就是爲什麼我在評論中問道:「兩個輸入文件是否總是被排序,以便兩者的行總是可以合併?」答案是「是的,他們是。」 – 2015-04-04 08:44:20

0

看起來像公共密鑰Login一個join。 這應該很容易解決一些地圖和一些POJO s。

在下面的一些額外的信息,應該有助於澄清我的想法。


讓我們考慮下面的數據表。它包含人們的姓名,電子郵件地址和登錄名。

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 
+ Login    + Email   + First name + Last name  + 
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 
+ smith    + [email protected] + John   + Smith   + 
+ miller   + [email protected] + John   + Miller  + 
+ jackson   + [email protected] + Scott   + Jackson  + 
+ scott    + [email protected]  + Scott   + Jackson  + 
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 

這些信息足以用於簡單的數據查詢。如果我們想知道John Smith的電子郵件地址是什麼,我們必須在第一個表格中執行搜索。如果我們想知道斯科特傑克遜的地址,我們有一個問題,因爲我們的數據庫中有兩個人名字完全相同。

所以有必要區分人,即列Login。它在此表中是獨一無二的,因此可以用來避免含糊不清。 由於Login具有此屬性,因此稱爲

此下表包含每個登錄的組聯繫。

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

上表還有Login作爲鍵。使用該屬性允許我們進行另一種查詢。有可能要求組織人員加入,爲此,我們必須檢索相關用戶的登錄名。因此使用第一個表格。由於Login是第二個表中的關鍵字,因此它可以用於獲取組關係。

這個過程被稱爲加盟,我們從第二個表合併組聯繫,從第一個表上的第一和第二名稱的信息和所使用的登錄信息爲關鍵

自然連接在所有行上執行此操作。在這一點上,我希望很清楚爲什麼,我提出了加入。這2個文件對應於2個表格(對於數據順序的變化是不變的)。加入他們會得到包含所有信息的第三個表格。打印該表格是對OP問題的回答。

要利用底層關係代數的一個簡單的java.util.MapLogin作爲鍵可以使用。

+0

如何?你能提供一些這樣的代碼嗎? – 2015-04-04 08:44:43

+0

是的,我可以,但如果有人理解加入的概念,那就是多餘的。所以我寧願提供更多與此相關的信息。如果還不清楚,我會添加一個小例子。 – mike 2015-04-04 10:27:53

+0

更新了我的答案。 – mike 2015-04-04 19:38:43

2

如何使用Map和POJO容器。

POJO的是

String email; 
String group; 

然後你有一個HashMap

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

這不是一個完整的解決方案,但應提供另一種解決此問題的可能方法的建議。

+0

我會有一個POJO'UserInfo',但這基本上就是我在說的。 +1 – mike 2015-04-04 20:14:08