Рассмотрим пример. Заметьте, что полученный список без всяких дополнительных усилий сортируется (по алфавиту) с помощью метода j a va. u ti L. Array. sort() и объекта String.CASE_INSENSITIVE_ORDER:
//: io/DirList java
// Вывод списка каталогов с использованием регулярных выражений
// {Параметры- "D *\.java"}
import java.util regex.*.
import java io.*.
import java util *,
public class DirList {
public static void main(String[] args) { File path = new File(" "). StringC] list, if(args length == 0)
list = path listO.
else
list = path list(new DirFilter(args[0])); Arrays sortdist. String CASE_INSENSITIVE_ORDER). for(String dirltem list)
System.out.printin(dirltem).
class DirFiIter implements FilenameFilter { private Pattern pattern; public DirFilter(String regex) {
pattern = Pattern compile(regex);
}
public boolean accept(File dir. String name) { return pattern matcher(name) matchesO;
}
} /* Output DirectoryDemo java DirList java DirList2 java DirList3 java
Класс DirFilter реализует интерфейс FilenameFilter. Посмотрите, как просто выглядит этот интерфейс:
public interface FilenameFilter {
boolean accept(File dir. String name).
}
Это показывает, что данный тип объекта должен поддерживать метод с именем accept(), который вызывается методом list() с целью определения того, какие имена файлов должны включаться в выходной список, а какие нет. Перед нами один из примеров паттерна
Метод accept() получает объект File, представляющий собой каталог, в котором был найден данный файл, и строку с именем файла. Помните, что метод list() вызывает accept() для каждого файла, обнаруженного в каталоге, чтобы определить, какие из них следует включить в выходной список — в зависимости от возвращаемого значения accept() (значение типа boolean).
Метод accept() использует объект регулярного выражения matcher, чтобы посмотреть, соответствует ли имя файла выражению regex. Метод list() возвращает массив.
Безымянные внутренние классы
Описанный пример идеально подходит для демонстрации преимуществ внутренних классов (описанных в главе 10). Для начала создадим метод filter(), который возвращает ссылку на объект FilenameFilter:
// io/DirList java
II Использование безымянных внутренних классов
II {Параметры "D *\ java"}
import java util regex *,
import java io *.
import java util *,
public class DirList {
public static void main(String[] args) { File path = new FileC" ").
Stri ng[] list.
list = path listO.
else
list = path list(new Di rFi1ter(args[0])): Arrays.sort(1i st, Stri ng.CASE_INSENSITIVE_ORDER); for(String dirltem . list)
System out println(dirltem);
class DirFiIter implements FilenameFilter { private Pattern pattern, public Di rFilter(String regex) {
pattern = Pattern.compile(regex);
}
public boolean accept(File dir. String name) { return pattern.matcher(name).matchesО;
}
} /* Output. DirectoryDemo.java DirList.java DirList2.java Di rLi st3.java *///:-
Заметьте, что аргумент метода filter() должен быть неизменным (final). Это необходимо для того, чтобы внутренний класс смог получить к нему доступ даже за пределами области определения аргумента.
Несомненно, структура программы улучшилась хотя бы потому, что объект FilenameFilter теперь неразрывно связан с внешним классом DirList2. Впрочем, можно сделать следующий шаг и определить безымянный внутренний класс как аргумент метода list(), в результате чего программа станет еще более компактной:
//: io/Dirl_ist3.java
// Создание безымянного внутреннего класса "на месте".
// {Параметры: "D.*\.java"}
import java.util.regex.*;
import java.io.*;
import java.util.*;
public class DirList3 {
public static void main(final String[] args) { File path = new File(V); String[] list; if(args.length == 0)
list = path.listO;
else
list = path.list(new FilenameFilterО {
private Pattern pattern = Pattern.compile(args[0]); public boolean accept(File dir, String name) { return pattern.matcher(name).matches();
}
}):
Arrays.sort(1i st. Stri ng.CASE_INSENSITIVE_ORDER); for(String dirltem : list)
System out println(dirltem).
}
} /* Output. DirectoryDemo.java DirList java DirList2.java DirList3.java */// ~
На этот раз неизменным (final) объявлен аргумент метода main(), так как безымянный внутренний класс использует параметр командной строки (args[0]) напрямую.