How to get the following items of the list tree

This question is about practice rather than retrieving items from a list.

I have an ArrayList which I have though using a simple for-loop. In case a specific keyword appears, I need to compare the following tree elements against a specific pattern.

private static boolean areVectorArgumentsValid(ArrayList<String> fileContent)
{
    for (int i=0; i<fileContent.size(); i++)
    {
        if (fileContent.get(i).equals(NORMAL) || fileContent.get(i).equals(VERTEX))
        {
            // get the next three elements of "fileContent" and see if they match a certain pattern
        }
    }
return true;
}

      

My first approach would be to use another for loop in the loop of the actual outler and then increment i by 3:

for (int j=i+1; j<=i+3; j++)
{
    if (!fileContent.get(j).matches(PATTERN))
    {
        return false;
    }
}
i+=3;

      

As you can see, it's not hard to get the method to do what I want, but ... I'm not sure if there could be a way that you would call more elegant.

+3


source to share


4 answers


This question is more about best practice than retrieving items from a list.

Before going into details, a few comments.

  • NORMAL.equals(fileContent.get(i))

    instead of fileContent.get(i).equals(NORMAL)

    avoidingNullPointerException

  • Before repeating for the next three elements, you must first check if your List

    next three has or not, to avoidArrayIndexOutOfBoundException


Now if it only checks the next three elements and only returns false if any of the three elements don't match the pattern than you have something like the following,



   if (fileContent.size() < i + 3 
    && (!fileContent.get(i+1).matches(PATTERN)
        || !fileContent.get(i+2).matches(PATTERN) 
        || !fileContent.get(i+3).matches(PATTERN))) {
        return false;
   }

      

The problem with this approach is that it doesn't check if your list has the next three items.

As for your approach, by allowing the next available items to be checked, you can simply add one condition to check if your list has the next item or not in the loop before calling the method get

on the list. Your approach to iterating over the next three elements seems fine, but further improvement is needed.

for (int j=i+1; j<=i+3; j++){
    if (fileContent.size() < j && !fileContent.get(j).matches(PATTERN)){
        return false;
    } else {
        break;
    }
}

      

+1


source


You can repeat three times and use ++i

when getting an element:

for (int j = 0; j < 3; j++) {
    if (!fileContent.get(++i).matches(PATTERN)) {
        return false;
    }
}

      

Or do something like this with a stream:



if (fileContent.stream().skip(i).limit(3).anyMatch(s -> !s.matches(PATTERN))) {
    return false;
}
i += 3;

      

But I think the best solution would be to completely change and use it Iterator

:

private static boolean areVectorArgumentsValid(ArrayList<String> fileContent) {
    for (Iterator<String> it = fileContent.iterator(); it.hasNext();) {
        String s = it.next();
        if (!s.equals(NORMAL) && !s.equals(VERTEX)) {
            continue;
        }
        for (int i = 0; i < 3; i++) {
            if (!it.hasNext() || !it.next().matches(PATTERN)) {
                return false;
            }
        }
    }
    return true;
}

      

0


source


In my opinion, you should make a method that takes an array and an index to start searching, and return a boolean if it matches three or not. This is an elegant way.

0


source


You can do this in just one loop by injecting state:

private static boolean areVectorArgumentsValid(ArrayList<String> fileContent)
{
    int state = 0;
    for (int i=0; i<fileContent.size(); i++)
    {
         switch (state) {
         case 0:
             if (fileContent.get(i).equals(NORMAL) || fileContent.get(i).equals(VERTEX))
                 state++;
             break;
         case 1:
         case 2:
         case 3:
             if (!fileContent.get(i).matches(PATTERN))
                 return false;
             state = (state + 1) % 4;
             break;
    }
    return true;
}

      

0


source







All Articles