我拥有的:,我有一个文件,它是逐行读取的。这些行不在文件中计算。
我想要做的事情:,我想计数一条流中的每一行,并且只返回发生特定文本的数字。
到目前为止我所拥有的:
public static Integer findLineNums(String word)
throws IOException {
final Map<String, Integer> map = new HashMap<>();
final List<String> lines = Files.lines(Paths.get(PATH)).collect(Collectors.toList());
IntStream.rangeClosed(0, lines.size()-1).forEach(f -> map.put(lines.get(f), f+1));
return map.get(word);
}问:我如何只用一个流就可以做到这一点?
编辑的问题:我想做流中的每一件事,这也包括在列表中的积累。
最好的情况是:
Files.lines(Paths.get(PATH)).superAwesomeStreamFuncs().collect(Collectors.toList());编辑:在我的例子中,我只返回一个Integer,但是我想得到类似于Integer列表的内容。
发布于 2015-04-30 14:01:39
这样做是可行的:
int[] i = new int[]{0}; // trick to make it final
List<Integer> hits = <your stream>
.map(s -> s.contains(word) ? ++i[0] : - ++i[0])
.filter(n -> n > 0)
.collect(Collectors.toList());这里的主要“技巧”是数组的使用,它的引用不会改变(即它是“有效的终结”,但它允许我们将它的(仅)元素作为计数器,它是以行方式递增的)。一个快速的过滤器扔出非火柴。
一些测试代码:
String word = "foo";
int[] i = new int[]{0};
List<Integer> hits = Stream.of("foo", "bar", "foobar")
.map(s -> s.contains(word) ? ++i[0] : - ++i[0])
.filter(n -> n > 0)
.collect(Collectors.toList());
System.out.println(hits);输出:
[1, 3]发布于 2015-04-30 13:30:02
下面的代码片段将创建一个包含单词的行的List<Integer>
String word = "foo";
List<Integer> matchedLines = new ArrayList<>();
final List<String> lines = Files.readAllLines(Paths.get("word_list.txt"));
IntStream.rangeClosed(0, lines.size() - 1).forEach(f -> {
if (lines.get(f).contains(word)) {
matchedLines.add(++f);
}
});
System.out.println("matchedLines = " + matchedLines);假设文件word_list.txt为
foo
bar
baz
foobar
barfoo输出是
matchedLines = [1, 4, 5]编辑以使用单个流解决它,创建一个自定义Consumer
public class MatchingLines {
static class MatchConsumer implements Consumer<String> {
private int count = 0;
private final List<Integer> matchedLines = new ArrayList<>();
private final String word;
MatchConsumer(String word) {
this.word = word;
}
@Override
public void accept(String line) {
count++;
if (line.contains(this.word)) {
matchedLines.add(count);
}
}
public List<Integer> getResult() {
return matchedLines;
}
}
public static void main(String[] args) throws IOException {
MatchConsumer matchConsumer = new MatchConsumer("foo");
Files.lines(Paths.get("word_list.txt")).forEach(matchConsumer);
System.out.println("matchedLines = " + matchConsumer.getResult());
}
}发布于 2015-04-30 14:25:41
此方法返回按文件中其编号映射的行。
public static Map<String, Integer> findLineNums(Path path, String word) throws IOException {
final Map<String, Integer> map = new HashMap<>();
int lineNumber = 0;
Pattern pattern = Pattern.compile("\\b" + word + "\\b");
try (BufferedReader reader = Files.newBufferedReader(path)) {
String line = null;
while ((line = reader.readLine()) != null) {
lineNumber++;
if (pattern.matcher(line).find()) {
map.put(line, lineNumber);
}
}
}
for (String line : map.keySet()) {
Integer lineIndex = map.get(line);
System.out.printf("%d %s\n", lineIndex, line);
}
return map;
}BufferedReader逐行读取文件,Files.lines流也是如此。
https://stackoverflow.com/questions/29968763
复制相似问题