有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

在Java8中,从字符串中删除某些重复单词的优雅方法是什么

在Java 8中,从字符串中删除某些特定的重复单词的优雅方式是什么

有一个不重复的单词列表:[cat,mat]

给一根绳子:“一只猫坐在垫子上,戴着一顶帽子一只猫坐在垫子上,戴着一顶帽子”

结果应该是:“一只猫坐在垫子上戴着帽子,一只猫坐在垫子上戴着帽子”

注意:这是我们要保存的第一个实例


共 (3) 个答案

  1. # 1 楼答案

    您可以这样做:

    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


    作为对一些评论的回应,担心词语的顺序没有得到保留:

    ^{}的文档没有明确说明返回的流是有序的,但它确实提到:

    Returns a sequential Stream with the specified array as its source.

    数组对它有一个已定义的顺序,也就是说,它是有序的,所以我认为读取它是安全的,因为返回的流也是有序的

    获取有序流的另一种方法是使用Arrays.spliterator并将结果包装到流中(因为拆分器将通过documentation报告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();
    
  2. # 2 楼答案

    更新Here一个使用正向前瞻的示例,删除的单词是第一个出现的

    \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 );
    
  3. # 3 楼答案

    寻求比其他解决方案更基本的解决方案

    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()上的'limit'参数,您可以用以下内容替换上面的循环:

        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,}", " ");