maxSpan function implementation
Your choice of data structures is unnecessarily heavy. You're interested only in the first and last index of a number, so store only those in a lightweight data structure of two integers (an array):

for (int i = 0; i &lt; nums.length; i++) {
    final int num = nums[i];
    int[] span = spans.get(num);
    if (span == null) {
        span = new int[] { i, i };
        spans.put(num, span);
    } else {
        span[1] = i;
    }
}


Java comes with built in functions for selecting larger or smaller number from two, so use them instead of if-statements or ternary operations. It makes code easier to read.

// Empty set has maxSpan = 0
int maxSpan = 0;
for (int[] span: spans.values()) {
    maxSpan = Math.max(maxSpan, span[1] - span[0] + 1);
}
return maxSpan;


Avoid end-of-line comments. They make the code messy and are a pain in the ass to maintain. Avoid unnecessary comments that describe what code does. The reader can already see that the code iterates over values. Instead document why the code does what it does.

Use variable names that describe what the variable is used for. Value does not give any new information to the reader about what it contains.

Position as a name for a list is deceptive. It's singular form suggests that it contains one value when it instead contains all positions of a certain number.

Edit: You don't actually even need to store the last occurrence of a number. Just store the first one and calculate the maxSpan as you traverse the array the first time.

int maxSpan = 0;
for (int i = 0; i &lt; nums.length; i++) {
    final int num = nums[i];
    Integer firstIndex = firstIndexes.get(num);
    if (firstIndex == null) {
        firstIndex = i;
        firstIndexes.put(num, firstIndex);
    }
    maxSpan = Math.max(maxSpan, i - firstIndex + 1);
}
return maxSpan;