С давних времён веду в своей программе на Java перечисления в таком стиле:
public static final int NONE = 0, ACTION_ID = 1, ADAPTER_NAME = 2, ATTR_ACCESS_TYPE = 3;
public static final int ATTR_GROUP_ID = 4, ATTR_ID = 5, ATTR_ID_LIST = 6, ATTR_SCHEMA_ID = 7;
public static final int ATTR_TYPE_DEF_ID = 8, ATTR_TYPE_ID = 9, COMPONENT_ID = 10, CONNECTION_TYPE = 11;
public static final int COST = 12, DATA = 13, DEF_VALUE = 14, DESCRIPTION = 15;
public static final int FLAGS = 16, GRANTS = 17, HEIGHT = 18, ID = 19;
public static final int KIND = 20, LISTENER_ID = 21, LIST_VALUE_ID = 22, MASK = 23;
public static final int NAME = 24, OBJECT_ID = 25, OBJECT_TYPE_ID = 26, OPTIONS = 27;
...
Ну и так далее. Поскольку в Java до версии 1.5 не было явных перечислений, их приходится эмулировать int'овыми константами.
И я предпочитаю данные константы записывать по четыре на строчку, причём со сквозной сортировкой по имени (уверен, пуристы оценят :).
Самое сложное в такой организации перечисления - добавить новое значение (к примеру, DATE), точнее вставить его в нужное место в середине последовательности (с перестановкой хвостов на следующую строчку и перенумерацией всего стоящего после).
Всё хорошо, пока таких констант мало, но когда их число подходит к сотне, задача несколько усложняется. Тратить несколько минут на перенумерацию уже лень :)
Совет перейти на Java 1.5+ с её перечислениями (перенумерация не требуется) отвергнем сразу - требуется обратная совместимость.
Люди прагматичные скажут - пиши новую константу в конец, функциональность не пострадает. Не послушаем и их скучных советов - у вышеописанной структуры есть свои преимущества.
Если не хочется делать лишнюю работу руками - думаем головой. Первое, что приходит в голову - разбить при помощи FAR'овского клавиатурного шаблона (keyboard template) каждую строчку на 4, скопировать полученное в Excel, создать там арифметическую прогрессию, скопировать полученное обратно и при помощи ещё одного клавиатурного шаблона слить всё воедино. Многовато шагов получается, да и Эксель придётся запускать - решение для не очень ленивых.
Всё-таки хочется решить задачу полностью при помощи клавиатурных шаблонов. Но как? Если первую операцию (сделать так, чтобы после вставки нового значения на каждой строчке по-прежнему было по 4 константы) реализовать несложно - выделить в конце строчки хвост начиная с запятой и перенести его на следующую строчку - то как организовать перенумерацию? Ведь клавиатурный шаблон - это просто запись последовательного нажатия клавиш на клавиатуре, в нём нет переменных, нет памяти.
Стоп, это что-то напоминает. Строка текста, которую можно редактировать, и жёсткий набор простейших команд. Это же машина Тьюринга, пусть аналогия и неполная (у машины Тьюринга есть состояние, а у нас нет, но зато у нас есть буфер обмена, который можно использовать в качестве состояния).
Я сразу же вспомнил одну задачку на семинаре по теории алгоритмов, в процессе решения которой машине Тьюринга потребовалась простейшая память в виде единственного числа, которую машина тащила за собой по ленте, перепрыгивая через другие числа.
Попробуем применить подобный подход (с движущейся за курсором памятью) и в нашем случае.
Итак, мы вставили в список значение DATE:
public static final int COST = 12, DATA = 13, DATE = XX, DEF_VALUE = 14, DESCRIPTION = 15;
public static final int FLAGS = 16, GRANTS = 17, HEIGHT = 18, ID = 19;
public static final int KIND = 20, LISTENER_ID = 21, LIST_VALUE_ID = 22, MASK = 23;
public static final int NAME = 24, OBJECT_ID = 25, OBJECT_TYPE_ID = 26, OPTIONS = 27;
...
Приводим его к четырёхконстантной форме при помощи клавиатурных шаблонов:
...
public static final int COST = 12, DATA = 13, DATE = XX, DEF_VALUE = 14;
public static final int DESCRIPTION = 15, FLAGS = 16, GRANTS = 17, HEIGHT = 18;
public static final int ID = 19, KIND = 20, LISTENER_ID = 21, LIST_VALUE_ID = 22;
public static final int MASK = 23, NAME = 24, OBJECT_ID = 25, OBJECT_TYPE_ID = 26;
public static final int OPTIONS = 27, ...
Можно посмотреть на видео, как это делается:
Click to view
Наша вновь вставленная константа имеет фиктивное значение XX - впоследствие мы заменим его на более подобающее 14.
Мысль следующая: начнём перенумерацию с единиц (к счастью, мы вставили значение в область двузначных чисел - с ними и будем работать), а потом перейдём к десяткам. Единицы должны циклически проходить значения от 0 до 9 (при переходе через 0 десятки увеличиваются на 1, но про это пока забываем).
Формируем циклическую последовательность для единиц, начиная с цифры, которую хотим присвоить первой константе:
...
2345678901
public static final int COST = 12, DATA = 13, DATE = XX, DEF_VALUE = 14;
public static final int DESCRIPTION = 15, FLAGS = 16, GRANTS = 17, HEIGHT = 18;
public static final int ID = 19, KIND = 20, LISTENER_ID = 21, LIST_VALUE_ID = 22;
public static final int MASK = 23, NAME = 24, OBJECT_ID = 25, OBJECT_TYPE_ID = 26;
public static final int OPTIONS = 27, ...
А теперь делаем такой шаблон: вырезаем первую цифру из "памяти" и тут же вставляем её в конец (получится 3456789012), а потом находим значение первой константы и ставим ей в разряд единиц цифру из буфера обмена. Аналогично делаем ещё три раза, ища последовательно более дальние константы на той же строчке. А потом берём нашу "память", вырезаем всей строкой и переносим на строку ниже. И всё - шаблон готов. Он делает перенумерацию единиц на отдельно взятой строке, чтобы получилось вот так:
...
public static final int COST = 12, DATA = 13, DATE = X4, DEF_VALUE = 15;
6789012345
public static final int DESCRIPTION = 15, FLAGS = 16, GRANTS = 17, HEIGHT = 18;
public static final int ID = 19, KIND = 20, LISTENER_ID = 21, LIST_VALUE_ID = 22;
public static final int MASK = 23, NAME = 24, OBJECT_ID = 25, OBJECT_TYPE_ID = 26;
public static final int OPTIONS = 27, ...
Назначаем шаблон на желаемую клавишу - и проходимся по всем строкам - с единицами задача решена.
Видео:
Click to view
Теперь надо подумать, что делать с десятками (заметьте - теперь у нас после 19 следует 10, а не положенное 20). Для последовательно идущих чисел цифра десятков меняется каждые 10 чисел - немного модифицируем нашу "память", повторив цифру десятков по десять раз:
...
1111111122222222223333333333
public static final int COST = 12, DATA = 13, DATE = X4, DEF_VALUE = 15;
public static final int DESCRIPTION = 16, FLAGS = 17, GRANTS = 18, HEIGHT = 19;
public static final int ID = 10, KIND = 21, LISTENER_ID = 22, LIST_VALUE_ID = 23;
public static final int MASK = 24, NAME = 25, OBJECT_ID = 26, OBJECT_TYPE_ID = 27;
public static final int OPTIONS = 28, ...
Заметьте, шаблон используется почти тот же (только он должен пройти не до единиц, а до десятков) - просто на вход ему подаётся другая информация. После первой итерации получается следующее:
...
public static final int COST = 12, DATA = 13, DATE = 14, DEF_VALUE = 15;
1111222222222233333333331111
public static final int DESCRIPTION = 16, FLAGS = 17, GRANTS = 18, HEIGHT = 19;
public static final int ID = 10, KIND = 21, LISTENER_ID = 22, LIST_VALUE_ID = 23;
public static final int MASK = 24, NAME = 25, OBJECT_ID = 26, OBJECT_TYPE_ID = 27;
public static final int OPTIONS = 28, ...
Повторяем для оставшихся строчек - и вуаля. На самом деле, всё делается достаточно весьма быстро - за пару минут.
Видео:
Click to view