Java 8过滤字符串

8

我有一个从字符串中删除部分字符的方法。使用Java 8,有没有更好的方法来实现这个操作?

public String filter(String test) {
    StringBuilder builder = new StringBuilder();
    for (int i = 0; i < test.length(); i++) {
        if (MYCOLLECTION.contains(test.charAt(i))) {
            builder .append(test.charAt(i));
        }
    }
    return builder .toString();
}
4个回答

3
这个怎么样?
Set<Character> filter = new HashSet<>(Arrays.asList('a','b','c'));
String filtered = "abcdefga".chars ()
                            .filter(i -> filter.contains((char) i))
                            .mapToObj(i -> "" + (char) i)
                            .collect(Collectors.joining());
System.out.println (filtered);

输出:

abca

注意: filter 的作用与您的 MYCOLLECTION 相同 - 我只是给它起了一个更有意义的名称,并使用了一个 Set 以提高 contains 的性能。
如果有一个 CharStream(即原始字符流),那么代码可以更加简洁,这样我就不必使用 IntStream

不知道你在尝试什么,这对我可行 https://ideone.com/GpgXpG - Michael
@Michael 我在Eclipse上使用你的代码时出现了Cannot infer type argument(s) for <U> mapToObj(IntFunction<? extends U>)错误。Java 8. - Eran
2
@Michael 你的变体在 ideone 上运行正常,因为 Character.toString(int) 已经在 Java 11 中添加。 - Holger
1
这个流变量对我来说并不比原始循环代码更好,而且肯定不会提高性能。 - Holger
2
@Naman 喜欢 filtered = inputString.replaceAll( filter.stream().map(Object::toString).collect(Collectors.joining("", "[^", "]")),"") 吗?它只适用于字符没有特殊含义的情况(否则需要额外的努力)。除非过滤字符是常量,否则没有什么能比简单的循环解决方案更好了... - Holger
显示剩余3条评论

1
如果您愿意使用第三方库,以下内容适用于Java 8和Eclipse Collections
CharSet set = CharSets.immutable.with('a', 'b', 'c');
CharAdapter chars = Strings.asChars("a1b2c3");
String string = chars.select(set::contains).toString();
Assert.assertEquals("abc", string);

Eclipse Collections支持原始集合,因此无需将char值作为Character实例进行包装。
您还可以使用名为reject的方法来排除而不是包含字符,该方法是select的反义词。
CharSet set = CharSets.immutable.with('a', 'b', 'c');
CharAdapter chars = Strings.asChars("a1b2c3");
String include = chars.select(set::contains).toString();
String exclude = chars.reject(set::contains).toString();
Assert.assertEquals("abc", include);
Assert.assertEquals("123", exclude);

注意:我是 Eclipse Collections 的提交者。

0

这里有一个使用正则表达式的非常简单的方法

var string = "what ever you want!";

final var charSet = "".,;:!@";

final var stringResult = string.replaceAll("[" + charSet + "]", "");

>> ""what ever you want"

0
“更好”是以什么标准来衡量的?以下是我的写法。
final String filtered = test.chars()
    .mapToObj(chr -> (char) chr)    // IntStream -> Stream<Character>
    .filter(MYCOLLECTION::contains)
    .collect(
        Collector.of(StringBuilder::new, StringBuilder::append, StringBuilder::append, StringBuilder::toString)
    );

收集器有点丑,我可能会将其提取到自己的方法中
private static Collector<Character, StringBuilder, String> characterCollector()
{
    return Collector.of(
        StringBuilder::new,
        StringBuilder::append,
        StringBuilder::append,
        StringBuilder::toString
    );
}

然后调用这个函数代替原来的函数

.collect(characterCollector())

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接