code: public void merge(OrderedIntDoubleMapping updates, DoubleDoubleFunction func) {
      int[] updateIndices = updates.getIndices();
      double[] updateValues = updates.getValues();
  
      int newNumMappings = numMappings + updates.getNumMappings();
      int newCapacity = Math
          .max((int) (1.2 * newNumMappings), newNumMappings + 1);
      int[] newIndices = new int[newCapacity];
      double[] newValues = new double[newCapacity];
  
      int k = 0;
      int i = 0, j = 0;
      for (; i < numMappings && j < updates.getNumMappings(); ++k) {
        if (indices[i] < updateIndices[j]) {
          newIndices[k] = indices[i];
          newValues[k] = func.apply(values[i], 0);
          ++i;
        } else if (indices[i] > updateIndices[j]) {
          newIndices[k] = updateIndices[j];
          newValues[k] = func.apply(0, updateValues[j]);
          ++j;
        } else {
          newIndices[k] = updateIndices[j];
          newValues[k] = func.apply(values[i], updateValues[j]);
          ++i;
          ++j;
        }
      }
  
      if (i < numMappings) {
        int delta = numMappings - i;
        System.arraycopy(indices, i, newIndices, k, delta);
        System.arraycopy(values, i, newValues, k, delta);
        k += delta;
      }
  
      if (j < updates.getNumMappings()) {
        int delta = updates.getNumMappings() - j;
        System.arraycopy(updateIndices, j, newIndices, k, delta);
        System.arraycopy(updateValues, j, newValues, k, delta);
        k += delta;
      }
  
      indices = newIndices;
      values = newValues;
      numMappings = k;
    }
docs: Merges the updates in linear time by allocating new arrays and iterating
  through the existing indices and values and the updates' indices and values
  at the same time while selecting the minimum index to set at each step.
  
  @param updates another list of mappings to be merged in.