在Java8中,如何优雅地从字符串中删除某些特定的重复单词,以便:
有一个非重复单词列表:cat,mat
给出一条绳子:“一只猫坐在垫子上,戴着一顶帽子--坐在垫上,戴着帽子。”
结果应该是:“一只猫坐在垫子上,戴着一顶帽子。”
注意:是我们想要保留的第一次出现。
发布于 2018-02-09 09:55:29
你可以这样做:
String input = "A cat sat on a mat and wore a hat A cat sat on a mat and wore a hat";
Set<String> toFilter = Set.of("cat", "mat"); // Java 9's set.of, for brievety.
Set<String> seen = new HashSet<>();
String result = Arrays.stream(input.split(" "))
.filter(s -> !toFilter.contains(s) || seen.add(s))
.collect(Collectors.joining(" "));
System.out.println(result); // A cat sat on a mat and wore a hat A sat on a and wore a hat
这利用了这样一个事实:如果单词已经在集合中,seen.add
将返回false。
作为对一些评论的回应,担心未予保留的词语的顺序:
Arrays.stream
的文档并没有明确指出返回的流是有序的,但它确实提到了:
返回以指定数组为源的顺序流。
数组对它有一个定义的排序,也就是说,它是有序的,所以我要说,读取它是安全的,因为返回的流也是有序的。
获得有序流的另一种方法是使用Arrays.spliterator
并自己将结果包装在流中(因为分配器将按文档报告ORDERED
):
StreamSupport.stream(Arrays.spliterator(input.split(" ")), false)
但目前,Arrays.stream
也这样做了。
否则,总是会出现for-循环回退:
String[] tokens = input.split(" ");
StringJoiner joiner = new StringJoiner(" ");
for(String s : tokens) {
if(!toFilter.contains(s) || seen.add(s)) {
joiner.add(s);
}
}
String result = joiner.toString();
发布于 2018-02-09 09:56:27
使用正前瞻更新的这里示例,删除的单词是要发生的第一次
\b(cat|mat)\b(?=.*\b\1\b)
在爪哇
String input = "A cat sat on a mat and wore a hat A cat sat on a mat and wore a hat";
input = input.replaceAll("\\b(cat|mat)\\b(?=.*\\b\\1\\b)", "");
System.out.println( input );
发布于 2018-02-09 10:52:53
一个比其他解决方案更基本的解决方案;
String input = "A cat sat on a mat and wore a hat A cat sat on a mat and wore a hat";
String[] list = {"cat", "mat"};
for(String word : list){
int index = input.indexOf(word) + word.length();
input = input.substring(0, index) + input.substring(index).replace(word, "");
}
或者,通过使用String.split()
上的“极限”参数,您可以用以下方法替换上面的循环;
for(String word : list){
String[] split = input.split(word, 2);
input = split[0] + word + split[1].replace(word, "");
}
这两个输出都是A cat sat on a mat and wore a hat A sat on a and wore a hat
,但是如果您想要删除双空间,则可以在返回值以删除任何其他空格之前轻松调用input.replaceAll(" {2,}", " ");
。
https://stackoverflow.com/questions/48702999
复制相似问题