Предположим, вы хотите получить список директории. Объект File может выдать его двумя способами. Если вы вызовите list( ) без аргументов, вы получите полный список, содержащийся в объекте File. Однако если вы хотите ограничить список, например, если вы хотите получить все файлы с расширением .java, то вам нужно использовать “фильтр директории”, который является классом, который определяет, как использовать объект File для отображения.
Здесь приведен код примера. Обратите внимание, что результат без труда будет храниться (в алфавитном порядке) при использовании метода java.utils.Array.sort( ) и AlphabeticComparator, определенного в Главе 9:
//: c11:DirList.java
// Отображение списка директории.
import java.io.*; import java.util.*; import com.bruceeckel.util.*;
public class DirList { public static void main(String[] args) { File path = new File("."); String[] list; if(args.length == 0) list = path.list(); else list = path.list(new DirFilter(args[0])); Arrays.sort(list, new AlphabeticComparator()); for(int i = 0; i < list.length; i++) System.out.println(list[i]); } }
class DirFilter implements FilenameFilter { String afn; DirFilter(String afn) { this.afn = afn; } public boolean accept(File dir, String name) { // Получение информации о пути:
String f = new File(name).getName(); return f.indexOf(afn) != -1; } } ///:~
Класс DirFilter “реализует” interface FilenameFilter. Полезно посмотреть, насколько прост FilenameFilter interface:
public interface FilenameFilter { boolean accept(File dir, String name); }
Это говорит о том, что этот тип объекта должен обеспечивать метод, называемый accept( ). Главная цель создания этого класса заключается в обеспечении метода accept( ) для метода list( ), так как list( ) может выполнять “обратный вызов” accept( ) для определения, какое имя файла должно включаться в список. Эта техника часто называется обратным вызовом или иногда функтором (то есть, DirFilter - это функтор, потому что он выполняет работу по поддержанию метода) или Командой Заполнения. Потому что list( ) принимает объект FilenameFilter в качестве аргумента, это означает, что вы можете передать объект любого класса, который реализует FilenameFilter для выбора (даже во время выполнения) поведения метода list( ). Назначение обратного вызова заключается в обеспечении гибкого поведения кода.