Iterating over an Array and an Iterable (List) I have a byte array and a List of a custom object ByteRule and I'm needing to loop around and perform an operation on both but only as long as one of both is available, the original method is as follows:

private final List&lt;ByteRule&gt; rules;

@Override
public boolean match(final InetAddress addr)
{
    final byte[] bytes = addr.getAddress();
    for(int i = 0; i &lt; this.rules.size() &amp;&amp; i &lt; bytes.length; i++)
    {
        final int value = bytes[i] &lt; 0 ? (int) bytes[i] + 256 : bytes[i];
        if(!this.rules.get(i).match(value))
        {
            return false;
        }
    }
    return true;
}


Obviously the this.rules.get(i) on every iteration is inefficient, however as I need to maintain a counter, an enhanced for loop means keeping a separate counter and performing a check on it every time like so (list declaration skipped for space):

@Override
public boolean match(final InetAddress addr)
{
    final byte[] bytes = addr.getAddress();
    int counter = 0;
    for(final ByteRule rule : this.rules)
    {
        if(counter + 1 == bytes.length) break; //In case there aren't enough bytes
        final int value = bytes[counter] &lt; 0 ? (int) bytes[counter] + 256 : bytes[counter];
        if(!rule.match(value))
        {
            return false;
        }
        counter++;
    }
    return true;
}


Is there a cleaner/more efficient solution to this problem that I'm missing?
I would be happy with:

@Override
public boolean match(final InetAddress inetAddress)
{
    final byte[] bytes = inetAddress.getAddress();
    int end = Math.min(this.rules.size(), bytes.length);
    for(int i = 0; i &lt; end; i++)
    {
        final int adressPart = bytes[i] &amp; 0xFF; //byte range from -128 to 127, &amp;0xFF makes it unsigned, therefore positive
        if(!this.rules.get(i).match(adressPart))
            return false;
    }
    return true;
}


If you think, the this.rules.get(i), then test it with a profiler. I would be surprised if this line is the reason for any slowdown, because the length of a InetAddress is probably quite limited and most likely implemented as an ArrayList annyway. If it really matters, you can change it to:

@Override
public boolean match(final InetAddress inetAddress)
{
    final byte[] bytes = inetAddress.getAddress();
    ByteRule[] byteRulesArray = rules.toArray(new String[rules.size()]);
    int end = Math.min(this.rules.size(), bytes.length);
    for(int i = 0; i &lt; end; i++)
    {
        final int adressPart = bytes[i] &amp; 0xFF; //byte range from -128 to 127, &amp;0xFF makes it unsigned, therefore positive
        if(!byteRulesArray[i].match(adressPart))
            return false;
    }
    return true;
}


or if you even fear the array creation, you can use an iterator:

@Override
public boolean match(final InetAddress inetAddress)
{
    final byte[] bytes = inetAddress.getAddress();
    Iterator&lt;ByteRule&gt; rulesIterator = rules.iterator();
    int end = Math.min(this.rules.size(), bytes.length);
    for(int i = 0; i &lt; end; i++)
    {
        final int adressPart = bytes[i] &amp; 0xFF; //byte range from -128 to 127, &amp;0xFF makes it unsigned, therefore positive
        if(!rulesIterator.next.match(adressPart))
            return false;
    }
    return true;
}


Hint: In theory, the iterator solution would be faster than the array creation. However in the real world, because of hardware reasons, the array creation will, most likely, be faster.