список фильтров Java-потока - PullRequest
0 голосов
/ 19 февраля 2019

Допустим, у меня есть список строк, и я хочу отфильтровать их по списку строк.Для списка, состоящего из: «abcd», «xcfg», «dfbf»

, я бы уточнил список фильтрующих строк: «a», «b» и после чего-то вроде фильтра (i-> i.contains (filterStrings) Я хотел бы получить список "abcd", "dfbf" и список строк фильтрации: "c", "f" Я хотел бы получить список "xcfg" и "dfbf".

List<String> filteredStrings = filteredStrings.stream()
            .filter(i -> i.contains("c") || i.contains("f")) //i want to pass a list of filters here
            .collect(Collectors.toList());

Есть ли другой способ сделать это вместо расширения тела лямбда-выражения и написания функции с флагом, который будет проверять каждый фильтр?

Ответы [ 4 ]

0 голосов
/ 19 февраля 2019

Вы можете использовать Pattern:

static final Pattern pattern = Pattern.compile("c|f");

и затем проверить, соответствует ли строка указанному шаблону.

List<String> strings = filteredStrings.stream()
    .filter(s -> pattern.matcher(s).find())
    .collect(Collectors.toList());

То, что pattern, конечно, может быть вычислено с помощьюзаданный вход:

public static Pattern compute(String... words) {
    StringBuilder pattern = new StringBuilder();
    for(int i = words.length - 1; i >= 0; i++) {
       pattern.append(words[i]);
       if(i != 0) {
           pattern.append('|');
       }
    }
    return Pattern.compile(pattern);
}

Который затем можно было бы назвать так:

Pattern patten = compute("some", "words", "hello", "world");

Что привело бы к регулярному выражению:

some|words|hello|world
0 голосов
/ 19 февраля 2019

Вы можете изменить contains с помощью простого регулярного выражения:

.filter(i -> i.matches(".*[cf].*")) // to check just one character

или:

.filter(i -> i.matches(".*(c|f).*")) // or if you have a words
0 голосов
/ 19 февраля 2019

Вместо этого вы должны выполнить anyMatch над списком для совпадения с:

List<String> input = Arrays.asList("abcd", "xcfg", "dfbf"); // your input list
Set<String> match = new HashSet<>(Arrays.asList("c", "f")); // to match from
List<String> filteredStrings = input.stream()
        .filter(o -> match.stream().anyMatch(o::contains))
        .collect(Collectors.toList());
0 голосов
/ 19 февраля 2019

Фильтр может быть представлен как Predicate.В вашем случае это Predicate<String>.Итак, список фильтров может быть сохранен в List<Predicate<String>>.

Теперь, если вы хотите применить такой список к каждому элементу вашего Stream:

List<String> filteredStrings = input.stream()
                                    .filter(i -> filterList.stream().anyMatch(f -> f.test(i))) 
                                    .collect(Collectors.toList());

Toзавершите пример:

List<String> input = new ArrayList<>(Arrays.asList ("abcd", "xcfg", "dfbf","erk"));
List<Predicate<String>> filterList = new ArrayList<>();
filterList.add (i -> i.contains("c"));
filterList.add (i -> i.contains("f"));
List<String> filteredStrings = input.stream()
                                    .filter(i -> filterList.stream().anyMatch(f -> f.test(i))) 
                                    .collect(Collectors.toList());
System.out.println (filteredStrings);

Вывод:

[abcd, xcfg, dfbf]
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...