I am attempting to expand a function to find the number of integer matches through Binary Search by resetting the high variable, but it gets stuck in a loop. I am guessing a workaround would be to duplicate this function to obtain the last index to determine the number of matches, but I do not think this would be such an elegant solution.
From this:
public static Matches findMatches(int[] values, int query) {
    int firstMatchIndex = -1;
    int lastMatchIndex = -1;
    int numberOfMatches = 0;
    int low = 0;
    int mid = 0;
    int high = values[values.length - 1];
    boolean searchFirst = false;
    while (low <= high){
        mid = (low + high)/2;
        if (values[mid] == query && firstMatchIndex == -1){
            firstMatchIndex = mid;
            if (searchFirst){
                high = mid - 1;
                searchFirst = false;
            } else { 
                low = mid + 1;
            }
        } else if (query < values[mid]){
            high = mid - 1;
        } else {
            low = mid + 1;
        }           
    }
    if (firstMatchIndex != -1) { // First match index is set
        return new Matches(firstMatchIndex, numberOfMatches);
    }
    else { // First match index is not set
        return new Matches(-1, 0); 
    }
}
To something like this:
public static Matches findMatches(int[] values, int query) {
    int firstMatchIndex = -1;
    int lastMatchIndex = -1;
    int numberOfMatches = 0;
    int low = 0;
    int mid = 0;
    int high = values[values.length - 1];
    boolean searchFirst = false;
    while (low <= high){
        mid = (low + high)/2;
        if (values[mid] == query && firstMatchIndex == -1){
            firstMatchIndex = mid;
            if (searchFirst){
                high = values[values.length - 1]; // This is stuck in a loop
                searchFirst = false;
            } 
        } else if (values[mid] == query && lastMatchIndex == -1){
            lastMatchIndex = mid;
            if (!searchFirst){
                high = mid - 1;
            } else { 
                low = mid + 1;
            }
        } else if (query < values[mid]){
            high = mid - 1;
        } else {
            low = mid + 1;
        }
    }
    if (firstMatchIndex != -1) { // First match index is set
        return new Matches(firstMatchIndex, numberOfMatches);
    }
    else { // First match index is not set
        return new Matches(-1, 0); 
    }
}