HackerRank Angry Professor challenge I've written an answer to HackerRank's Angry Professor problem. Please let me know if there's a quicker/better way of solving this as I think I wrote quite a bit of code for this problem (answer has to be in 1 class btw). Also, any improvements on my code in Java 8 are welcome too.

Problem statement (as written on HackerRank):


  The professor is conducting a course on Discrete Mathematics to a
  class of N students. He is angry at the lack of their discipline, and
  he decides to cancel the class if there are less than K students
  present after the class starts.
  
  Given the arrival time of each student, your task is to find out if
  the class gets cancelled or not.


Answer:

import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;

public class AngryProfessor {
    public static void main(String[] args) {
        List&lt;List&lt;List&lt;Integer&gt;&gt;&gt; testCases = readInput();

        for(List&lt;List&lt;Integer&gt;&gt; testCase : testCases){
            int numStudents = testCase.get(0).get(0);
            int minStudents = testCase.get(0).get(1);
            // Gotta STDOUT in hacker rank for it to be graded.
            System.out.println(isLectureCancelled(calcNumAttending(testCase.get(1), numStudents), minStudents));
        }
    }

    private static void addData(List&lt;Integer&gt; arrayList, String[] numbersToAdd){
        for(String num : numbersToAdd){
            arrayList.add(Integer.valueOf(num));
        }
    }

    /**
     * Calculates the number of students that make the lecture on time.
     *
     * @param studentTimes    the relative time at which the student arrives (student is on time if time is &lt;= 0)
     * @param numStudents     number of students that make the lecture on time
     * @return numStudents
     */
    private static int calcNumAttending(List&lt;Integer&gt; studentTimes, int numStudents){
        int numAttending = 0;
        for(int i = 0; i &lt; numStudents; i++){
            if(studentTimes.get(i) &lt;= 0){
                numAttending++;
            }
        }
        return numAttending;
    }

    /**
     * Determines whether the lecture is cancelled or not.
     *
     * @param numAttending    Number of students who attend the lecture
     * @param minStudents     Minimum number of students for the lecture to go ahead
     * @return whether the lecture is cancelled or not
     */
    private static String isLectureCancelled(int numAttending, int minStudents){
        return numAttending &lt; minStudents ? "YES" : "NO";
    }

    /**
     * Reads and stores all the data given. Each index is a test case. At that index is a list containing two lists. One
     * for each line of input that's read. The first list contains numStudents and minStudents, and the second list
     * contains the student times.
     *
     * @return a List containing all the data.
     */
    private static List&lt;List&lt;List&lt;Integer&gt;&gt;&gt; readInput(){
        Scanner k = new Scanner(System.in);
        int numTestCases = Integer.valueOf(k.nextLine());
        List&lt;List&lt;List&lt;Integer&gt;&gt;&gt; testCases = new ArrayList&lt;&gt;(numTestCases);

        // fills up testCases with ArrayLists before filling up with numbers
        for(int i = 0; i &lt; numTestCases; i++){
            List&lt;List&lt;Integer&gt;&gt; list = new ArrayList&lt;&gt;(2);
            for(int j = 0; j &lt; 2; j++){
                list.add(new ArrayList&lt;&gt;());
            }
            testCases.add(list);
        }

        // Inputs data into the ArrayLists
        for(int i = 0; i &lt; numTestCases; i++) {
            String line1 = k.nextLine();
            String line2 = k.nextLine();
            addData(testCases.get(i).get(0), line1.split(" "));
            addData(testCases.get(i).get(1), line2.split(" "));
        }
        k.close();
        return testCases;
    }
}
you have a nice, correct program here!
...please see what I made of it with little scope on "fewer lines" and little "performance" and of course some Java8 tweaks:

import java.util.LinkedList;//why always Array-Array?(especially for 2 - 20 entries)
import java.util.List;
import java.util.Scanner;

public class Solution {//adjusted class name for code upload

  public static void main(String[] args) {
    readInput()// don't need the variable, but same call as in original program
    .stream().forEach(//just as a showcase for streams and lambda but no real improvement
      /*TestCase*/ t -&gt; {System.out.println(t.outcome);}
    );
  }

  private static List&lt;TestCase&gt; readInput() {//no changes, except the return (list) type
    final List&lt;TestCase&gt; testCases = new LinkedList&lt;&gt;();//"final" becuase it is..., LinkedList: no(0) initial capacity
    try (Scanner k = new Scanner(System.in)) {//try with ressources {@link: https://docs.oracle.com/javase/tutorial/essential/exceptions/tryResourceClose.html}
        int numTestCases = Integer.valueOf(k.nextLine());//original code
        for (int i = 0; i &lt; numTestCases; i++) {//...
            testCases.add(//...
               new TestCase(//new "TestCase" with ...
                   k.nextLine(),//the next line &lt;- blocks
                   k.nextLine() //..and the next line &lt;-blocks
               )
            );
        }
    }
    return testCases;
  }

  private static class TestCase {//This is "nicer" to read/understand than nested lists
    //we don't really need these (they could also be local constructor variables):
    private final int students;
    private final int minAttendees;
    private final int[] arrivals;//(I) prefer arrays&gt;list, when knowing the size in advance and size &lt; 65536 (2^16)
    //we only need this:
    final String outcome;

    private TestCase(String courseData, String studsData) {
         /*This is the "power" but also "the weakness" of this approach:
         It does everything (possible) in one loop/line/routine - 
         it saves lines of code (and maybe little exec. time)!
         But it is less flexible, and for big routines
          (many students, and maybe not "keyboard scanner")
         this would definitely be a bottleneck.*/
        String[] tmp = courseData.split(" ");//according to original code, reuse of String[] variable
        students = Integer.valueOf(tmp[0]);//according to original code/input format 
        minAttendees = Integer.valueOf(tmp[1]);//...
        tmp = studsData.split(" ");//...
        arrivals = new int[students];//..initialize...
        int attendees = 0;//...
        for (int i = 0; i &lt; students; i++) {//only one loop...
            arrivals[i] = Integer.valueOf(tmp[i]);//...copying...
            if (arrivals[i] &lt;= 0) {//...evaluating...
                attendees++;
            }
        }
        outcome = attendees &lt; minAttendees ? "YES" : "NO";//..and finally aggregating
    }
  }
}