pbadcefp's answer is probably the easiest. Since you stated in the comments that you need it to be "dynamic", here's an alternate approach. Note that the weights basically specify how often the number appears in the array to pick from
public int weightedRandom( Random random, int max, Map<Integer, Integer> weights ) {
int totalWeight = max;
for( int weight : weights.values() ) {
totalWeight += weight - 1;
}
int choice = random.nextInt( totalWeight );
int current = 0;
for( int i = 0; i < max; i++ ) {
current += weights.containsKey( i ) ? weights.get( i ) : 1;
if( choice < current ) {
return i;
}
}
throw new IllegalStateException();
}
Example usage:
Map<Integer, Integer> weights = new HashMap<>();
weights.put( 1, 0 ); // make choosing '1' impossible
weights.put( 4, 3 ); // '4' appears 3 times rather than once
int result = weightedRandom( new Random(), 5, weights );
Basically, this is equivalent to pbadcefp's solution applied on the array { 0, 2, 3, 4, 4, 4 }
You will have to adapt this if you want to use percentages. Just calculate weights accordingly. Also, I didn't test cornercases on this, so you might want to test this a little bit more extensively.
This is by no means a complete solution, but I prefer giving something to work on over complete solutions since you should do some of the work yourself.
I'll also go on record and say that IMHO this is over-engineered; but you wanted something like this.