Bringing the average score up to 9.5
The trick is not to loop to determine how many extra elements there is to add but to calculate them. A little mathematical consideration can show that you need to add 19 * marks.length - 2 * total elements.

So a faster solution would be:

public static int need(int[] marks) {
    int total = 0;
    for (int x : marks)
        total += x;

    return Math.max(19 * marks.length - 2 * total, 0);
}


If the number of extra steps to add with the result of that calculation is negative, it means the input array already satisfied the condition and we can return 0.



Here are the result of a small JMH benchmark comparing the code in your question and the above code. The two codes are given a random array of integers between 0 and 10, with a size going from 100,000 to 100,000,000 (Windows 10, JDK 1.8.0_66, i5 3230M @ 2.60GHz).

Benchmark             (arraySize)  Mode  Cnt     Score    Error  Units
StreamTest.testNeed        100000  avgt   30     8,208 ±  0,218  ms/op
StreamTest.testNeed       1000000  avgt   30    78,823 ±  0,834  ms/op
StreamTest.testNeed      10000000  avgt   30   798,294 ±  7,651  ms/op
StreamTest.testNeed     100000000  avgt   30  8038,244 ± 77,131  ms/op
StreamTest.testNeed2       100000  avgt   30     0,037 ±  0,004  ms/op
StreamTest.testNeed2      1000000  avgt   30     0,621 ±  0,179  ms/op
StreamTest.testNeed2     10000000  avgt   30     4,143 ±  0,090  ms/op
StreamTest.testNeed2    100000000  avgt   30    41,597 ±  1,499  ms/op


This shows a tremendous improvement! The code is at least 100x faster.

@Warmup(iterations = 10, time = 1000, timeUnit = TimeUnit.NANOSECONDS)
@Measurement(iterations = 10, time = 1000, timeUnit = TimeUnit.NANOSECONDS)
@BenchmarkMode(Mode.AverageTime)
@OutputTimeUnit(TimeUnit.MILLISECONDS)
@Fork(3)
public class StreamTest {

    private static final Random RANDOM = new Random();

    @State(Scope.Benchmark)
    public static class ArrayContainer {

        @Param({ "100000", "1000000", "10000000", "100000000"})
        private int arraySize;

        private int[] marks;

        @Setup(Level.Iteration)
        public void setUp() {
            marks = RANDOM.ints(arraySize, 0, 10).toArray();
        }

    }

    public static int need( int[] marks ){
        double average = 0, total = 0;
        int extras = 0;

        for( int x : marks )
            total += x;

        average = total / marks.length;

        if( average &gt;= 9.5 )
            return 0;

        while( average &lt; 9.5 ){
            extras++;
            total += 10;

            average = total / ( marks.length + extras );
        }

        return extras;
    }

    public static int need2(int[] marks) {
        int total = 0;
        for (int x : marks)
            total += x;

        return Math.max(19 * marks.length - 2 * total, 0);
    }


    @Benchmark
    public int testNeed(ArrayContainer c) {
        return need(c.marks);
    }

    @Benchmark
    public int testNeed2(ArrayContainer c) {
        return need2(c.marks);
    }

}