Другими словами, старайтесь не выполнять всю логику в вашем парсере.Разделите логику, чтобы синтаксический анализатор просто обнаруживал структуру, а затем строил объекты, чтобы помочь вам обеспечить соблюдение правил.Синтаксический анализатор может легко обнаружить аргументы и использовать их для создания списка.
Если вы создаете класс, содержащий ваши аргументы, например:
public class Arg {
public int number;
public String value;
public Arg(int num, String val) {
this.number = num;
this.value = val;
}
@Override
public String toString()
{
return "[Arg num=" + number + ", value=" + value + "]";
}
}
, то вы можете поместить их в простоеХеш-таблица.
Map<Arg> argList = new HashMap<Arg>();
Затем вы можете сделать логику, используя, может быть, счетчик и содержит () или indexOf () и т. Д.
Наличие класса Arg также упрощает сортировку.Если вам нужен список, отсортированный по позиции аргумента, вы создаете для этого компаратор.
import java.util.Comparator;
public class ArgNumComparator implements Comparator<Arg> {
public int compare(Arg o1, Arg o2) {
if (o1.number == o2.number) {
return 0;
}
return o1.number < o2.number ? -1 : 1 ;
}
}
Сортировка по значению аргумента еще проще, поскольку вы можете повторно использовать сравниваемое () значение Strings.
import java.util.Comparator;
public class ArgValComparator implements Comparator<Arg>
{
public int compare(Arg o1, Arg o2)
{
return o1.value.compareTo(o2.value);
}
}
Затем, чтобы выполнить сортировку, используйте Collections.sort () примерно так:
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
public class ArgList{
public static void main(String[] args) {
//args1=msg args2=flow args3=content args4=depth args6=within ==> args5=content
List<Arg> l = new ArrayList<Arg>();
// hard-coded example instead of more likely parsing
l.add(new Arg(1, "msg"));
l.add(new Arg(2, "flow"));
l.add(new Arg(3, "content"));
l.add(new Arg(4, "depth"));
l.add(new Arg(5, "flow"));
l.add(new Arg(6, "within"));
Collections.sort(l, new ArgValComparator()); // take your pick of comparators
System.out.println(l); // uses the toString() of Arg.
}
}
EDIT: добавлен метод toString () в Arg и изменен список вПример с двумя аргументами «потока».
Запуск с новым кодом toString выводит на консоль следующее:
[[Arg num = 3, value = content], [Arg num = 4, значение = глубина], [Arg num = 2, значение = поток], [Arg num = 5, значение = поток], [Arg num = 1, значение = msg], [Arg num = 6, значение= в пределах]]
Как видите, два аргумента со значением = "поток" теперь рядом друг с другом.Чтобы обнаружить несколько аргументов, где значение = «поток», можно сделать так:
boolean flowFound = false;
for (Arg arg : l){
if (arg.value.compareToIgnoreCase("flow") == 0) {
if (flowFound) //already found one? {
// action when second "flow" exists
System.out.println("2nd flow found");
}
else {
flowFound = true; // found the first "flow"
}
}
}