public class Main {
    ArrayList<String> parentheses = new ArrayList<String>();
    public Main() {
        parentheses.add("(");
        parentheses.add("(");
        parentheses.add(")");
        parentheses.add(")");
    }

    public boolean isParenthesesValid() {
        System.out.println(parentheses.toString());
        // If there is an odd number of parentheses, the expression is not valid
        if (parentheses.size() % 2 != 0) {
            return false;
        }

        // Create stack to store open parentheses and remove when needed
        Stack<String> openParStack = new Stack<String>();

        // Iterate through parenthesis in the parentheses ArrayList
        for (int i = 0; i < parentheses.size(); i++) {
            if (parentheses.get(i).equals("(")) {
                // If open parenthesis appears, push it to the stack
                openParStack.push(parentheses.get(i));
            } else if (openParStack.size() == 0) {
                // If close parenthesis appears instead, but no open parentheses are in the stack, return false
                // Basically, return false if there are more close parentheses than open parentheses, or if a close parenthesis appears before its open parenthesis counterpart
                return false;
            } else if (parentheses.get(i).equals(")")) {
                // If close parenthesis appears and open parentheses are in the stack, pop an open parenthesis out of the stack
                openParStack.pop();
            }
        }

        // Return false if there are more open parentheses than close parentheses
        if (openParStack.size() > 0) {
            return false;
        }

        // By default, return true
        return true;
    }

    public static void main(String[] args) {
        Main tester = new Main();
        System.out.println(tester.isParenthesesValid());
    }
}

Main.main(null);
[(, (, ), )]
true