Q:

What is the most efficient way to add and remove Slick2D sprites? 

I'm making a game in Java with Slick2D and I want to create planes which shoots:
int maxBullets = 40;
static int bullet = 0;
Missile missile[] = new Missile[maxBullets];

I want to create/move my missiles in the most efficient way, I would appreciate your advise:
public void shoot() throws SlickException{
    if(bullet<maxBullets){
        if(missile[bullet] ! = null){
            missile[bullet].resetLocation(plane.getCenterX(), plane.getCenterY(), plane.image.getRotation());
        }else{
            missile[bullet] = 
            new Missile("resources/missile.png", plane.getCenterX(), plane.getCenterY(), plane.image.getRotation());
        }
    }else{
        bullet = 0;
        missile[bullet].resetLocation(plane.getCenterX(), plane.getCenterY(), plane.image.getRotation());
    }
    bullet++;
}

I created the method resetLocation in my Missile class in order to avoid loading again the resource.  Is it correct? 
In the update method I've got this to move all the missiles:
if(bullet > 0 && bullet < maxBullets){   
    float hyp = 0.4f * delta;
    if(bullet == 1){
        missile[0].move(hyp);
    }else{
        for(int x = 0; x<bullet; x++){
            missile[x].move(hyp);
        }
    }       
}

A:

First thing would be to load all your bullets when starting your game.  This will barely slow down the start up time and avoids performance problem when loading the bullets during the game. 
Furthermore you should ensure that each bullet uses the same OpenGL texture.  So you don't load the same image 40 times into the video memory.  It might be good to only construct the first bullet and create the remaining ones using copy constructors that ensure that the same texture is used. 
For the update method... while the idea you had there is okay, the additional check won't provide much of the speedup and makes the code simply more complicated.  I guess most of the time will will have more then one bullet on the screen anyway.  If the for loop is too slow for your taste you can easily switch to a while loop looking like:
int x = -1;
while (++x < bullet) {
    missile[x].move(hyp);
}
Other than that you can turn the variables that never change final.  That does not cause the massive speedup... but it does not hurt. 
Last thing is that I think you got a but in this whole concept. 
You have one variable (bullet) that mark the current position in your array where you write new bullets too.  But what happens for example if I fire 42 bullets?  The count raises up to 40, then drops to 0 at the 41st shot and to 1 at the 42nd shot.  You update function will now only update missile[0] and the other bullets (index 1 to 39) are stuck. 
Most likely its a better approach to use two lists (ArrayLists for example).  One containing the "active" bullets, one the buffered bullets.  And as new bullets are needed you transfer them to the active bullet list and update them until they are out of the screen or hit something or ended there lifetime on any other way.  And put them back into the buffered list after to be reused. 