如何在java 8流中进行条件操作以跳过下一个流操作?

sea*_*eal 2 java java-8 java-stream

在传统方式中,我已经编写了这个简单的java for循环

public String setString(String string) {  
StringBuilder stringBuilder = new StringBuilder();

    // This for loop I want to convert into stream. 
    for (char c : string.toCharArray()) {
       if (Character.isSpaceChar(c))
           stringBuilder.append(c);
       else if (isBangla(c))
           stringBuilder.append(get(c));
    }
    return stringBuilder.toString();
}

String get(int c) {
    return keyMap.getMap((char) c); // Map<Character, String> keyMap
}

boolean isBangla(int codePoint) {
    return ((codePoint >= BANGLA_CHAR_START && codePoint <= BANGLA_CHAR_END) &&
        (codePoint <= BANGLA_NUMBER_START || codePoint >= BANGLA_NUMBER_END)));
}
Run Code Online (Sandbox Code Playgroud)

我试过这样的事情.

String str = string.chars()
            .filter(i -> Character.isSpaceChar(i)) // if this is true need to add string 
            .filter(this::isBangla)
            .mapToObj(this::get)
            .collect(Collectors.joining());
Run Code Online (Sandbox Code Playgroud)

我想要做的是,如果第一个过滤器检测到它是一个spaceChar然后它将不会进行任何进一步的流处理,而是它跳转到collect.

那么我怎样才能实现这种if/else情况以跳过下一个流操作呢?提前致谢.

Rea*_*tic 6

好吧,你可以使用这样的东西:

String str = string.chars()
           .filter( ch -> Character.isSpaceChar(ch) || isBangla(ch) )
           .mapToObj( ch -> isBangla(ch) ? get(ch) : Character.toString((char)ch))
           .collect(Collectors.joining());
Run Code Online (Sandbox Code Playgroud)

如您所见,此流检查isBangla两次.第一次是只留下流中的空格或孟加拉字符,第二次是为了知道要转换哪些字符.

因为流操作是独立的 - 每个流都不知道流之前发生了什么 - 当在传统循环中编写时,这样的操作可能更有效.更重要的是,当你在流中运行它时,你创建了许多小字符串,你必须将所有字符转换为字符串,而不仅仅是bangla字符串.

重要的是要注意你在这里没有"跳过"任何东西.在传统循环中,您可以跳过操作.但是在流中,跳过元素意味着它们不会出现在最终结果中.您在流中执行的操作是将这些元素保持不变(或者在这种情况下,从a更改char为a String),而不是跳过.

  • @seal当您将流转换为对象时,*all*字符将成为字符串对象,然后才会收集它们.`String`是不可变的,因此临时对象被*复制*到最终结果中.所以你创建了一个临时对象占用了一点内存,需要进行垃圾收集,当你使用`StringBuilder`时没有,因为你没有把它转换成`String`,但写了字符直接进入`StringBuilder`. (2认同)