【问题标题】:How to remove Digits and whitespaces from a Stream?如何从流中删除数字和空格?
【发布时间】:2019-05-14 09:47:26
【问题描述】:

我尝试将 args 转换为流。然后必须将流设为大写,从字符串(而不是整个字符串)中删除数字和空格。 创建流和大写成功,现在我被过滤器方法卡住了,我不明白为什么我的代码不起作用,也已经做了一些研究。

package A_11;

import java.util.Arrays;
import java.util.stream.Stream;

public class A_11_g {
    public static void main(String[] args){
        Stream<String> stream = Arrays.stream(args);
        stream.map(s -> s.toUpperCase()).filter(s -> Character.isDigit(s)).filter(e -> !e.isEmpty())
                .forEach(name -> System.out.print(name + " "));
    }
}

【问题讨论】:

  • 当您说过滤器时,您的意思是要从提供的字符串中删除数字和空格,还是要删除包含数字/空格的任何字符串?
  • 我想从流中删除数字和空格,我认为 filter 是用于此目的的正确方法
  • 您拥有的是Stream&lt;String&gt;,您想完全删除带有条件或字符的字符串吗?虽然您可能正在寻找 stream.map(String::toUpperCase) .filter(s -&gt; !StringUtils.isNumeric(s) || !s.isEmpty()) .forEach(name -&gt; System.out.print(name + " "));,而 StringUtils 来自 apache commons。
  • 是的,但是从流中删除包含数字/空格的字符串,或者从流的字符串中删除数字/空格? Filter 是第一个,只有满足提供的 Predicate 时才会接受过滤 Stream 中的每个元素。
  • @FrancisDrake 您可能应该 edit 您的问题以明确要求(换句话说,将评论回复合并到问题本身中)。

标签: java arrays filter java-stream


【解决方案1】:

filter() 生成一个新流,其中包含满足 Predicate(您提供的条件)的原始元素。 您需要的是 map() 函数,它在将给定函数应用于原始流的每个元素后生成一个新流。

下面的代码应该可以解决问题,底部有一些断言,您可以选择使用它在单元测试中进行验证。

Stream<String> stringStream = Stream.of("unfiltered", "withDigit123", " white space ");

List<String> filtered = stringStream.map(s -> s.toUpperCase())//Can be replaced with .map(String::toUpperCase) if you want, but did it this way to make it easier to understand for someone new to all this.
        .map(s -> s.replaceAll("[0-9]", ""))//Removes all digits
        .map(s -> s.replace(" ", ""))//Removes all whitespace
        .collect(Collectors.toList());//Returns the stream as a list you can use later, technically not what you asked for so you can change or remove this depending on what you want the output to be returned as.

//Assertions, optional.
assertTrue(filtered.contains("UNFILTERED"));
assertTrue(filtered.contains("WITHDIGIT"));
assertTrue(filtered.contains("WHITESPACE"));

【讨论】:

  • 当您了解replaceAll("[0-9]", "") 的作用时,您应该很容易意识到它只需要稍作更改,即replaceAll("[0-9 ]", ""),即可使其也删除空格字符。
【解决方案2】:

如果您真的想要使用流来实现,则需要在较低级别应用过滤逻辑 - 而不是字符串流,而是单个字符串中的字符流:

System.out.println(
    "abcd 123 efgh".chars()
        .map(Character::toUpperCase)
        .filter(c -> !Character.isDigit(c))
        .filter(c -> !Character.isSpaceChar(c))
        .mapToObj(c -> String.valueOf((char) c))
        .collect(Collectors.joining())
);

ABCDEFGH

(mapToObj 部分是为了避免不得不处理本来需要的自定义收集器,因为流是IntStream 而不是常规的对象流。)

如果需要,您可以将其包装到处理多个字符串的流中 - 然后,上述逻辑将在该流上的 map 操作中。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-11-18
    • 2021-09-04
    • 2017-05-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多