我不认为这是因为,流并非旨在提供对元素的访问,而不是像集合那样。
一种解决方法是读取列表中的文件,然后使用
IntStream生成相应的索引,然后可以从中应用过滤器:
List<String> list = Files.readAllLines(Paths.get("file"));//readAllLines current implementation returns a RandomAccessList so //using get will not have a big performance impact.//The pipeline can be safely run in parallelList<Integer> lineNumbers = IntStream.range(0, list.size()) .filter(i -> list.get(i).contains(word)) .mapToObj(i -> i + 1) .collect(toList());由于您冒着将整个文件的内容加载到列表中,可能只保留一些元素的风险,所以这有点过头了。如果您不满意,可以编写good for循环,这不是很多代码。
也许您可能对此问题感兴趣,使用带有lambda的JDK8压缩流(java.util.stream.Streams.zip)。例如,使用质子包装库:
List<Long> lineNumbers = StreamUtils.zipWithIndex(Files.lines(Paths.get("file"))) .filter(in -> in.getValue().contains(word)) .map(in -> in.getIndex() + 1) .collect(toList());或者,您可以
LineNumberReader从创建一个
BufferedReader,然后调用
lines()并将每一行映射到文件中的行号。请注意,如果管道并行运行,则此方法将
失败 ,因此,我不建议这样做。
LineNumberReader numberRdr = new LineNumberReader(Files.newBufferedReader(Paths.get("file")));List<Integer> linesNumbers = numberRdr.lines() .filter(w -> w.contains(word)) .map(w -> numberRdr.getLineNumber()) .collect(toList());


