Calculate next position and velocity after "bounce"
Review


You have redundant code. Store position + velocity in a variable.
Use well-known variable names when the code is of a mathematical nature. Distance x Velocity v A clamped area [a,b].
It is not clear from your description what should happen if the distance is so far away from the boundaries, that when reflecting the movement you are still out of bounds, but on the other side.
.x(max - ((position + velocity) % max)) This does not correspond to your description of 


  the next position should be equal to the amount the object would be beyond the boundary subtracted from the boundary



Proposed Solution


Use mathematical variable names.
Allow damped bouncing when the distance is too far out of bounds (Damped bouncing reflects the value x, alternating around the boundaries until it is clamped with the area [a,b]).
Make both 0 and max a variable, respectively a and b.




public TwoVector&lt;Double&gt; getNextPositionAndVelocity(double x, double v, double a, double b)
{
    assert a &lt; b;
    double xn = x + v;

    // the loop allows for damped bouncing
    while (true) {
        if (xn &lt; a) {
            xn = a - xn;
            v = Math.abs(v);
        }
        else if (xn &gt; b) {
            xn = b - (xn - b);
            v = -Math.abs(v);
        }
        else {
            break;
        }
    }

    return TwoVector.&lt;Double&gt;builder().x(xn).y(v).build();
}