Удалить символ из каждого элемента списка в JAVA - PullRequest
1 голос
/ 27 февраля 2020

У меня есть такая строка "-FOREST&-JUNGLE&DESERT"
Эта строка разбита на слова в списке, например, так: [-FOREST, -JUNGLE ,DESERT]
List<String> pattern = Arrays.asList(s.split("\\s*&\\s*"));

Каждое слово со знаком минус на начало должно быть в одном новом списке, а каждое слово без в другом, например, так:

List<String> allowedtags = pattern
                            .stream()
                            .filter(name -> !name.startsWith("-"))
                            .collect(Collectors.toList());

List<String> unwantedtags = pattern
                            .stream()
                            .filter(name -> name.startsWith("-"))
                            .collect(Collectors.toList());

Моя проблема в том, что мой unwantedtags сохраняет слова с минусом в начале, но для всех моих операций Мне нужно избавиться от этого. Если я сделаю приведенный ниже пример, он не будет работать, если «FOREST» находится в taglist, поскольку мой unwantedtags содержит «-FOREST».

if (taglist.stream().anyMatch(unwantedtags::contains)) {
                        return !IsWhitelist;
                        }

Так как я могу исправить свой список нежелательных тегов? Может быть в java 8 потоковых API? Более того, у меня есть ощущение, что, с одной стороны, до этого момента он работал нормально, но, с другой стороны, у меня возникает ощущение, что это большой код для получения всего двух списков. Можно ли его оптимизировать?

Ответы [ 3 ]

3 голосов
/ 27 февраля 2020

Вы можете сопоставить каждый элемент, чтобы убрать начальный знак минуса после его обнаружения:

List<String> unwantedtags = pattern
                            .stream()
                            .filter(name -> name.startsWith("-"))
                            .map(name -> name.substring(1))
                            .collect(Collectors.toList());

Код можно сделать более эффективным путем явного создания и заполнения списков. Затем вы можете обработать pattern за один проход вместо двух:

List<String> allowedtags = new ArrayList();
List<String> unwantedtags = new ArrayList();
pattern.stream()
       .forEach(name -> {
                if (name.startsWith("-")) unwantedtags.add(name.substring(1));
                else allowedtags.add(name);
            }
        );
2 голосов
/ 27 февраля 2020

Вам не хватает ни одной операции. С оператором map () вы можете взять входную строку и изменить ее.

List<String> unwantedtags = pattern
                .stream()
                .filter(name -> name.startsWith("-"))
                .map(name -> name.substring(1))
                .collect(Collectors.toList());
0 голосов
/ 27 февраля 2020

Вы можете использовать groupingBy, чтобы разделить эту коллекцию (на name.startsWith("-")):

Map<Boolean, List<String>> collect = pattern.stream()
        .collect(Collectors.groupingBy(name -> name.startsWith("-")));

Тогда у вас есть:

{false=[DESERT], true=[-FOREST, -JUNGLE]}

После этого вы можете выполнить дальнейшую обработку ( с unwantedtags):

List<String> unwantedtags = collect
        .getOrDefault(true, List.of()).stream()
        .map(name -> name.substring(1))
        .collect(Collectors.toList());

Или вы можете сделать это в одном потоке, но это может выглядеть сложнее.

Map<Boolean, List<String>> collectWithMap = pattern.stream()
        .collect(Collectors.groupingBy(name -> name.startsWith("-"),
                Collectors.mapping(name -> name.startsWith("-") ? name.substring(1) : name, 
                        Collectors.toList())));

результат:

{false=[DESERT], true=[FOREST, JUNGLE]}
...