Java 8 Streams 修改集合值
Java 8 Streams modify collection values
使用流API;过滤相关数据后,我想编辑正在收集的数据。这是到目前为止的代码:
String wordUp = word.substring(0,1).toUpperCase() + word.substring(1);
String wordDown = word.toLowerCase();
ArrayList<String> text = Files.lines(path)
.parallel() // Perform filtering in parallel
.filter(s -> s.contains(wordUp) || s.contains(wordDown) && Arrays.asList(s.split(" ")).contains(word))
.sequential()
.collect(Collectors.toCollection(ArrayList::new));
编辑下面的代码很糟糕,我正在努力避免它。(它也不能完全工作。它是在凌晨 4 点完成的,请原谅。)
for (int i = 0; i < text.size(); i++) {
String set = "";
List temp = Arrays.asList(text.get(i).split(" "));
int wordPos = temp.indexOf(word);
List<String> com1 = (wordPos >= limit) ? temp.subList(wordPos - limit, wordPos) : new ArrayList<String>();
List<String> com2 = (wordPos + limit < text.get(i).length() -1) ? temp.subList(wordPos + 1, wordPos + limit) : new ArrayList<String>();
for (String s: com1)
set += s + " ";
for (String s: com2)
set += s + " ";
text.set(i, set);
}
它在文本文件中寻找一个特定的词,一旦该行被过滤,我想每次只收集该行的一部分。正在搜索的关键字两侧的单词数。
例如:
keyword = "the"
limit = 1
它将找到:"Early in the morning a cow jumped over a fence."
然后应该 return: "in the morning"
*P.S。任何建议的速度改进都会被投票。
您应该考虑两项不同的任务。首先,将文件转换为单词列表:
List<String> words = Files.lines(path)
.flatMap(Pattern.compile(" ")::splitAsStream)
.collect(Collectors.toList());
这使用了您最初在 space 个字符处拆分的想法。这对于简单的任务可能就足够了,但是,您应该研究 the documentation of BreakIterator
以了解这种简单方法与真实、复杂的单词边界拆分之间的区别。
其次,如果您有一个单词列表,您的任务是找到您的 word
的匹配项,并将匹配项周围的项目序列转换为单个匹配项 String
,方法是使用单个 space 字符作为分隔符:
List<String> matches=IntStream.range(0, words.size())
// find matches
.filter(ix->words.get(ix).matches(word))
// create subLists around the matches
.mapToObj(ix->words.subList(Math.max(0, ix-1), Math.min(ix+2, words.size())))
// reconvert lists into phrases (join with a single space
.map(list->String.join(" ", list))
// collect into a list of matches; here, you can use a different
// terminal operation, like forEach(System.out::println), as well
.collect(Collectors.toList());
使用流API;过滤相关数据后,我想编辑正在收集的数据。这是到目前为止的代码:
String wordUp = word.substring(0,1).toUpperCase() + word.substring(1);
String wordDown = word.toLowerCase();
ArrayList<String> text = Files.lines(path)
.parallel() // Perform filtering in parallel
.filter(s -> s.contains(wordUp) || s.contains(wordDown) && Arrays.asList(s.split(" ")).contains(word))
.sequential()
.collect(Collectors.toCollection(ArrayList::new));
编辑下面的代码很糟糕,我正在努力避免它。(它也不能完全工作。它是在凌晨 4 点完成的,请原谅。)
for (int i = 0; i < text.size(); i++) {
String set = "";
List temp = Arrays.asList(text.get(i).split(" "));
int wordPos = temp.indexOf(word);
List<String> com1 = (wordPos >= limit) ? temp.subList(wordPos - limit, wordPos) : new ArrayList<String>();
List<String> com2 = (wordPos + limit < text.get(i).length() -1) ? temp.subList(wordPos + 1, wordPos + limit) : new ArrayList<String>();
for (String s: com1)
set += s + " ";
for (String s: com2)
set += s + " ";
text.set(i, set);
}
它在文本文件中寻找一个特定的词,一旦该行被过滤,我想每次只收集该行的一部分。正在搜索的关键字两侧的单词数。
例如:
keyword = "the"
limit = 1
它将找到:"Early in the morning a cow jumped over a fence."
然后应该 return: "in the morning"
*P.S。任何建议的速度改进都会被投票。
您应该考虑两项不同的任务。首先,将文件转换为单词列表:
List<String> words = Files.lines(path)
.flatMap(Pattern.compile(" ")::splitAsStream)
.collect(Collectors.toList());
这使用了您最初在 space 个字符处拆分的想法。这对于简单的任务可能就足够了,但是,您应该研究 the documentation of BreakIterator
以了解这种简单方法与真实、复杂的单词边界拆分之间的区别。
其次,如果您有一个单词列表,您的任务是找到您的 word
的匹配项,并将匹配项周围的项目序列转换为单个匹配项 String
,方法是使用单个 space 字符作为分隔符:
List<String> matches=IntStream.range(0, words.size())
// find matches
.filter(ix->words.get(ix).matches(word))
// create subLists around the matches
.mapToObj(ix->words.subList(Math.max(0, ix-1), Math.min(ix+2, words.size())))
// reconvert lists into phrases (join with a single space
.map(list->String.join(" ", list))
// collect into a list of matches; here, you can use a different
// terminal operation, like forEach(System.out::println), as well
.collect(Collectors.toList());