In other words, try not to execute all your logic in your parser. Separate the logic so that the parser simply detects the structure and then creates objects to help you apply the rules. The parser can easily detect arguments and use them to create a list.
If you create a class containing your arguments as follows:
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 + "]"; } }
then you can put them in a simple hashtable.
Map<Arg> argList = new HashMap<Arg>();
Then you can do the logic using perhaps a counter and it contains () or indexOf (), etc.
Having an Arg class makes sorting easy. If you need a list sorted by argument position, you create a Comparator for this.
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 ; } }
Sorting by argument value is even easier since you can reuse compareTo () for strings.
import java.util.Comparator; public class ArgValComparator implements Comparator<Arg> { public int compare(Arg o1, Arg o2) { return o1.value.compareTo(o2.value); } }
Then, to sort, use Collections.sort () as follows:
import java.util.ArrayList; import java.util.Collections; import java.util.List; public class ArgList{ public static void main(String[] args) {
EDIT: added the toString () method for Arg and changed the list in the example to two βstreamsβ args.
Running with the new toString code puts the following into the console:
[[Arg num = 3, value = content], [Arg num = 4, value = depth], [Arg num = 2, value = flow], [Arg num = 5, value = flow], [Arg num = 1 , value = msg], [Arg num = 6, value = within]]
As you can see, the two arguments with the value = "stream" are now next to each other. To detect a few arguments, where value = "stream" can be done this way:
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" } } }