2017-07-29 78 views
1

所以通常情況下,我知道人們會使用標準的for循環迭代雖然陣列,像這樣的:文件IO,使用for-each循環從文件陣列讀取(:)在Java中

public static void readCodesFromFile(String filename, String[] codes) throws FileNotFoundException { 
    try (Scanner fin = new Scanner(new File(filename));) { 
     for (int i = 0; i <= codes.length - 1; i++) { 
      codes[i] = fin.nextLine(); 
     } 
    } 
} 

但,我非常想發現如何用每個循環代替這個來做到這一點。 在這一點上,我只需要知道它是否可以完成,但也會喜歡使用此循環執行此任務的效率和清潔度。我嘗試過類似的東西,並且多次移動東西,但似乎無法正確讀取任何內容。

下面是每個(:)我一直在努力:

public static void readCodesFromFile(String filename, String [] codes) throws FileNotFoundException { 
    try (Scanner fin = new Scanner(new File(filename));) { 
     for (String code : codes) { 
      codes = fin.nextLine(); 
     } 
    } 
} 
+0

你不能用'for-each'修改底層數組(它隱藏了迭代器)。你可以使用'Stream'(在Java 8+中,如果你想的話)。 'Stream.generate(() - > fin.nextLine())。limit(codes.length).collect(Collectors.toList())。toArray(codes);' –

+0

*「** ** ** ** **文件「*? – Andreas

+0

這是不可能的使用for-each循環,看看這裏 https://stackoverflow.com/questions/17969515/java-for-loop-by-value-or-by-reference –

回答

0

在這一點上,我只需要知道,如果這是可以做到...

無,而不是它寫的。首先,規範不允許,但你也處理不可變的String s。從第二個例子來說,code是對數組中元素的引用。一旦我做code = "foo";,code現在引用(推測)新的String和數組元素保留其原始值。

但是,我非常想發現如何做到這一點與每個 循環代替。

如果是這樣的話,爲什麼不反過來呢?不要遍歷數組,而是提供迭代文件的方法。

在這個答案,我要承擔兩件事情:

  1. 您提供IterableFileReader
  2. 你會使用ArrayList,而不是一個正常的數組(這讓過去與額外的好處索引問題,你將不再需要知道或關心行的文件

在這裏,在數字的的FileReader(與很多尚未實現):

class FileReader implements Iterable<String> { 

    @Override 
    public Iterator<String> iterator() { 
     return new FileReaderIterator(); 
    } 

    @Override 
    public void forEach(Consumer<? super String> action) { } 

    @Override 
    public Spliterator<String> spliterator() { return null; } 

    class FileReaderIterator implements Iterator<String> { 

     @Override 
     public boolean hasNext() { 
      return false; 
     } 

     @Override 
     public String next() { 
      return null; 
     } 

     @Override 
     public void remove() { } 

     @Override 
     public void forEachRemaining(Consumer<? super String> action) { } 
    } 
} 

假設你有這個實現,你可以用它像這樣:

List<String> lines = new ArrayList<>(); 
FileReader reader = new FileReader(...); 
for (String line : reader) { 
    lines.add(line); 
} 

我不建議你改變你的設計,而要考慮多麼不同的設計選擇可以提供。

+0

謝謝你的詳細解答。你說得很清楚。 –

0

另一種可以很容易地用基本數組實現這一點的方法是將行封裝在類中。例如:

class FileLine { 
    private String line; 

    public FileLine() {...} 

    public FileLine(String line) { 
     this.line = line; 
    } 

    public setLine(String line) { 
     this.line = line; 
    } 
} 

使那些陣列,迭代它與增強的for循環,並且代替設定數組字符串元素的值,設定FileLine實例的字符串成員的值。像這樣:

// Given an array of instantiated FileLines... 
for (FileLine fileLine : fileLines) { 
    fileLine.setLine(...); 
} 

更省力,您不必擔心試圖遍歷文件。