Несколько ключей и значений - PullRequest
1 голос
/ 09 марта 2012

Я немного застрял в проекте .. По сути, я получаю каталог для сканирования файлов, который проходит определенные фильтры.

Командные файлы содержат строки с инструкциями по фильтрации (имя фильтра хранится в файле enum). как это например: Суффикс% TXT Exec% ДА

если это все, он вернет все файлы, оканчивающиеся на txt (расширение), и будет выполнимым. пока проблем нет.

проблема начинается с такой строки: суффикс% txt exec% YES (в той же строке) в этом случае должен возвращать все файлы, оканчивающиеся на txt ИЛИ исполняемый файл ..

Я разбиваю строку с помощью String.split ("%") и помещаю ее в карту с ключом и значением, затем перебираю каждый ключ и проверяю, какой это фильтр в перечислении, и выполняю проверку желания .

Я как бы застрял на том, как это определить, когда у меня более 1 фильтра на строку. Я попытался сделать HashMap с 1-м фильтром в качестве ключа, и значение представляет собой список, который содержит все остальные (используя split ("") для разбиения фильтров .. Я не могу полагаться на ключи, находящиеся на четных или нечетных индексах, потому что у фильтра может быть еще один% NOT в конце его (суффикс% txt% NOT), который вернет все файлы, которые не заканчиваются на txt. ..

Любая помощь будет принята с благодарностью! Спасибо!

1 Ответ

2 голосов
/ 09 марта 2012

Как насчет этого: создайте интерфейс Filter и напишите функцию, которая анализирует файл в одноместный фильтр на основе содержимого файла. У вас будет что-то вроде:

interface Filter {
  boolean passesFilter(File file);
}

class SuffixFilter implements Filter {
  SuffixFilter(String suffix) { ... }
  public boolean passesFilter(File file) {
    // return true if file has the appropriate suffix
  }
}

class ExecutableFilter implements Filter {
  ...  // filter that returns true if the file is executable
}

// now for the interesting part ...
class NegationFilter implements Filter {
  private final Filter subfilter;
  NegationFilter(Filter subfilter) {
    this.subfilter = subfilter;
  }

  public boolean passesFilter(File file) {
    return !subfilter.passesFilter(file);
  }
}

class AndFilter implements Filter {
  private final Collection<Filter> subfilters;
  AndFilter(Collection<Filter> subfilters) {
    this.subfilters = subfilters;
  }

  public boolean passesFilter(File file) {
    for (Filter subfilter : subfilters) {
      if (!subfilter.passesFilter(file)) {
        return false;
      }
    }
    return true;
  }
}

class OrFilter implements Filter {
  private final Collection<Filter> subfilters;
  OrFilter(Collection<Filter> subfilters) {
    this.subfilters = subfilters;
  }

  public boolean passesFilter(File file) {
    for (Filter subfilter : subfilters) {
      if (subfilter.passesFilter(file)) {
        return true;
      }
    }
    return false;
  }
}

Имея это в виду, вам просто нужно создать все базовые фильтры, а затем смежные элементы в одной строке объединятся OrFilter, а фильтры в отдельных строках (или отфильтрованы или нет) получат AndFilter ed. все вместе. Вот эскиз:

Filter readAndFilter(Iterable<String> fileLines) {
  List<Filter> subfilters = new ArrayList<Filter>();
  for (String line : fileLines) {
    subfilters.add(readOrFilter(line));
  }
  return new AndFilter(subfilters);
}

Filter readOrFilter(String fileLine) {
  List<Filter> subfilters = new ArrayList<Filter>();
  for (String oneFilter : fileLine.split(" ")) {
    Filter filter = buildOneFilter(oneFilter);
    subfilters.add(filter);
  }
  return new OrFilter(subfilters);
}

Filter buildOneFilter(String oneFilterClause) {
  // parse as you were doing before
}

Вы бы назвали readAndFilter в строках, считанных из вашего файла, и вы всегда получаете один Filter, в который вы можете передавать файлы, и он сообщит вам, проходят ли они фильтр. (Примечание: если вы хотите, вы можете использовать специальные методы my readAndFilter и readOrFilter, чтобы проверить, имеет ли список, который они возвращают, длину 1, и если это так, просто вернуть один фильтр, а не And или Or одного элемента. Это не влияет на корректность, но это может сделать отладочные результаты немного легче для чтения.)

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