[英]Strange behavior of Nested while loop while iterating over a text file
我是Java新手。 我試圖遍歷幾個.txt
文件,以將文件的一行與第二個文件的每一行進行比較。 這是我的兩個文件: listread.txt
和csvread.txt
。
這是我正在使用的代碼:
try {
BufferedReader csvReader = new BufferedReader(new FileReader("/data/csvread.txt"));
BufferedReader listReader = new BufferedReader(new FileReader("/data/list.txt"));
String csvItem, listItem;
int count =0;
while((csvItem = csvReader.readLine()) != null){
System.out.println("before second loop:"+csvItem);
while ((listItem = listReader.readLine())!= null) {
System.out.println("list Item: "+listItem.toLowerCase().split("¬")[1]);
System.out.println("csv Item: "+csvItem.toLowerCase());
if(listItem.toLowerCase().split("¬")[1].contains(csvItem.toLowerCase())){
count++;
}
}
}
}catch(Exception e){
e.printStackTrace();
}
當我運行此命令時,僅將csvread.txt
的第一行(存儲在變量csvItem
)與csvItem
的所有行進行listread.txt
。 這是示例輸出:
before second loop:Record Category
list item: provisions
csv Item: record category
list item: request category
csv Item: record category
list item: elevator
csv Item: record category
list item: assessment
csv Item: record category
list item: associates
csv Item: record category
list item: score
csv Item: record category
list item: attachments
csv Item: record category
它只有在所有行迭代list.txt
文件與第一線csvread.txt
文件。 不會繼續前進到csvread.txt
的第二行,並且該程序結束在最后一行拋出錯誤:
java.lang.ArrayIndexOutOfBoundsException: 1
at test.main(test.java:52)
引用行System.out.println("list item: "+listItem.toLowerCase().split("¬")[1]);
。 該語句與我猜想的迭代無關。 不知道為什么會引發此錯誤。
但是,當我注釋掉第二個for循環時,它可以對csvread.txt
文件中的所有行進行很好的迭代。 這是一個示例輸出,其中僅第一個while循環和第二個循環被注釋掉了:
before second loop:Record Category
before second loop:Type
before second loop:Name
before second loop:State
before second loop:Number
before second loop:ID (Self)
before second loop:Parent
before second loop:Title
僅當存在嵌套循環時,才會發生此問題。 當只有一個循環時,根本沒有問題。 有人可以闡明這種奇怪的行為嗎? 另外我該如何克服呢?
編輯:我添加了一個if
條件來檢查行是否包含¬
因為我在該字符上分割了行:
if(listItem.contains("¬")){
System.out.println("list item: "+listItem.toLowerCase().split("¬")[1]);
System.out.println("csv Item: "+csvItem.toLowerCase());
if(listItem.toLowerCase().split("¬")[1].contains(csvItem.toLowerCase())){
count++;
}
}
不,我再也沒有例外。 但是,該行為仍然很奇怪。 這是添加if
之后的輸出:
before second loop:Record Category
list item: provisions
csv Item: record category
list item: request category
csv Item: record category
list item: elevator
csv Item: record category
list item: assessment
csv Item: record category
list item: associates
csv Item: record category
list item: score
csv Item: record category
list item: attachments
csv Item: record category
before second loop:Type
before second loop:Name
before second loop:State
before second loop:Number
before second loop:ID (Self)
before second loop:Parent
before second loop:Title
現在的其它元素被遍歷在csvread.txt
但在線路中的比較listread.txt
不除了第一元件hapeening。
任何幫助,將不勝感激。 謝謝!
使用嵌套循環時,內部循環將完全執行。 然后執行控制從內循環中出來,並開始外循環的下一次迭代。 因此,如果要逐行比較兩個文件的內容,則不應有任何內部循環。 下面是在這種情況下可以嘗試執行的示例代碼。 雖然,我還沒有測試。
try {
BufferedReader csvReader = new BufferedReader(new FileReader("/data/csvread.txt"));
BufferedReader listReader = new BufferedReader(new FileReader("/data/list.txt"));
String csvItem, listItem;
int count =0;
while((csvItem = csvReader.readLine()) != null){
System.out.println("before second loop:"+csvItem);
listItem = listReader.readLine();
if (listItem != null){
if(listItem.toLowerCase().split("¬")[1].contains(csvItem.toLowerCase())){
count++;
}
}else{
//The listItem has no more lines to compare, so ending the process.
break;
}
}
}catch(Exception e){
e.printStackTrace();
}
我希望這有幫助。
注意:給出上述答案的前提是,要求是逐行比較兩個文件的內容。
您的訪問權限
listItem.toLowerCase().split("¬")[1]
至關重要,因為您始終希望所有行都帶有您的“¬”。 如果不是這種情況,則拆分將不會返回數組,並且您將在位置[1]處訪問returend數組,該數組將失敗並返回IndexOutOfBounds。
從我對listReader
評論擴展到第一次迭代后指向文件的末尾。 BufferedReader
不提供移動文件指針的機制,因此一種簡單的方法是將listReader
的創建移動到外部循環內部:
try {
BufferedReader csvReader = new BufferedReader(new FileReader("/data/csvread.txt"));
// BufferedReader listReader = new BufferedReader(new FileReader("/data/list.txt"));
String csvItem, listItem;
int count =0;
while((csvItem = csvReader.readLine()) != null){
System.out.println("before second loop:"+csvItem);
BufferedReader listReader = new BufferedReader(new FileReader("/data/list.txt"));
while ((listItem = listReader.readLine())!= null) {
System.out.println("list Item: "+listItem.toLowerCase().split("¬")[1]);
System.out.println("csv Item: "+csvItem.toLowerCase());
if(listItem.toLowerCase().split("¬")[1].contains(csvItem.toLowerCase())){
count++;
}
}
}
}catch(Exception e){
e.printStackTrace();
}
因此,每次迭代都會有一個新的listReader
,它從文件的頂部開始。
但這可能是太多的I / O。 如果list.txt的大小不是太大,則可能只讀取一次,解析它,然后存儲在Set<String>
以便以后進行比較:
try (BufferedReader listReader = new BufferedReader(new FileReader("/data/list.txt"));
BufferedReader csvReader = new BufferedReader(new FileReader("/data/csvread.txt"))) {
String listItem = null;
Set<String> listItems = new HashSet<>();
while ((listItem = listReader.readLine()) != null) {
listItems.add(listItem.toLowerCase().split("¬")[1]);
}
String csvItem;
int count = 0;
while ((csvItem = csvReader.readLine()) != null) {
System.out.println("before second loop:" + csvItem);
for (String item : listItems) {
System.out.println("list Item: " + item);
System.out.println("csv Item: " + csvItem.toLowerCase());
if (item.contains(csvItem.toLowerCase())) {
count++;
}
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
還移至try-with-resources,以確保正確關閉csvReader
和listReader
。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.