Java 8 фильтрация строки - PullRequest
7 голосов
/ 16 января 2020

У меня есть метод для удаления некоторых символов из строки. Есть ли лучший способ сделать это, используя 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();
}

Ответы [ 3 ]

4 голосов
/ 16 января 2020

Как насчет этого:

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 (т.е. поток примитивов char s), поэтому мне не пришлось бы используйте IntStream.

1 голос
/ 17 января 2020

Если вы открыты для использования сторонней библиотеки, следующее будет работать с 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.

1 голос
/ 16 января 2020

"Лучше", чем метри c? Вот как я мог бы написать это

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())
...