Sample Program provided to count number of elements from an array that are less than the specified value. Processing time taken by the program varies, using Java 8 forEach and stream takes more time for execution. Please explain if I should go with Java 8 features and if not which areas should it be avoided, additionally will parallelStream or multithreading with multi core processor help?
Code:
public static void main(String[] args) {
    int lessThan = 4;
    // Using for loop iteration
    List<Integer> integerForSort1 = Arrays.asList(4, 1, 1, 2, 3);
    long startTime1 = System.nanoTime();
    long count1 = countNumbers(integerForSort1, lessThan);
    long stopTime1 = System.nanoTime();
    System.out.println(stopTime1 - startTime1);
    System.out.println(count1);
    integerForSort1 = null;
    System.gc();
    // Using binary search
    List<Integer> integerForSort2 = Arrays.asList(4, 1, 1, 2, 3);
    long startTime2 = System.nanoTime();
    long count2 = countByBinarySearch(integerForSort2, lessThan);
    long stopTime2 = System.nanoTime();
    System.out.println(stopTime2 - startTime2);
    System.out.println(count2);
    integerForSort2 = null;
    System.gc();
    // Using Java 8
    List<Integer> integerForSort3 = Arrays.asList(4, 1, 1, 2, 3);
    long startTime3 = System.nanoTime();
    long count3 = integerForSort3.stream()
            .filter(p -> p < lessThan)
            .count();
    long stopTime3 = System.nanoTime();
    System.out.println(stopTime3 - startTime3);
    System.out.println(count3);
    integerForSort3 = null;
    System.gc();
    //Using Java 8 for each loop
    List<Integer> integerForSort4 = Arrays.asList(4, 1, 1, 2, 3);
    long startTime4 = System.nanoTime();
    long count4 = process(integerForSort4, p -> p < lessThan);
    long stopTime4 = System.nanoTime();
    System.out.println(stopTime4 - startTime4);
    System.out.println(count4);
    integerForSort4 = null; 
}
public static long countNumbers(List<Integer> integerForSort, int lessThan) {
    long count = 0;
    Collections.sort(integerForSort);
    for (Integer anIntegerForSort : integerForSort) {
        if (anIntegerForSort < lessThan)
            count++;
    }
    return count;
}
public static long countByBinarySearch(List<Integer> integerForSort, int lessThan){
    if(integerForSort==null||integerForSort.isEmpty())
        return 0;
    int low = 0, mid = 0, high = integerForSort.size();
    Collections.sort(integerForSort);
    while(low != high){
        mid = (low + high) / 2;
        if (integerForSort.get(mid) < lessThan) {
            low = mid + 1;
        }
        else {
            high = mid;
        }
    }
    return low;
}    
public static long process(List<Integer> integerForSort, Predicate<Integer> predicate) {
    final AtomicInteger i = new AtomicInteger(0);
    integerForSort.forEach((Integer p) -> {
        if (predicate.test(p)) {
            i.getAndAdd(1);
        }
    });
    return i.intValue();
}
Output:
345918
4
21509
4
29651234
4
2242999
4
Questions:
Is it possible to reduce the process time using Java 8 features?
Why does Java 8 stream takes more time?
How can I use lambda expression with binary Search, will it process faster?
Even using multithreading with concurrent.ExecutorService gave consistent results:
Result 4 : Thread 'pool-1-thread-1' ran process - Using Java 8 stream in 6 millisecond, from 11:16:05:361 to 11:16:05:367
Result 4 : Thread 'pool-1-thread-2' ran process - Using Java 8 forEach in 3 millisecond, from 11:16:05:361 to 11:16:05:364
Result 4 : Thread 'pool-1-thread-4' ran process - Using Java 7 binary Search in 0 millisecond, from 11:16:05:379 to 11:16:05:379
Result 4 : Thread 'pool-1-thread-3' ran process - Using Java 7 for loop in 1 millisecond, from 11:16:05:362 to 11:16:05:363
 
    