Java 8相当于Streams的getLineNumber() [英] Java 8 equivalent to getLineNumber() for Streams

查看:127
本文介绍了Java 8相当于Streams的getLineNumber()的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆