Java 8相当于Streams的getLineNumber() [英] Java 8 equivalent to getLineNumber() for Streams
问题描述
Java 8中的Streams是否等效于getLineNumber()?
Is there an equivalent to getLineNumber() for Streams in Java 8?
我想在文本文件中搜索一个单词并将行号作为整数返回。
这是我的搜索方法:
I want to search for a word in a textfile and return the line number as Integer. This is my search Method:
result = Files.lines(Paths.get(fileName))
.filter(w -> w.contains(word))
.collect(Collectors.<String> toList());
推荐答案
我认为没有,因为流是不是为了提供对元素的访问,而不是像集合一样。
I don't think there is, because streams are not designed to provide an access to their elements, not like collections.
一种解决方法是读取列表中的文件,然后使用 IntStream
生成相应的索引,然后您可以从中应用过滤器:
One workaround would be to read the file in the list, then use an IntStream
to generate the corresponding indices, from which you can then apply your filter:
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 parallel
List<Integer> lineNumbers =
IntStream.range(0, list.size())
.filter(i -> list.get(i).contains(word))
.mapToObj(i -> i + 1)
.collect(toList());
因为冒风险将整个文件的内容加载到列表中可能会保留,所以有点矫枉过正之后只有几个元素。如果它不满足你,你可以写好for循环,它的代码不多。
It's a bit overkill as you take the risk to load the entire file's content into a list to maybe keep only a few elements after. If it doesn't satisfy you, you can write the good for loop, it's not much code.
也许你可能对这个问题感兴趣使用带有lambda的JDK8压缩流(java.util.stream.Streams.zip )。例如,使用 proton-pack 库:
Maybe you can be interested in this question Zipping streams using JDK8 with lambda (java.util.stream.Streams.zip). For example, using the proton-pack library:
List<Long> lineNumbers =
StreamUtils.zipWithIndex(Files.lines(Paths.get("file")))
.filter(in -> in.getValue().contains(word))
.map(in -> in.getIndex() + 1)
.collect(toList());
或者您可以从a创建 LineNumberReader
BufferedReader
,然后调用 lines()
并将每一行映射到文件中的行号。请注意,如果管道并行运行,此方法将失败,因此我不推荐它。
Or you can create a LineNumberReader
from a BufferedReader
, then call lines()
and map each line to its line number in the file. Note that this approach will fail if the pipeline is run in parallel, so I don't recommend it.
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());
这篇关于Java 8相当于Streams的getLineNumber()的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!