2016-12-28 74 views
0

我是Java編程的新手,我已經通過比較列來分析CSV文件並打印出正確的CSV文件行。打印的行需要有唯一的第一列和第二列,第三列必須包含「否」,並且第四列的值大於或等於 12.Java:如何比較CSV文件的列和打印特定行

共有5列。

此外,我不允許使用任何爲您解析CSV的庫。

這是到目前爲止我的代碼:

private static String[] routerData; 

public static void main(String [] args) { 

    // Input of file which needs to be parsed 
    String csvFile = "./sample.csv"; 
    BufferedReader csvReader = null; 

    // Data split by ',' in CSV file 
    String line = null; 
    String csvSplitBy = ","; 

    try { 

     // Create the CSV file reader 
     csvReader = new BufferedReader(new FileReader(csvFile)); 
     while ((line = csvReader.readLine()) !=null) { 

      routerData = line.split(csvSplitBy, -1); 
      System.out.println(routerData[0] + ", " + routerData[1] + ", " + routerData[2] + ", " + routerData[3] + ", " + routerData[4]); 

     } 

    } catch (FileNotFoundException e) { 
     e.printStackTrace(); 
    } catch (IOException e) { 
     e.printStackTrace(); 
    } finally { 
     if (csvReader != null) { 
      try { 
       csvReader.close(); 
      } catch (IOException e) { 
       e.printStackTrace(); 
      } 
     } 
    } 
} 

}

編輯樣品CSV:

例如,一個樣品CSV文件應該是這樣的:

Name,IP,Working?,Version,Comments 
name,0.0.0.0,No,11.2,Some GUI Bugs 
name2,0.1.2.0,Yes,12.3, 
name,0.0.1.0,Yes,12.2,Case broken, 
name4,0.0.0.0,no,10.3 

因此,代碼必須採取一個CSV文件,然後打印取出具有唯一名稱(第1列),唯一IP(第2列)的行,「工作?」爲「否」。 (第3列),並且版本值高於12.

我不確定使用哪種數據結構將允許我比較列。

我非常感謝您的任何建議!

+0

第一列和第二列必須相對於整個CSV數據文件的第一列還是第二列是唯一的? – DevilsHnd

+0

@DevilsHnd整個CSV文件都是唯一的。因此,只有符合所有要求,我才能從CSV文件中打印出正確的行。 –

+0

在這種情況下@Adil Khan,請查看我對您問題的回答。 – DevilsHnd

回答

0

你的問題中的要求是相當混亂,事情不要」如果沒有示例CSV數據,就會變得更輕鬆。令人困惑的部分是關於唯一性的第1欄和第2欄數據。你認爲什麼是UNIQUE

A)是它是在這個意義上獨特之處在於第1列和或第2列含有未在任何其他CSV文件中的行重複的字符串或數值(其各自的列內沒有重複的)?

B)或者是它是在這個意義上,列1和或第2列包含一個字符串或數值的值,該值是在其自身獨特的,並且可以在其他CSV文件行中找到(允許內重複獨特其各列)?

下面的示例代碼假定爲唯一條件(A)。那麼這意味着,如果一個CSV文件含有如下逗號分隔的行然後只有兩個那些線將實現指定的數據的條件:

Jack,Flash,yes,14,Unknown Value 
Bob,Stick,no,11,Unknown Value 
Jack,Flash,no,22,Unknown Value 
Fred,Frog,yes,6,Unknown Value 
Bob,Stick,no,32,Unknown Value 
Tracey,Jones,no,17,Unknown Value 
Fred,Frog,no,23,Unknown Value 
John,Brown,no,12,Unknown Value 
Bob,Stick,yes,88,Unknown Value 

因爲只有那些兩行具有真正獨特的列1和2整個CSV文件。你能看到他們是哪條線嗎?

下面是示例代碼:

ArrayList<String> resultList = new ArrayList<>(); 
ArrayList<String> linesList = new ArrayList<>(); 
// Input of file which needs to be parsed 
String csvFile = "sample.csv"; 
BufferedReader csvReader; 

// Data split by ',' in CSV file 
String csvSplitBy = ","; 
try { 
    // Read the CSV file into an ArrayList array for easy processing. 
    String line; 
    csvReader = new BufferedReader(new FileReader(csvFile)); 
    while ((line = csvReader.readLine()) !=null) { 
     linesList.add(line); 
    } 
    csvReader.close(); 
} 
catch (IOException e) { e.printStackTrace(); } 

// Process each CSV file line which is now contained within 
// the linesList list Array 
for (int i = 0; i < linesList.size(); i++) { 
    String[] data = linesList.get(i).split(csvSplitBy); 
    String col1 = data[0]; 
    String col2 = data[1]; 
    String col3YesNo = data[2]; 
    //int col4Value = Integer.parseInt(data[3]); //WAS THIS 
    double col4Value = Double.parseDouble(data[3]); // *** SHOULD BE *** 
    String col5Unknown = data[4]; 

    // Determine if Column 1 and Column 2 data for the 
    // current line is unique to the entire CSV file. 
    boolean columns1And2AreUnique = true; 
    for (int j = 0; j < linesList.size(); j++) { 
     String[] tmp = linesList.get(j).split(csvSplitBy); 
     // Make sure we don't process the same line we are on... 
     if (j != i) { 
      if (col1.equals(tmp[0]) || col2.equals(tmp[1])) { 
       columns1And2AreUnique = false; 
       break; 
      } 
     } 
    } 
    if (columns1And2AreUnique && col3YesNo.equalsIgnoreCase("no") && col4Value >= 12.0) { 
     resultList.add(linesList.get(i)); 
    } 
} 

// Display the determined results from the CSV file. 
if (resultList.isEmpty()) { 
    System.out.println("There could be no data results gathered from the supplied\n" 
        + "CSV file which meets the required criteria."); 
} 
else { 
    System.out.println("Column 1\tColumn 2\tColumn 3\tColumn 4\tColumn 5"); 
    System.out.println("================================================" 
        + "========================\n"); 
    String padString = "  "; //Used for simple space padding in display 
    for (int i = 0; i < resultList.size(); i++) { 
     String[] tmp = resultList.get(i).split(csvSplitBy); 
     System.out.println(tmp[0] + padString.substring(tmp[0].length()) + "\t" 
         + tmp[1] + padString.substring(tmp[1].length()) + "\t" 
         + tmp[2] + padString.substring(tmp[2].length()) + "\t" 
         + tmp[3] + padString.substring(tmp[3].length()) + "\t" 
         + tmp[4]); 
    } 
} 

編輯:現在你已經從發佈的CSV文件的一些樣本數據...

好,我非常接近我的柱狀CSV數據類型假設,但確實需要更改代碼,因爲我現在知道第4個數據列包含Double數據類型值。

您需要的代碼行,指出改變:

int col4Value = Integer.parseInt(data[3]); 

到處理雙數據類型值,這行代碼:

double col4Value = Double.parseDouble(data[3]); 

這會幫助你一點點,而你修改代碼以滿足您的需求。

+0

對不起,我應該添加一個CSV示例!但是,這是唯一條件(A)。 請再次檢查我的帖子!我已經添加了一個應該幫助你的編輯! 希望這個清楚。我也要編輯你的代碼,看看我能否使它工作!非常感謝您的幫助! –

+0

@Adil Khan,感謝您發佈您的CSV數據樣本。爲了適應CSV數據行第4列包含Double數據類型這一事實,已經進行了小的一行代碼修改。看到我上面的編輯帖子。 – DevilsHnd

0

我會這樣做。首先創建一個代表一行數據的簡單類,讓它成爲A命名。接下來爲包含A對象列表的字段的此數據集創建包裝類B。爲此類創建公共方法,將返回滿足這些謂詞的行作爲參數傳遞。要找到唯一值,可以在另一個類中創建靜態公用程序方法。該方法作爲例子字符串列表(1列)的參數,並將返回可以通過B類方法旁邊的唯一值。看看Java的8個流API和映射方法來獲取第一列的值,即列表傳遞給該實用程序方法,你可以這樣做:

b.getList().stream().map(e -> e.getFirstValue()).collect(Collectors.asList());

+0

非常感謝!我現在要試試你的方法,並且會報告回來! –